Наследование: Cornerstone.Database.Tables.DatabaseTable
        public static void CreateMovingPictureCategories()
        {
            if (!TraktSettings.MovingPicturesCategories)
                return;

            TraktLogger.Debug("Checking if Category has already been created");
            if (TraktSettings.MovingPicturesCategoryId == -1)
            {
                TraktLogger.Debug("Category not created so let's create it");
                DBNode<DBMovieInfo> traktNode = new DBNode<DBMovieInfo>();
                traktNode.Name = "${Trakt}";

                DBMovieNodeSettings nodeSettings = new DBMovieNodeSettings();
                traktNode.AdditionalSettings = nodeSettings;

                TraktLogger.Debug("Setting the sort position to {0}", (MovingPicturesCore.Settings.CategoriesMenu.RootNodes.Count + 1).ToString());
                //Add it at the end
                traktNode.SortPosition = MovingPicturesCore.Settings.CategoriesMenu.RootNodes.Count + 1;

                TraktLogger.Debug("Adding to Root Node");
                MovingPicturesCore.Settings.CategoriesMenu.RootNodes.Add(traktNode);

                TraktLogger.Debug("Committing");
                MovingPicturesCore.Settings.CategoriesMenu.Commit();

                TraktLogger.Debug("Saving the ID {0}", traktNode.ID.ToString());
                TraktSettings.MovingPicturesCategoryId = (int)traktNode.ID;
                TraktSettings.saveSettings();

            }
            else
            {
                TraktLogger.Debug("Category has already been created");
            }
        }
Пример #2
0
        private void UpdateYear(DBNode <DBMovieInfo> node)
        {
            // grab list of possible years
            HashSet <string> allYears = node.DBManager.GetAllValues(node.BasicFilteringField,
                                                                    node.BasicFilteringRelation,
                                                                    node.GetFilteredItems());

            // build list of decades, each will correspond to one subnode
            HashSet <int> decades = new HashSet <int>();

            foreach (string year in allYears)
            {
                int iYear;
                if (int.TryParse(year, out iYear))
                {
                    decades.Add(iYear / 10);
                }
            }

            // build lookup for subnodes and build list of nodes to remove
            List <DBNode <DBMovieInfo> >            toRemove   = new List <DBNode <DBMovieInfo> >();
            Dictionary <int, DBNode <DBMovieInfo> > nodeLookup = new Dictionary <int, DBNode <DBMovieInfo> >();

            foreach (DBNode <DBMovieInfo> currSubNode in node.Children)
            {
                if (!currSubNode.AutoGenerated)
                {
                    continue;
                }

                int decade = 0;
                if (int.TryParse(currSubNode.Filter.Criteria[0].Value.ToString(), out decade))
                {
                    decade = (decade + 1) / 10;
                    if (decades.Contains(decade))
                    {
                        nodeLookup[decade] = currSubNode;
                    }
                }
                else
                {
                    toRemove.Add(currSubNode);
                }
            }

            // remove subnodes that are no longer valid
            foreach (DBNode <DBMovieInfo> currSubNode in toRemove)
            {
                node.Children.Remove(currSubNode);
                currSubNode.Delete();
            }

            // add subnodes that are missing
            foreach (int currDecade in decades)
            {
                if (nodeLookup.ContainsKey(currDecade))
                {
                    continue;
                }

                DBNode <DBMovieInfo> newSubNode = new DBNode <DBMovieInfo>();
                newSubNode.Name          = (currDecade == 0) ? Translation.Unknown : Translation.GetByName("DecadeShort", currDecade);
                newSubNode.AutoGenerated = true;
                newSubNode.SortPosition  = currDecade;

                DBFilter <DBMovieInfo> newFilter = new DBFilter <DBMovieInfo>();
                newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ALL;
                newFilter.Name             = currDecade.ToString();

                newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.GREATER_THAN, ((currDecade * 10) - 1)));
                newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.LESS_THAN, ((currDecade * 10) + 10)));

                newSubNode.Filter = newFilter;

                // set the default sortorder for the gui
                DBMovieNodeSettings settings = new DBMovieNodeSettings();
                settings.UseDefaultSorting = false;
                settings.SortField         = SortingFields.Year;

                newSubNode.AdditionalSettings = settings;


                node.Children.Add(newSubNode);
                newSubNode.Parent = node;
            }

            node.Children.Sort();
        }
