Example #1
0
        /// <summary>
        /// Temporarily clears all items in a list
        /// Next time list contents will be refereshed online
        /// </summary>
        public static void ClearItemsInList(string username, string slug)
        {
            // if we are adding to the current active list, then this is invalid and we dont care
            // if we are removing from the current list, we already take care of this ourselves
            // in all other cases we should clear
            if (GUIListItems.CurrentList != null && GUIListItems.CurrentList.Slug == slug && GUIListItems.CurrentUser == username)
            {
                return;
            }

            IEnumerable <TraktUserList> lists = GetListsForUser(username);
            TraktUserList list = lists.FirstOrDefault(l => l.Slug == slug);

            // nothing to do
            if (list.Items == null)
            {
                return;
            }

            // remove old list from cache
            lists = lists.Where(l => l.Slug != slug);

            // remove items from current list
            list.Items = null;

            // update cached result
            lists = lists.Concat(new[] { list });
            usersLists[username] = lists;
        }
        private void DeleteList(TraktUserList list)
        {
            if (!GUIUtils.ShowYesNoDialog(Translation.Lists, Translation.ConfirmDeleteList, false))
            {
                return;
            }

            GUIBackgroundTask.Instance.ExecuteInBackgroundAndCallback(() =>
            {
                TraktLogger.Info("Deleting list '{0}'", list.Name);
                TraktList deleteList = new TraktList {
                    UserName = TraktSettings.Username, Password = TraktSettings.Password, Slug = list.Slug
                };
                return(TraktAPI.TraktAPI.ListDelete(deleteList));
            },
                                                                      delegate(bool success, object result)
            {
                if (success)
                {
                    TraktResponse response = result as TraktResponse;
                    TraktLogger.LogTraktResponse <TraktResponse>(response);
                    if (response.Status == "success")
                    {
                        // reload with new list
                        TraktLists.ClearCache(TraktSettings.Username);
                        LoadLists();
                    }
                    else
                    {
                        GUIUtils.ShowNotifyDialog(Translation.Lists, response.Error);
                    }
                }
            }, Translation.DeletingList, true);
        }
Example #3
0
        /// <summary>
        /// Get list for user
        /// </summary>
        public static TraktUserList GetListForUser(string username, string slug)
        {
            bool getUpdates = LastRequest < DateTime.UtcNow.Subtract(new TimeSpan(0, TraktSettings.WebRequestCacheMinutes, 0));

            IEnumerable <TraktUserList> lists = GetListsForUser(username);
            TraktUserList list = lists.FirstOrDefault(l => l.Slug == slug);

            // lists api doesn't return items so check if have them yet
            if (list.Items == null || getUpdates)
            {
                // remove old list from cache
                lists = lists.Where(l => l.Slug != slug);

                // remember sort order
                int sortOrder = list.SortOrder;

                // get list with list items
                list           = TraktAPI.TraktAPI.GetUserList(username, slug);
                list.SortOrder = sortOrder;

                // update cached result
                lists = lists.Concat(new[] { list });
                usersLists[username] = lists;
                LastRequest          = DateTime.UtcNow;
            }

            return(list);
        }
