diff --git a/models/course.py b/models/course.py index d5da7a53..f9f6103a 100644 --- a/models/course.py +++ b/models/course.py @@ -301,6 +301,8 @@ def search(params, current_user=None): count = int(params.get('count', 10)) offset = int(params.get('offset', 0)) exclude_taken_courses = (params.get('exclude_taken_courses') == "yes") + exclude_full_courses = (params.get('exclude_full_courses') == "yes") + next_term = (params.get('full_next_term') == "yes") # TODO(david): These logging things should be done asynchronously rmclogger.log_event( @@ -332,6 +334,14 @@ def regexify_keywords(keyword): else: logging.error('Anonymous user tried excluding taken courses') + if exclude_full_courses: + existing_courses = Course.objects(**filters).only('id') + with_space = section.Section.objects( + course_id__in=existing_courses, + term_id=term.Term.get_next_term_id() if next_term else term.Term.get_current_term_id() + ).where("this.enrollment_total < this.enrollment_capacity").only('course_id').distinct('course_id') + filters['id__in'] = with_space + if sort_mode == 'friends_taken' and current_user: import user friends = user.User.objects(id__in=current_user.friend_ids).only( diff --git a/server/static/js/search_page.js b/server/static/js/search_page.js index d55e6ec5..29afc21e 100644 --- a/server/static/js/search_page.js +++ b/server/static/js/search_page.js @@ -23,6 +23,8 @@ function($, _, _s, course, __, Backbone, RmcBackbone, return (sortMode.name.replace(' ', '+') === queryParams.sort_mode); }) || window.pageData.sortModes[0], excludeTakenCourses: queryParams.exclude_taken_courses || "no", + excludeFullCourses: queryParams.exclude_full_courses || "no", + fullNextTerm: queryParams.full_next_term || "no", keywords: (queryParams.keywords || '').replace('+',' ') }); @@ -56,6 +58,14 @@ function($, _, _s, course, __, Backbone, RmcBackbone, queryParams.exclude_taken_courses = view.excludeTakenCourses; } + if (view.excludeFullCourses === 'yes') { + queryParams.exclude_full_courses = view.excludeFullCourses; + } + + if (view.fullNextTerm === 'yes') { + queryParams.full_next_term = view.fullNextTerm; + } + if (view.keywords) { queryParams.keywords = view.keywords; } @@ -81,10 +91,14 @@ function($, _, _s, course, __, Backbone, RmcBackbone, courses: undefined, hasMore: true, excludeTakenCourses: undefined, + excludeFullCourses: undefined, + fullNextTerm: undefined, initialize: function(options) { this.sortMode = options.sortMode; this.excludeTakenCourses = options.excludeTakenCourses; + this.excludeFullCourses = options.excludeFullCourses; + this.fullNextTerm = options.fullNextTerm; if (!pageData.currentUserId) { this.excludeTakenCourses = "no"; @@ -125,6 +139,8 @@ function($, _, _s, course, __, Backbone, RmcBackbone, selectedSortMode: this.sortMode, getIconForMode: this.getIconForMode, excludeTakenCourses: this.excludeTakenCourses, + excludeFullCourses: this.excludeFullCourses, + fullNextTerm: this.fullNextTerm, keywords: this.keywords })); @@ -161,6 +177,10 @@ function($, _, _s, course, __, Backbone, RmcBackbone, events: { 'click .excluding-taken-courses-dropdown .dropdown-menu li': 'changeExcludeTakenCourses', + 'click .excluding-full-courses-dropdown .dropdown-menu li': + 'changeExcludeFullCourses', + 'click .excluding-full-courses-term-dropdown .dropdown-menu li': + 'changeFullNextTerm', 'click .sort-options .option': 'changeSortMode', 'input .keywords': 'changeKeywords', 'paste .keywords': 'changeKeywords' @@ -181,12 +201,32 @@ function($, _, _s, course, __, Backbone, RmcBackbone, } var $target = $(evt.currentTarget); - this.$('.selected-exclude-option').text($target.text()); + this.$('.taken-courses-exclude-option').text($target.text()); this.setExcludeTakenCourses($target.attr('data-value')); this.resetAndUpdate(); }, + changeExcludeFullCourses: function(evt) { + evt.preventDefault(); + + var $target = $(evt.currentTarget); + this.$('.full-courses-exclude-option').text($target.text()); + this.setExcludeFullCourses($target.attr('data-value')); + + this.resetAndUpdate(); + }, + + changeFullNextTerm: function(evt) { + evt.preventDefault(); + + var $target = $(evt.currentTarget); + this.$('.full-next-term-option').text($target.text()); + this.setFullNextTerm($target.attr('data-value')); + + this.resetAndUpdate(); + }, + changeSortMode: function(evt) { evt.preventDefault(); @@ -222,6 +262,14 @@ function($, _, _s, course, __, Backbone, RmcBackbone, this.excludeTakenCourses = excludeTakenCourses; }, + setExcludeFullCourses: function(excludeFullCourses) { + this.excludeFullCourses = excludeFullCourses; + }, + + setFullNextTerm: function(fullNextTerm) { + this.fullNextTerm = fullNextTerm; + }, + setSortMode: function(sortName) { this.sortMode = _.find(pageData.sortModes, function(sortMode) { return sortName === sortMode.name; @@ -266,7 +314,9 @@ function($, _, _s, course, __, Backbone, RmcBackbone, count: this.count, sort_mode: this.sortMode.name, keywords: this.keywords, - exclude_taken_courses: this.excludeTakenCourses + exclude_taken_courses: this.excludeTakenCourses, + exclude_full_courses: this.excludeFullCourses, + full_next_term: this.fullNextTerm }; this.trigger('update'); diff --git a/server/templates/search_page.html b/server/templates/search_page.html index 1e01eb95..ff3932ed 100644 --- a/server/templates/search_page.html +++ b/server/templates/search_page.html @@ -62,7 +62,7 @@