Пример #3
0
        private void UpdateDateAdded(DBNode <DBMovieInfo> node)
        {
            // get all items that these nodes will apply to
            HashSet <DBMovieInfo> items = node.GetFilteredItems();

            // get all available periods
            string[] periods = new string[] {
                "WithinLastSevenDays",
                "WithinLastTwoWeeks",
                "WithinLastThirtyDays",
                "LastMonth",
                "TwoMonthsAgo",
                "ThreeMonthsAgo",
                "ThisYear",
                "LastYear",
                "Older"
            };

            // build lookup for subnodes and build list of nodes to remove
            List <DBNode <DBMovieInfo> > toRemove = new List <DBNode <DBMovieInfo> >();
            Dictionary <string, DBNode <DBMovieInfo> > nodeLookup = new Dictionary <string, DBNode <DBMovieInfo> >();

            foreach (DBNode <DBMovieInfo> currSubNode in node.Children)
            {
                if (!currSubNode.AutoGenerated)
                {
                    continue;
                }

                string period = currSubNode.Filter.Name;
                if (!periods.Contains(period))
                {
                    toRemove.Add(currSubNode);
                }
                else
                {
                    nodeLookup[period] = currSubNode;
                }
            }

            // remove subnodes that are no longer valid
            foreach (DBNode <DBMovieInfo> currSubNode in toRemove)
            {
                node.Children.Remove(currSubNode);
                currSubNode.Delete();
            }

            // add subnodes that are missing
            int index = 0;

            foreach (string period in periods)
            {
                index++;

                if (nodeLookup.ContainsKey(period))
                {
                    continue;
                }

                DBFilter <DBMovieInfo> newFilter = new DBFilter <DBMovieInfo>();
                newFilter.Name = period;

                DBNode <DBMovieInfo> newSubNode = new DBNode <DBMovieInfo>();
                newSubNode.AutoGenerated = true;
                newSubNode.SortPosition  = index;

                switch (period)
                {
                case "WithinLastSevenDays":
                    newSubNode.Name            = Translation.GetByName("DatePartWithinDays", "7");
                    newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ONE;
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.EQUAL, "-7d"));
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.GREATER_THAN, "-7d"));
                    break;

                case "WithinLastTwoWeeks":
                    newSubNode.Name            = Translation.GetByName("DatePartWithinDays", "14");
                    newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ONE;
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.EQUAL, "-14d"));
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.GREATER_THAN, "-14d"));
                    break;

                case "WithinLastThirtyDays":
                    newSubNode.Name            = Translation.GetByName("DatePartWithinDays", "30");
                    newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ONE;
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.EQUAL, "-30d"));
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.GREATER_THAN, "-30d"));
                    break;

                case "LastMonth":
                    newSubNode.Name            = Translation.LastMonth;
                    newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ALL;
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.LESS_THAN, "M"));
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.GREATER_THAN, "-1M"));
                    break;

                case "TwoMonthsAgo":
                    newSubNode.Name            = Translation.GetByName("DatePartAgo", 2, Translation.DateMonths);
                    newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ALL;
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.LESS_THAN, "-1M"));
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.GREATER_THAN, "-2M"));
                    break;

                case "ThreeMonthsAgo":
                    newSubNode.Name            = Translation.GetByName("DatePartAgo", 3, Translation.DateMonths);
                    newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ALL;
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.LESS_THAN, "-2M"));
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.GREATER_THAN, "-3M"));
                    break;

                case "ThisYear":
                    newSubNode.Name            = Translation.ThisYear;
                    newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ONE;
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.EQUAL, "Y"));
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.GREATER_THAN, "Y"));
                    break;

                case "LastYear":
                    newSubNode.Name            = Translation.LastYear;
                    newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ALL;
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.LESS_THAN, "Y"));
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.GREATER_THAN, "-1Y"));
                    break;

                case "Older":
                    newSubNode.Name            = Translation.Older;
                    newFilter.CriteriaGrouping = DBFilter <DBMovieInfo> .CriteriaGroupingEnum.ALL;
                    newFilter.Criteria.Add(createCriteria(node, DBCriteria <DBMovieInfo> .OperatorEnum.LESS_THAN, "-1Y"));
                    break;
                }


                newSubNode.Filter = newFilter;

                // set the default sortorder for the gui
                DBMovieNodeSettings settings = new DBMovieNodeSettings();
                settings.UseDefaultSorting = false;
                settings.SortField         = SortingFields.DateAdded;
                settings.SortDirection     = SortingDirections.Descending;

                newSubNode.AdditionalSettings = settings;

                node.Children.Add(newSubNode);
                newSubNode.Parent = node;
            }

            node.Children.Sort();
        }
        private static IEnumerable<DBNode<DBMovieInfo>> CreateNodes(bool watchlist, bool recommendations)
        {
            List<DBNode<DBMovieInfo>> nodesAdded = new List<DBNode<DBMovieInfo>>();

            if (watchlist)
            {
                var watchlistNode = new DBNode<DBMovieInfo> { Name = "${" + GUI.Translation.WatchList + "}" };

                var watchlistSettings = new DBMovieNodeSettings();
                watchlistNode.AdditionalSettings = watchlistSettings;

                nodesAdded.Add(watchlistNode);
            }

            if (recommendations)
            {
                var recommendationsNode = new DBNode<DBMovieInfo> { Name = "${" + GUI.Translation.Recommendations + "}" };

                var recommendationsSettings = new DBMovieNodeSettings();
                recommendationsNode.AdditionalSettings = recommendationsSettings;

                nodesAdded.Add(recommendationsNode);
            }

            return nodesAdded;
        }
