diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 44877ef597f2ff6104750eda5994ee4baa3858a1..a8981177d9b3f9119027a4f22dac8015ef2310db 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -40,7 +40,7 @@ from xmodule.modulestore.exceptions import ItemNotFoundError from datetime import date from collections import namedtuple -from courseware.courses import get_courses_by_university +from courseware.courses import get_courses_by_start_date from courseware.access import has_access from statsd import statsd @@ -74,16 +74,17 @@ def index(request, extra_context={}, user=None): domain = settings.MITX_FEATURES.get('FORCE_UNIVERSITY_DOMAIN') # normally False if domain==False: # do explicit check, because domain=None is valid domain = request.META.get('HTTP_HOST') - universities = get_courses_by_university(None, - domain=domain) + + courses = get_courses_by_start_date(None, domain=domain) # Get the 3 most recent news top_news = _get_news(top=3) - context = {'universities': universities, 'news': top_news} + context = {'courses': courses, 'news': top_news} context.update(extra_context) return render_to_response('index.html', context) + def course_from_id(course_id): """Return the CourseDescriptor corresponding to this course_id""" course_loc = CourseDescriptor.id_to_location(course_id) diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index 65a1eee25bd3611d1ba17ed609c4e854f3b03688..0f039b6cf5e532cf4aaf6412c76e665dd4757a51 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -217,11 +217,66 @@ def get_courses_by_university(user, domain=None): ''' # TODO: Clean up how 'error' is done. # filter out any courses that errored. - visible_courses = branding.get_visible_courses(domain) + visible_courses = get_courses(user, domain) universities = defaultdict(list) for course in visible_courses: - if not has_access(user, course, 'see_exists'): - continue universities[course.org].append(course) + return universities + + +def get_courses(user, domain=None): + ''' + Returns a list of courses available, sorted by course.number + ''' + courses = branding.get_visible_courses(domain) + courses = [c for c in courses if has_access(user, c, 'see_exists')] + + return courses + + +def get_courses_by_start_date(user, domain=None): + """ + Returns a list of courses available, sorted by start date + """ + visible_courses = get_courses(user, domain) + courses = _sort_courses_and_mark_new(visible_courses) + + return courses + + +def _sort_courses_and_mark_new(courses): + """Sort by course start date and mark which have not started yet""" + for course in courses: + days_to_start = _get_course_days_to_start(course) + + # Add values as attributes, so they can be used in templates + setattr(course, '_days_to_start', days_to_start) + setattr(course, 'is_new', days_to_start > 1) + + courses = sorted(courses, key=lambda d: d._days_to_start, reverse=True) + + return courses + + +def _get_course_days_to_start(course): + from datetime import datetime as dt + from time import mktime, gmtime + + convert_to_datetime = lambda ts: dt.fromtimestamp(mktime(ts)) + + start_date = convert_to_datetime(course.start) + + # If the course has a valid advertised date, use that instead + advertised_start = course.metadata.get('advertised_start', None) + if advertised_start: + try: + start_date = dt.strptime(advertised_start, "%Y-%m-%dT%H:%M") + except ValueError: + pass # Invalid date, keep using course.start + + now = convert_to_datetime(gmtime()) + days_to_start = (start_date - now).days + + return days_to_start diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py index 276af80ca916a086077d8e5fb76c9146fab0e6ef..dc83061fcd6e30b2b83d013e636d0daa499abe64 100644 --- a/lms/djangoapps/courseware/views.py +++ b/lms/djangoapps/courseware/views.py @@ -17,7 +17,7 @@ from django.views.decorators.cache import cache_control from courseware import grades from courseware.access import has_access -from courseware.courses import (get_course_with_access, get_courses_by_university) +from courseware.courses import (get_course_with_access, get_courses_by_start_date) import courseware.tabs as tabs from courseware.models import StudentModuleCache from module_render import toc_for_course, get_module, get_instance_module @@ -68,9 +68,9 @@ def courses(request): ''' Render "find courses" page. The course selection work is done in courseware.courses. ''' - universities = get_courses_by_university(request.user, + courses = get_courses_by_start_date(request.user, domain=request.META.get('HTTP_HOST')) - return render_to_response("courseware/courses.html", {'universities': universities}) + return render_to_response("courseware/courses.html", {'courses': courses}) def render_accordion(request, course, chapter, section): @@ -317,7 +317,7 @@ def jump_to(request, course_id, location): except NoPathToItem: raise Http404("This location is not in any class: {0}".format(location)) - # choose the appropriate view (and provide the necessary args) based on the + # choose the appropriate view (and provide the necessary args) based on the # args provided by the redirect. # Rely on index to do all error handling and access control. if chapter is None: @@ -328,7 +328,7 @@ def jump_to(request, course_id, location): return redirect('courseware_section', course_id=course_id, chapter=chapter, section=section) else: return redirect('courseware_position', course_id=course_id, chapter=chapter, section=section, position=position) - + @ensure_csrf_cookie def course_info(request, course_id): """ diff --git a/lms/static/sass/shared/_course_object.scss b/lms/static/sass/shared/_course_object.scss index 3adcc11534ad9ca61c52cad8019e43e9eba6b846..2c638ed15841a9fa06953c3f1e5042d06d50b475 100644 --- a/lms/static/sass/shared/_course_object.scss +++ b/lms/static/sass/shared/_course_object.scss @@ -41,6 +41,31 @@ width: 100%; @include transition(all, 0.15s, linear); + .status { + background: $blue; + color: white; + font-size: 10px; + left: 10px; + padding: 2px 10px; + @include border-radius(2px); + position: absolute; + text-transform: uppercase; + top: -6px; + z-index: 100; + } + + .status:after { + border-bottom: 6px solid shade($blue, 50%); + border-right: 6px solid transparent; + content: ""; + display: block; + height: 0; + position: absolute; + right: -6px; + top: 0; + width: 0; + } + a:hover { text-decoration: none; } diff --git a/lms/templates/course.html b/lms/templates/course.html index 50a00f9d3160f2d53a1f1fc13ae99d626329824c..a2eff572e1078a8b8fe5143050528781714d63e0 100644 --- a/lms/templates/course.html +++ b/lms/templates/course.html @@ -5,6 +5,9 @@ %> <%page args="course" /> <article id="${course.id}" class="course"> + %if course.is_new: + <span class="status">New</span> + %endif <a href="${reverse('about_course', args=[course.id])}"> <div class="inner-wrapper"> <header class="course-preview"> diff --git a/lms/templates/courseware/courses.html b/lms/templates/courseware/courses.html index 0c45faa92355c4aeda2fc9dc66cbc33475d28351..a8fe851d19dea8fcf9f8b9f5c0616e1d75e63f19 100644 --- a/lms/templates/courseware/courses.html +++ b/lms/templates/courseware/courses.html @@ -20,21 +20,13 @@ ## I'm removing this for now since we aren't using it for the fall. ## <%include file="course_filter.html" /> <section class="courses"> - <section class='university-column'> - %for course in universities['MITx']: + <ul class="courses-listing"> + %for course in courses: + <li class="courses-listing-item"> <%include file="../course.html" args="course=course" /> + </li> %endfor - </section> - <section class='university-column'> - %for course in universities['HarvardX']: - <%include file="../course.html" args="course=course" /> - %endfor - </section> - <section class='university-column last'> - %for course in universities['BerkeleyX']: - <%include file="../course.html" args="course=course" /> - %endfor - </section> + </ul> </section> </section> </section> diff --git a/lms/templates/index.html b/lms/templates/index.html index ca15eeae8160a5c28c168f9d5ef53be54b6428d8..d82c9120d457ae2c02b243843bac81d0586c56d6 100644 --- a/lms/templates/index.html +++ b/lms/templates/index.html @@ -106,21 +106,13 @@ </section> <section class="courses"> - <section class='university-column'> - %for course in universities['MITx']: - <%include file="course.html" args="course=course" /> + <ul class="courses-listing"> + %for course in courses: + <li class="courses-listing-item"> + <%include file="course.html" args="course=course" /> + </li> %endfor - </section> - <section class='university-column'> - %for course in universities['HarvardX']: - <%include file="course.html" args="course=course" /> - %endfor - </section> - <section class='university-column last'> - %for course in universities['BerkeleyX']: - <%include file="course.html" args="course=course" /> - %endfor - </section> + </ul> </section> </section> </section> diff --git a/lms/templates/static_templates/_courses-newlisting.html b/lms/templates/static_templates/_courses-newlisting.html deleted file mode 100644 index 97985977c1c323271cf4306503e817d537c703ef..0000000000000000000000000000000000000000 --- a/lms/templates/static_templates/_courses-newlisting.html +++ /dev/null @@ -1,301 +0,0 @@ -<ul class="courses-listing"> - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> - - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> - - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> - - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> - - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> - - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> - - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> - - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> - - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> - - <li class="courses-listing-item"> - <article id="MITx/6.002x/2012_Fall" class="course"> - <a href="/courses/MITx/6.002x/2012_Fall/about"></a> - <div class="inner-wrapper"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <header class="course-preview"> - <hgroup> - <h2><span class="course-number">6.002x</span> Circuits and Electronics</h2> - </hgroup> - <div class="info-link">âž”</div> - </header> - </a><section class="info"><a href="/courses/MITx/6.002x/2012_Fall/about"> - <div class="cover-image"> - <img src="/static/content-mit-6002x/images/course_image.jpg"> - </div> - <div class="desc"> - <p>6.002x teaches the fundamentals of circuit and electronic analysis. - </p> - </div> - </a><div class="bottom"><a href="/courses/MITx/6.002x/2012_Fall/about"> - </a><a href="/university_profile/MITx" class="university">MITx</a> - <span class="start-date">Sep 05, 2012</span> - </div> - </section> - </div> - <div class="meta-info"> - <p class="university">MITx</p> - </div> - </article> - </li> -</ul> \ No newline at end of file