Example #4
0
 private void PublishListSkinProperties(TraktUserList list)
 {
     SetProperty("#Trakt.List.Name", list.Name);
     SetProperty("#Trakt.List.Description", list.Description);
     SetProperty("#Trakt.List.Privacy", list.Privacy);
     SetProperty("#Trakt.List.Slug", list.Slug);
     SetProperty("#Trakt.List.Url", list.Url);
 }
 private void PublishListSkinProperties(TraktUserList list)
 {
     SetProperty("#Trakt.List.Name", list.Name);
     SetProperty("#Trakt.List.Description", list.Description);
     SetProperty("#Trakt.List.Privacy", list.Privacy);
     SetProperty("#Trakt.List.Slug", list.Slug);
     SetProperty("#Trakt.List.Url", list.Url);
     SetProperty("#Trakt.List.AllowShouts", list.AllowShouts.ToString());
     SetProperty("#Trakt.List.ShowNumbers", list.ShowNumbers.ToString());
 }
        private void SendListItemsToFacade(TraktUserList list)
        {
            // clear facade
            GUIControl.ClearControl(GetID, Facade.GetID);

            if (list.Items == null || list.Items.Count() == 0)
            {
                GUIUtils.ShowNotifyDialog(GUIUtils.PluginName(), Translation.NoListItemsFound);
                GUIWindowManager.ShowPreviousWindow();
                return;
            }

            int itemId     = 1;
            var listImages = new List <TraktImage>();

            // Add each list item
            foreach (var listItem in list.Items.Where(l => !string.IsNullOrEmpty(l.Title)))
            {
                // add image for download
                var images = GetTraktImage(listItem);
                listImages.Add(images);

                string itemName = list.ShowNumbers ? string.Format("{0}. {1}", itemId, GetListItemName(listItem)) : GetListItemName(listItem);

                var item = new GUICustomListItem(itemName, (int)TraktGUIWindows.ListItems);

                item.Label2          = listItem.Year;
                item.TVTag           = listItem;
                item.Images          = images;
                item.IsPlayed        = listItem.Watched;
                item.ItemId          = Int32.MaxValue - itemId;
                item.IconImage       = GUIImageHandler.GetDefaultPoster(false);
                item.IconImageBig    = GUIImageHandler.GetDefaultPoster();
                item.ThumbnailImage  = GUIImageHandler.GetDefaultPoster();
                item.OnItemSelected += OnItemSelected;
                Utils.SetDefaultIcons(item);
                Facade.Add(item);
                itemId++;
            }

            // Set Facade Layout
            Facade.SetCurrentLayout(Enum.GetName(typeof(Layout), CurrentLayout));
            GUIControl.FocusControl(GetID, Facade.GetID);

            Facade.SelectIndex(PreviousSelectedIndex);

            // set facade properties
            GUIUtils.SetProperty("#itemcount", list.Items.Count().ToString());
            GUIUtils.SetProperty("#Trakt.Items", string.Format("{0} {1}", list.Items.Count().ToString(), list.Items.Count() > 1 ? Translation.Items : Translation.Item));

            // Download images Async and set to facade
            GUICustomListItem.GetImages(listImages);
        }
        private void SendListItemsToFacade(TraktUserList list)
        {
            // clear facade
            GUIControl.ClearControl(GetID, Facade.GetID);

            if (list.Items == null || list.Items.Count() == 0)
            {
                GUIUtils.ShowNotifyDialog(GUIUtils.PluginName(), Translation.NoListItemsFound);
                GUIWindowManager.ShowPreviousWindow();
                return;
            }

            int           itemId = 0;
            List <object> images = new List <object>();

            // Add each list item
            foreach (var listItem in list.Items)
            {
                GUITraktCustomListItem item = new GUITraktCustomListItem(listItem.ToString());

                item.Label2          = listItem.Year;
                item.TVTag           = listItem;
                item.Item            = listItem.Images;
                item.IsPlayed        = listItem.Watched;
                item.ItemId          = Int32.MaxValue - itemId;
                item.IconImage       = "defaultVideo.png";
                item.IconImageBig    = "defaultVideoBig.png";
                item.ThumbnailImage  = "defaultVideoBig.png";
                item.OnItemSelected += OnItemSelected;
                Utils.SetDefaultIcons(item);
                Facade.Add(item);
                itemId++;

                // add image for download
                images.Add(listItem.Images);
            }

            // Set Facade Layout
            Facade.SetCurrentLayout(Enum.GetName(typeof(Layout), CurrentLayout));
            GUIControl.FocusControl(GetID, Facade.GetID);

            Facade.SelectIndex(PreviousSelectedIndex);

            // set facade properties
            GUIUtils.SetProperty("#itemcount", list.Items.Count().ToString());
            GUIUtils.SetProperty("#Trakt.Items", string.Format("{0} {1}", list.Items.Count().ToString(), list.Items.Count() > 1 ? Translation.Items : Translation.Item));

            // Download images Async and set to facade
            GetImages(images);
        }
        private void OnItemSelected(GUIListItem item, GUIControl parent)
        {
            TraktUserList list = item.TVTag as TraktUserList;

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

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

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

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

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

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

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

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

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

            copyThread.Start(copyList);
        }