Пример #5
0
        /// <summary>
        /// Creates a node in a menu
        /// </summary>
        /// <param name="menu">Categories or Filters menu</param>
        /// <param name="name">Name of node to create</param>
        static void CreateNodeInMenu(DBMenu<DBMovieInfo> menu, string name)
        {
            var node = new DBNode<DBMovieInfo>();
            node.Name = name;

            var nodeSettings = new DBMovieNodeSettings();
            node.AdditionalSettings = nodeSettings;

            // Add node to the end
            node.SortPosition = menu.RootNodes.Count + 1;

            // Add to root node
            menu.RootNodes.Add(node);

            // Committing node to menu
            menu.Commit();
        }
Пример #6
0
        /// <summary>
        /// Created a child node
        /// </summary>
        /// <param name="rootNode">The parent node to create a node under</param>
        /// <param name="name">Name of new child node</param>
        /// <returns>Returns the existing child node if it exists otherwise creates a new one</returns>
        static DBNode<DBMovieInfo> CreateNode(DBNode<DBMovieInfo> rootNode, string name, bool createBlacklist = false)
        {
            if (rootNode == null) return null;

            string nodeName = name;
            if (!nodeName.StartsWith("$"))
                nodeName = string.Format("${{{0}}}", name);

            // check if the node exists, if not create it
            var node = rootNode.Children.FirstOrDefault(n => n.Name == nodeName);

            // we have it, nothing else to do
            if (node != null)
                return node;

            TraktLogger.Info("Creating child node '{0}' under Trakt", name);

            // create the node with default settings
            node = new DBNode<DBMovieInfo> { Name = nodeName };

            var nodeSettings = new DBMovieNodeSettings();
            node.AdditionalSettings = nodeSettings;

            if (createBlacklist)
            {
                TraktLogger.Info("Adding dummy blacklist criteria to the '{0}' node filter", name);
                node.Filter = new DBFilter<DBMovieInfo>();
                node.Filter.CriteriaGrouping = DBFilter<DBMovieInfo>.CriteriaGroupingEnum.ONE;
                node.Filter.Name = string.Format("{0} Filter", nodeName);
                AddDummyBlacklistToFilter(node.Filter);
            }

            // add as a child to the root node
            node.Parent = rootNode;
            rootNode.Children.Add(node);
            rootNode.Commit();

            return node;
        }
        /// <summary>
        /// Publishes category (node) related artwork to the skin
        /// </summary>
        /// <param name="node"></param>
        private void PublishArtwork(DBNode<DBMovieInfo> node)
        {
            if (node == null) {
                logger.Debug("Clearing Category Artwork");
                cover.Filename = string.Empty;
                backdrop.Filename = string.Empty;
                return;
            }

            logger.Debug("Publishing Category Artwork");

            cover.Filename = string.Empty;

            // grab the node settings
            DBMovieNodeSettings settings = node.AdditionalSettings as DBMovieNodeSettings;
            if (settings == null) {
                settings = new DBMovieNodeSettings();
                node.AdditionalSettings = settings;
            }

            // grab the backdrop
            switch (settings.BackdropType) {
                case MenuBackdropType.FILE:
                    backdrop.Filename = settings.BackdropFilePath;
                    SetProperty("#MovingPictures.Settings.BackdropMovieTitle", "");
                    break;
                case MenuBackdropType.MOVIE:
                    backdrop.Filename = settings.BackdropMovie.BackdropFullPath;
                    SetProperty("#MovingPictures.Settings.BackdropMovieTitle", settings.BackdropMovie.Title);
                    break;
                case MenuBackdropType.RANDOM:
                    DBMovieInfo movie = null;
                    HashSet<DBMovieInfo> movies = browser.GetAvailableMovies(node);
                    lock (backdropSync) {
                        // Check if this node has an active movie cached and if it's still active.
                        if (activeMovieLookup.ContainsKey(node) && movies.Contains(activeMovieLookup[node])) {
                            movie = activeMovieLookup[node];
                        } else {
                            // grab a new random movie from the visible movies that has a backdrop
                            movie = movies.Where(m => m.BackdropFullPath != null && m.BackdropFullPath.Trim().Length > 0).ToList().Random();
                            // if we found one add it to our lookup list to speed up future requests
                            if (movie != null) activeMovieLookup[node] = movie;
                        }
                    }
                    // change the backdrop or set to null
                    backdrop.Filename = (movie != null) ? movie.BackdropFullPath : null;
                    SetProperty("#MovingPictures.Settings.BackdropMovieTitle"
                        , (movie != null) ? movie.Title : null);
                    break;
            }
        }
        private static IEnumerable<DBNode<DBMovieInfo>> CreateNodes(IEnumerable<TraktMovie> traktRecommendationMovies, IEnumerable<TraktWatchListMovie> traktWatchListMovies)
        {
            #region WatchList
            TraktLogger.Debug("Creating the watchlist node");
            var watchlistNode = new DBNode<DBMovieInfo> {Name = "${" + GUI.Translation.WatchList + "}"};

            var watchlistSettings = new DBMovieNodeSettings();
            watchlistNode.AdditionalSettings = watchlistSettings;

            TraktLogger.Debug("Getting the Movie's from Moving Pictures");
            var movieList = DBMovieInfo.GetAll();

            TraktLogger.Debug("Creating the watchlist filter");
            var watchlistFilter = new DBFilter<DBMovieInfo>();
            foreach (var movie in traktWatchListMovies.Select(traktmovie => movieList.Find(m => m.ImdbID.CompareTo(traktmovie.Imdb) == 0)).Where(movie => movie != null))
            {
                TraktLogger.Debug("Adding {0} to watchlist", movie.Title);
                watchlistFilter.WhiteList.Add(movie);
            }

            if (watchlistFilter.WhiteList.Count == 0)
            {
                TraktLogger.Debug("Nothing in watchlist, Blacklisting everything");
                watchlistFilter.BlackList.AddRange(movieList);
            }

            watchlistNode.Filter = watchlistFilter;

            #endregion

            #region Recommendations
            TraktLogger.Debug("Creating the recommendations node");
            var recommendationsNode = new DBNode<DBMovieInfo> {Name = "${" + GUI.Translation.Recommendations + "}"};

            var recommendationsSettings = new DBMovieNodeSettings();
            recommendationsNode.AdditionalSettings = recommendationsSettings;

            TraktLogger.Debug("Creating the recommendations filter");
            var recommendationsFilter = new DBFilter<DBMovieInfo>();
            foreach (var movie in traktRecommendationMovies.Select(traktMovie => movieList.Find(m => m.ImdbID.CompareTo(traktMovie.Imdb) == 0)).Where(movie => movie != null))
            {
                TraktLogger.Debug("Adding {0} to recommendations", movie.Title);
                recommendationsFilter.WhiteList.Add(movie);
            }

            if (recommendationsFilter.WhiteList.Count == 0)
            {
                TraktLogger.Debug("Nothing in recommendation list, Blacklisting everything");
                recommendationsFilter.BlackList.AddRange(movieList);
            }

            recommendationsNode.Filter = recommendationsFilter;

            #endregion

            return new DBNode<DBMovieInfo>[] { watchlistNode, recommendationsNode };
        }
        public static void VerifyCategoryMenu()
        {
            DBMenu<DBMovieInfo> menu = MovingPicturesCore.Settings.CategoriesMenu;

            if (menu.RootNodes.Count == 0) {
                int position = 1;

                DBNode<DBMovieInfo> allNode = new DBNode<DBMovieInfo>();
                allNode.Name = "${AllMovies}";
                allNode.DynamicNode = false;
                allNode.Filter = new DBFilter<DBMovieInfo>();
                allNode.SortPosition = position++;
                allNode.DBManager = MovingPicturesCore.DatabaseManager;
                menu.RootNodes.Add(allNode);

                DBNode<DBMovieInfo> unwatchedNode = new DBNode<DBMovieInfo>();
                unwatchedNode.Name = "${UnwatchedMovies}";
                unwatchedNode.DynamicNode = false;
                unwatchedNode.Filter = new DBFilter<DBMovieInfo>();
                DBCriteria<DBMovieInfo> criteria = new DBCriteria<DBMovieInfo>();
                criteria.Field = DBField.GetFieldByDBName(typeof(DBUserMovieSettings), "watched");
                criteria.Relation = DBRelation.GetRelation(typeof(DBMovieInfo), typeof(DBUserMovieSettings), "");
                criteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.EQUAL;
                criteria.Value = "0";
                unwatchedNode.Filter.Criteria.Add(criteria);
                unwatchedNode.SortPosition = position++;
                unwatchedNode.DBManager = MovingPicturesCore.DatabaseManager;
                menu.RootNodes.Add(unwatchedNode);

                DBNode<DBMovieInfo> recentNode = new DBNode<DBMovieInfo>();
                recentNode.Name = "${RecentlyAddedMovies}";
                recentNode.DynamicNode = false;
                recentNode.Filter = new DBFilter<DBMovieInfo>();
                recentNode.SortPosition = position++;
                recentNode.DBManager = MovingPicturesCore.DatabaseManager;

                DBCriteria<DBMovieInfo> recentCriteria = new DBCriteria<DBMovieInfo>();
                recentCriteria.Field = DBField.GetFieldByDBName(typeof(DBMovieInfo), "date_added");
                recentCriteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.GREATER_THAN;
                recentCriteria.Value = "-30d";
                recentNode.Filter.Criteria.Add(recentCriteria);

                DBMovieNodeSettings additionalSettings = new DBMovieNodeSettings();
                additionalSettings.UseDefaultSorting = false;
                additionalSettings.SortField = SortingFields.DateAdded;
                additionalSettings.SortDirection = SortingDirections.Descending;
                recentNode.AdditionalSettings = additionalSettings;

                menu.RootNodes.Add(recentNode);

                DBNode<DBMovieInfo> genreNode = new DBNode<DBMovieInfo>();
                genreNode.DynamicNode = true;
                genreNode.BasicFilteringField = DBField.GetFieldByDBName(typeof(DBMovieInfo), "genres");
                genreNode.Name = "${Genres}";
                genreNode.SortPosition = position++;
                genreNode.DBManager = MovingPicturesCore.DatabaseManager;
                menu.RootNodes.Add(genreNode);

                DBNode<DBMovieInfo> certNode = new DBNode<DBMovieInfo>();
                certNode.DynamicNode = true;
                certNode.BasicFilteringField = DBField.GetFieldByDBName(typeof(DBMovieInfo), "certification");
                certNode.Name = "${" + certNode.BasicFilteringField.Name + "}";
                certNode.DBManager = MovingPicturesCore.DatabaseManager;
                certNode.SortPosition = position++;
                menu.RootNodes.Add(certNode);

                DBNode<DBMovieInfo> yearNode = new DBNode<DBMovieInfo>();
                yearNode.DynamicNode = true;
                yearNode.BasicFilteringField = DBField.GetFieldByDBName(typeof(DBMovieInfo), "year");
                yearNode.Name = "${" + yearNode.BasicFilteringField.Name + "}";
                yearNode.SortPosition = position++;
                yearNode.DBManager = MovingPicturesCore.DatabaseManager;
                menu.RootNodes.Add(yearNode);

                menu.Commit();
            }

            foreach (DBNode<DBMovieInfo> currNode in menu.RootNodes) {
                currNode.UpdateDynamicNode();
                currNode.Commit();
            }
        }
        public static void VerifyMovieManagerFilterMenu()
        {
            DBMenu<DBMovieInfo> menu = MovingPicturesCore.Settings.MovieManagerFilterMenu;

            if (menu.RootNodes.Count == 0) {
                int position = 1;

                DBNode<DBMovieInfo> allNode = new DBNode<DBMovieInfo>();
                allNode.Name = "${AllMovies}";
                allNode.DynamicNode = false;
                allNode.Filter = new DBFilter<DBMovieInfo>();
                allNode.SortPosition = position++;
                allNode.DBManager = MovingPicturesCore.DatabaseManager;
                menu.RootNodes.Add(allNode);

                DBNode<DBMovieInfo> unwatchedNode = new DBNode<DBMovieInfo>();
                unwatchedNode.Name = "${UnwatchedMovies}";
                unwatchedNode.DynamicNode = false;
                unwatchedNode.Filter = new DBFilter<DBMovieInfo>();
                DBCriteria<DBMovieInfo> criteria = new DBCriteria<DBMovieInfo>();
                criteria.Field = DBField.GetFieldByDBName(typeof(DBUserMovieSettings), "watched");
                criteria.Relation = DBRelation.GetRelation(typeof(DBMovieInfo), typeof(DBUserMovieSettings), "");
                criteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.EQUAL;
                criteria.Value = "0";
                unwatchedNode.Filter.Criteria.Add(criteria);
                unwatchedNode.SortPosition = position++;
                unwatchedNode.DBManager = MovingPicturesCore.DatabaseManager;
                menu.RootNodes.Add(unwatchedNode);

                DBNode<DBMovieInfo> recentNode = new DBNode<DBMovieInfo>();
                recentNode.Name = "${RecentlyAddedMovies}";
                recentNode.DynamicNode = false;
                recentNode.Filter = new DBFilter<DBMovieInfo>();
                recentNode.SortPosition = position++;
                recentNode.DBManager = MovingPicturesCore.DatabaseManager;

                DBCriteria<DBMovieInfo> recentCriteria = new DBCriteria<DBMovieInfo>();
                recentCriteria.Field = DBField.GetFieldByDBName(typeof(DBMovieInfo), "date_added");
                recentCriteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.GREATER_THAN;
                recentCriteria.Value = "-30d";
                recentNode.Filter.Criteria.Add(recentCriteria);

                DBMovieNodeSettings additionalSettings = new DBMovieNodeSettings();
                additionalSettings.UseDefaultSorting = false;
                additionalSettings.SortField = SortingFields.DateAdded;
                additionalSettings.SortDirection = SortingDirections.Descending;
                recentNode.AdditionalSettings = additionalSettings;
                menu.RootNodes.Add(recentNode);

                DBNode<DBMovieInfo> genreNode = new DBNode<DBMovieInfo>();
                genreNode.DynamicNode = true;
                genreNode.BasicFilteringField = DBField.GetFieldByDBName(typeof(DBMovieInfo), "genres");
                genreNode.Name = "${Genres}";
                genreNode.SortPosition = position++;
                genreNode.DBManager = MovingPicturesCore.DatabaseManager;
                menu.RootNodes.Add(genreNode);

                DBNode<DBMovieInfo> certNode = new DBNode<DBMovieInfo>();
                certNode.DynamicNode = true;
                certNode.BasicFilteringField = DBField.GetFieldByDBName(typeof(DBMovieInfo), "certification");
                certNode.Name = "${" + certNode.BasicFilteringField.Name + "}";
                certNode.DBManager = MovingPicturesCore.DatabaseManager;
                certNode.SortPosition = position++;
                menu.RootNodes.Add(certNode);

                DBNode<DBMovieInfo> yearNode = new DBNode<DBMovieInfo>();
                yearNode.DynamicNode = true;
                yearNode.BasicFilteringField = DBField.GetFieldByDBName(typeof(DBMovieInfo), "year");
                yearNode.Name = "${" + yearNode.BasicFilteringField.Name + "}";
                yearNode.SortPosition = position++;
                yearNode.DBManager = MovingPicturesCore.DatabaseManager;
                menu.RootNodes.Add(yearNode);

                DBNode<DBMovieInfo> alphaNode = new DBNode<DBMovieInfo>();
                alphaNode.DynamicNode = true;
                alphaNode.BasicFilteringField = DBField.GetFieldByDBName(typeof(DBMovieInfo), "title");
                alphaNode.Name = "${BeginsWith}";
                alphaNode.DBManager = MovingPicturesCore.DatabaseManager;
                alphaNode.SortPosition = position++;
                menu.RootNodes.Add(alphaNode);

                // maintenance node
                DBNode<DBMovieInfo> maintenanceNode = new DBNode<DBMovieInfo>();
                maintenanceNode.Name = "${Missing}";
                maintenanceNode.DynamicNode = false;
                maintenanceNode.SortPosition = position++;
                maintenanceNode.DBManager = MovingPicturesCore.DatabaseManager;
                menu.RootNodes.Add(maintenanceNode);

                // missing covers node
                DBNode<DBMovieInfo> missingCoversNode = new DBNode<DBMovieInfo>();
                missingCoversNode.Name = "${Cover}";
                missingCoversNode.Parent = maintenanceNode;
                missingCoversNode.DynamicNode = false;
                missingCoversNode.Filter = new DBFilter<DBMovieInfo>();
                missingCoversNode.SortPosition = position++;
                missingCoversNode.DBManager = MovingPicturesCore.DatabaseManager;
                maintenanceNode.Children.Add(missingCoversNode);

                DBCriteria<DBMovieInfo> missingCoversCriteria = new DBCriteria<DBMovieInfo>();
                missingCoversCriteria.Field = DBField.GetFieldByDBName(typeof(DBMovieInfo), "coverfullpath");
                missingCoversCriteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.EQUAL;
                missingCoversCriteria.Value = "";
                missingCoversNode.Filter.Criteria.Add(missingCoversCriteria);

                // missing backdrops node
                DBNode<DBMovieInfo> missingBackdropsNode = new DBNode<DBMovieInfo>();
                missingBackdropsNode.Name = "${Backdrop}";
                missingBackdropsNode.Parent = maintenanceNode;
                missingBackdropsNode.DynamicNode = false;
                missingBackdropsNode.Filter = new DBFilter<DBMovieInfo>();
                missingBackdropsNode.SortPosition = position++;
                missingBackdropsNode.DBManager = MovingPicturesCore.DatabaseManager;
                maintenanceNode.Children.Add(missingBackdropsNode);

                DBCriteria<DBMovieInfo> missingBackdropsCriteria = new DBCriteria<DBMovieInfo>();
                missingBackdropsCriteria.Field = DBField.GetFieldByDBName(typeof(DBMovieInfo), "backdropfullpath");
                missingBackdropsCriteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.EQUAL;
                missingBackdropsCriteria.Value = "";
                missingBackdropsNode.Filter.Criteria.Add(missingBackdropsCriteria);

                // invalid years, only 1900 -> next year considered valid
                DBNode<DBMovieInfo> invalidYearsNode = new DBNode<DBMovieInfo>();
                invalidYearsNode.Name = "${Year}";
                invalidYearsNode.Parent = maintenanceNode;
                invalidYearsNode.DynamicNode = false;
                invalidYearsNode.Filter = new DBFilter<DBMovieInfo>();
                invalidYearsNode.Filter.CriteriaGrouping = DBFilter<DBMovieInfo>.CriteriaGroupingEnum.ONE;
                invalidYearsNode.SortPosition = position++;
                invalidYearsNode.DBManager = MovingPicturesCore.DatabaseManager;
                maintenanceNode.Children.Add(invalidYearsNode);

                DBCriteria<DBMovieInfo> invalidYearsCriteria = new DBCriteria<DBMovieInfo>();
                invalidYearsCriteria.Field = DBField.GetFieldByDBName(typeof(DBMovieInfo), "year");
                invalidYearsCriteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.LESS_THAN;
                invalidYearsCriteria.Value = 1900;
                invalidYearsNode.Filter.Criteria.Add(invalidYearsCriteria);
                invalidYearsCriteria = new DBCriteria<DBMovieInfo>();
                invalidYearsCriteria.Field = DBField.GetFieldByDBName(typeof(DBMovieInfo), "year");
                invalidYearsCriteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.GREATER_THAN;
                invalidYearsCriteria.Value = 2030;
                invalidYearsNode.Filter.Criteria.Add(invalidYearsCriteria);

                // missing mediainfo node
                DBNode<DBMovieInfo> missingMediaInfoNode = new DBNode<DBMovieInfo>();
                missingMediaInfoNode.Name = "${MediaInfo}";
                missingMediaInfoNode.Parent = maintenanceNode;
                missingMediaInfoNode.DynamicNode = false;
                missingMediaInfoNode.Filter = new DBFilter<DBMovieInfo>();
                missingMediaInfoNode.SortPosition = position++;
                missingMediaInfoNode.DBManager = MovingPicturesCore.DatabaseManager;
                maintenanceNode.Children.Add(missingMediaInfoNode);

                DBCriteria<DBMovieInfo> missingMediaInfoCriteria = new DBCriteria<DBMovieInfo>();
                missingMediaInfoCriteria.Field = DBField.GetFieldByDBName(typeof(DBLocalMedia), "videowidth");
                missingMediaInfoCriteria.Relation = DBRelation.GetRelation(typeof(DBMovieInfo), typeof(DBLocalMedia), "");
                missingMediaInfoCriteria.Operator = DBCriteria<DBMovieInfo>.OperatorEnum.EQUAL;
                missingMediaInfoCriteria.Value = 0;
                missingMediaInfoNode.Filter.Criteria.Add(missingMediaInfoCriteria);

                menu.Commit();
            }

            foreach (DBNode<DBMovieInfo> currNode in menu.RootNodes) {
                currNode.UpdateDynamicNode();
                currNode.Commit();
            }
        }