Example #10
0
        protected override void OnShowContextMenu()
        {
            if (GUIBackgroundTask.Instance.IsBusy)
            {
                return;
            }

            GUIListItem selectedItem = this.Facade.SelectedListItem;

            if (selectedItem == null)
            {
                return;
            }

            TraktUserList selectedList = (TraktUserList)selectedItem.TVTag;

            IDialogbox dlg = (IDialogbox)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);

            if (dlg == null)
            {
                return;
            }

            dlg.Reset();
            dlg.SetHeading(GUIUtils.PluginName());

            GUIListItem listItem = null;

            // only allow add/delete/update if viewing your own lists
            if (CurrentUser == TraktSettings.Username)
            {
                listItem = new GUIListItem(Translation.CreateList);
                dlg.Add(listItem);
                listItem.ItemId = (int)ContextMenuItem.Create;

                listItem = new GUIListItem(Translation.EditList);
                dlg.Add(listItem);
                listItem.ItemId = (int)ContextMenuItem.Edit;

                listItem = new GUIListItem(Translation.DeleteList);
                dlg.Add(listItem);
                listItem.ItemId = (int)ContextMenuItem.Delete;
            }
            else
            {
                // copy a friends list
                listItem = new GUIListItem(Translation.CopyList);
                dlg.Add(listItem);
                listItem.ItemId = (int)ContextMenuItem.Copy;
            }

            // Show Context Menu
            dlg.DoModal(GUIWindowManager.ActiveWindow);
            if (dlg.SelectedId < 0)
            {
                return;
            }

            TraktList currentList = new TraktList
            {
                Name        = selectedList.Name,
                Description = selectedList.Description,
                Privacy     = selectedList.Privacy,
                Slug        = selectedList.Slug,
                ShowNumbers = selectedList.ShowNumbers,
                AllowShouts = selectedList.AllowShouts
            };

            switch (dlg.SelectedId)
            {
            case ((int)ContextMenuItem.Create):
                TraktList list = new TraktList();
                if (TraktLists.GetListDetailsFromUser(ref list))
                {
                    if (Lists.ToList().Exists(l => l.Name == list.Name))
                    {
                        // list with that name already exists
                        GUIUtils.ShowNotifyDialog(Translation.Lists, Translation.ListNameAlreadyExists);
                        return;
                    }
                    TraktLogger.Info("Creating new '{0}' list '{1}'", list.Privacy, list.Name);
                    CreateList(list);
                }
                break;

            case ((int)ContextMenuItem.Delete):
                DeleteList(selectedList);
                break;

            case ((int)ContextMenuItem.Edit):
                if (TraktLists.GetListDetailsFromUser(ref currentList))
                {
                    TraktLogger.Info("Editing list '{0}'", currentList.Slug);
                    EditList(currentList);
                }
                break;

            case ((int)ContextMenuItem.Copy):
                if (TraktLists.GetListDetailsFromUser(ref currentList))
                {
                    CopyList(selectedList, currentList);
                }
                break;

            default:
                break;
            }

            base.OnShowContextMenu();
        }
Example #11
0
        public void SyncLibrary()
        {
            TraktLogger.Info("My Films Starting Sync");
            SyncInProgress = true;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    notInLocalCollection = false;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                #region update trending tags

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

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

            myvideos.Clear();

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