Commit 75318164 by David Ormsbee

Merge pull request #205 from MITx/course_images

Course images
parents 158bb699 f25dbc08
import time import time
import dateutil.parser import dateutil.parser
from fs.errors import ResourceNotFoundError
import logging import logging
from path import path
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.seq_module import SequenceDescriptor, SequenceModule from xmodule.seq_module import SequenceDescriptor, SequenceModule
...@@ -52,75 +50,5 @@ class CourseDescriptor(SequenceDescriptor): ...@@ -52,75 +50,5 @@ class CourseDescriptor(SequenceDescriptor):
return self.location.course return self.location.course
@property @property
def instructors(self):
return self.get_about_section("instructors").split("\n")
@property
def wiki_namespace(self): def wiki_namespace(self):
return self.location.course return self.location.course
\ No newline at end of file
def get_about_section(self, section_key):
"""
This returns the snippet of html to be rendered on the course about page, given the key for the section.
Valid keys:
- overview
- title
- university
- number
- short_description
- description
- key_dates (includes start, end, exams, etc)
- video
- course_staff_short
- course_staff_extended
- requirements
- syllabus
- textbook
- faq
- more_info
"""
# Many of these are stored as html files instead of some semantic markup. This can change without effecting
# this interface when we find a good format for defining so many snippets of text/html.
# TODO: Remove number, instructors from this list
if section_key in ['short_description', 'description', 'key_dates', 'video', 'course_staff_short', 'course_staff_extended',
'requirements', 'syllabus', 'textbook', 'faq', 'more_info', 'number', 'instructors', 'overview',
'effort', 'end_date', 'prerequisites']:
try:
with self.system.resources_fs.open(path("about") / section_key + ".html") as htmlFile:
return htmlFile.read().decode('utf-8')
except ResourceNotFoundError:
log.warning("Missing about section {key} in course {url}".format(key=section_key, url=self.location.url()))
return None
elif section_key == "title":
return self.metadata.get('display_name', self.name)
elif section_key == "university":
return self.location.org
elif section_key == "number":
return self.number
raise KeyError("Invalid about key " + str(section_key))
def get_info_section(self, section_key):
"""
This returns the snippet of html to be rendered on the course info page, given the key for the section.
Valid keys:
- handouts
- guest_handouts
- updates
- guest_updates
"""
# Many of these are stored as html files instead of some semantic markup. This can change without effecting
# this interface when we find a good format for defining so many snippets of text/html.
if section_key in ['handouts', 'guest_handouts', 'updates', 'guest_updates']:
try:
with self.system.resources_fs.open(path("info") / section_key + ".html") as htmlFile:
return htmlFile.read().decode('utf-8')
except ResourceNotFoundError:
log.exception("Missing info section {key} in course {url}".format(key=section_key, url=self.location.url()))
return "! Info section missing !"
raise KeyError("Invalid about key " + str(section_key))
from fs.errors import ResourceNotFoundError
from functools import wraps from functools import wraps
import logging
from path import path
from django.conf import settings
from django.http import Http404 from django.http import Http404
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
log = logging.getLogger(__name__)
def check_course(course_id, course_must_be_open=True, course_required=True): def check_course(course_id, course_must_be_open=True, course_required=True):
""" """
...@@ -31,3 +36,81 @@ def check_course(course_id, course_must_be_open=True, course_required=True): ...@@ -31,3 +36,81 @@ def check_course(course_id, course_must_be_open=True, course_required=True):
raise Http404("This course has not yet started.") raise Http404("This course has not yet started.")
return course return course
### These methods look like they should be on the course_module object itself, but they rely
### on the lms. Maybe they should be added dynamically to the class?
def course_static_url(course):
return settings.STATIC_URL + "/" + course.metadata['data_dir'] + "/"
def course_image_url(course):
return course_static_url(course) + "images/course_image.png"
def get_course_about_section(course, section_key):
"""
This returns the snippet of html to be rendered on the course about page, given the key for the section.
Valid keys:
- overview
- title
- university
- number
- short_description
- description
- key_dates (includes start, end, exams, etc)
- video
- course_staff_short
- course_staff_extended
- requirements
- syllabus
- textbook
- faq
- more_info
"""
# Many of these are stored as html files instead of some semantic markup. This can change without effecting
# this interface when we find a good format for defining so many snippets of text/html.
# TODO: Remove number, instructors from this list
if section_key in ['short_description', 'description', 'key_dates', 'video', 'course_staff_short', 'course_staff_extended',
'requirements', 'syllabus', 'textbook', 'faq', 'more_info', 'number', 'instructors', 'overview',
'effort', 'end_date', 'prerequisites']:
try:
with course.system.resources_fs.open(path("about") / section_key + ".html") as htmlFile:
return htmlFile.read().decode('utf-8').format(COURSE_STATIC_URL = course_static_url(course) )
except ResourceNotFoundError:
log.warning("Missing about section {key} in course {url}".format(key=section_key, url=course.location.url()))
return None
elif section_key == "title":
return course.metadata.get('display_name', course.name)
elif section_key == "university":
return course.location.org
elif section_key == "number":
return course.number
raise KeyError("Invalid about key " + str(section_key))
def get_course_info_section(course, section_key):
"""
This returns the snippet of html to be rendered on the course info page, given the key for the section.
Valid keys:
- handouts
- guest_handouts
- updates
- guest_updates
"""
# Many of these are stored as html files instead of some semantic markup. This can change without effecting
# this interface when we find a good format for defining so many snippets of text/html.
if section_key in ['handouts', 'guest_handouts', 'updates', 'guest_updates']:
try:
with course.system.resources_fs.open(path("info") / section_key + ".html") as htmlFile:
return htmlFile.read().decode('utf-8')
except ResourceNotFoundError:
log.exception("Missing info section {key} in course {url}".format(key=section_key, url=course.location.url()))
return "! Info section missing !"
raise KeyError("Invalid about key " + str(section_key))
\ No newline at end of file
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%! <%!
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from courseware.courses import course_image_url, get_course_about_section
%> %>
<%page args="course" /> <%page args="course" />
...@@ -9,25 +10,25 @@ ...@@ -9,25 +10,25 @@
<header class="course-preview"> <header class="course-preview">
<a href="${reverse('about_course', args=[course.id])}"> <a href="${reverse('about_course', args=[course.id])}">
<hgroup> <hgroup>
<h2>${course.number} ${course.get_about_section('title')}</h2> <h2>${course.number} ${get_course_about_section(course, 'title')}</h2>
</hgroup> </hgroup>
<div class="info-link">&#x2794;</div> <div class="info-link">&#x2794;</div>
</a> </a>
</header> </header>
<section class="info"> <section class="info">
<div class="cover-image"> <div class="cover-image">
<img src="${static.url('images/courses/history.png')}"> <img src="${course_image_url(course)}">
</div> </div>
<div class="desc"> <div class="desc">
<p>${course.get_about_section('short_description')}</p> <p>${get_course_about_section(course, 'short_description')}</p>
</div> </div>
<div class="bottom"> <div class="bottom">
<a href="#" class="university">${course.get_about_section('university')}</a> <a href="#" class="university">${get_course_about_section(course, 'university')}</a>
<span class="start-date">${course.start_date_text}</span> <span class="start-date">${course.start_date_text}</span>
</div> </div>
</section> </section>
</div> </div>
<div class="meta-info"> <div class="meta-info">
<p class="university">${course.get_about_section('university')}</p> <p class="university">${get_course_about_section(course, 'university')}</p>
</div> </div>
</article> </article>
<%! from django.core.urlresolvers import reverse %> <%!
from django.core.urlresolvers import reverse
from courseware.courses import course_image_url, get_course_about_section
%>
<%inherit file="main.html" /> <%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
...@@ -33,14 +36,14 @@ ...@@ -33,14 +36,14 @@
% for course in courses: % for course in courses:
<article class="my-course"> <article class="my-course">
<a href="${reverse('info', args=[course.id])}" class="cover" style="background-image: url('static/images/courses/python.png')"> <a href="${reverse('info', args=[course.id])}" class="cover" style="background-image: url('${course_image_url(course)}')">
<div class="shade"></div> <div class="shade"></div>
<div class="arrow"></div> <div class="arrow"></div>
</a> </a>
<section class="info"> <section class="info">
<hgroup> <hgroup>
<a href="#" class="university">${course.get_about_section('university')}</a> <a href="#" class="university">${get_course_about_section(course, 'university')}</a>
<h3><a href="${reverse('info', args=[course.id])}">${course.get_about_section("title")}</a></h3> <h3><a href="${reverse('info', args=[course.id])}">${get_course_about_section(course, "title")}</a></h3>
</hgroup> </hgroup>
<section class="course-status"> <section class="course-status">
<p>Class Starts - <span>9/2/2012</span></div> <p>Class Starts - <span>9/2/2012</span></div>
......
<%inherit file="main.html" /> <%inherit file="main.html" />
<%include file="course_navigation.html" args="active_page='info'" /> <%include file="course_navigation.html" args="active_page='info'" />
<%!
from courseware.courses import get_course_info_section
%>
<section class="container"> <section class="container">
<section class="course-content"> <section class="course-content">
...@@ -7,17 +10,17 @@ ...@@ -7,17 +10,17 @@
<div class="info-wrapper"> <div class="info-wrapper">
% if user.is_authenticated(): % if user.is_authenticated():
<section class="updates"> <section class="updates">
${course.get_info_section('updates')} ${get_course_info_section(course, 'updates')}
</section> </section>
<section aria-label="Handout Navigation" class="handouts"> <section aria-label="Handout Navigation" class="handouts">
${course.get_info_section('handouts')} ${get_course_info_section(course, 'handouts')}
</section> </section>
% else: % else:
<section class="updates"> <section class="updates">
${course.get_info_section('guest_updates')} ${get_course_info_section(course, 'guest_updates')}
</section> </section>
<section aria-label="Handout Navigation" class="handouts"> <section aria-label="Handout Navigation" class="handouts">
${course.get_info_section('guest_handouts')} ${get_course_info_section(course, 'guest_handouts')}
</section> </section>
% endif % endif
</div> </div>
......
<%! from django.core.urlresolvers import reverse %> <%!
from django.core.urlresolvers import reverse
from courseware.courses import course_image_url, get_course_about_section
%>
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%block name="js_extra"> <%block name="js_extra">
<script src="${static.url('js/course_info.js')}"></script> <script src="${static.url('js/course_info.js')}"></script>
...@@ -11,7 +14,7 @@ ...@@ -11,7 +14,7 @@
<div class="intro-inner-wrapper"> <div class="intro-inner-wrapper">
<section class="intro"> <section class="intro">
<hgroup> <hgroup>
<h1>${course.number}: ${course.get_about_section("title")}</h1><h2><a href="#">${course.get_about_section("university")}</a></h2> <h1>${course.number}: ${get_course_about_section(course, "title")}</h1><h2><a href="#">${get_course_about_section(course, "university")}</a></h2>
</hgroup> </hgroup>
<div class="main-cta"> <div class="main-cta">
...@@ -27,10 +30,10 @@ ...@@ -27,10 +30,10 @@
</div> </div>
</section> </section>
% if course.get_about_section("video"): % if get_course_about_section(course, "video"):
<a href="#video-modal" class="media" rel="leanModal"> <a href="#video-modal" class="media" rel="leanModal">
<div class="hero"> <div class="hero">
<img src="${static.url('images/courses/circuits.jpeg')}" /> <img src="${course_image_url(course)}" />
<div class="play-intro"></div> <div class="play-intro"></div>
</div> </div>
</a> </a>
...@@ -50,7 +53,7 @@ ...@@ -50,7 +53,7 @@
</nav> </nav>
<div class="inner-wrapper"> <div class="inner-wrapper">
${course.get_about_section("overview")} ${get_course_about_section(course, "overview")}
</div> </div>
</section> </section>
...@@ -76,16 +79,16 @@ ...@@ -76,16 +79,16 @@
<li><div class="icon start-icon"></div><p>Classes Start</p><span class="start-date">${course.start_date_text}</span></li> <li><div class="icon start-icon"></div><p>Classes Start</p><span class="start-date">${course.start_date_text}</span></li>
## End date should come from course.xml, but this is a quick hack ## End date should come from course.xml, but this is a quick hack
% if course.get_about_section("end_date"): % if get_course_about_section(course, "end_date"):
<li><div class="icon final-icon"></div><p>Classes End</p><span class="final-date">${course.get_about_section("end_date")}</span></li> <li><div class="icon final-icon"></div><p>Classes End</p><span class="final-date">${get_course_about_section(course, "end_date")}</span></li>
% endif % endif
% if course.get_about_section("effort"): % if get_course_about_section(course, "effort"):
<li><div class="icon"></div><p>Estimated Effort</p><span class="start-date">${course.get_about_section("effort")}</span></li> <li><div class="icon"></div><p>Estimated Effort</p><span class="start-date">${get_course_about_section(course, "effort")}</span></li>
% endif % endif
% if course.get_about_section("prerequisites"): % if get_course_about_section(course, "prerequisites"):
<li><div class="icon"></div><p>Prerequisites</p><span class="start-date">${course.get_about_section("prerequisites")}</span></li> <li><div class="icon"></div><p>Prerequisites</p><span class="start-date">${get_course_about_section(course, "prerequisites")}</span></li>
% endif % endif
##<li><div class="icon length-icon"></div><p>Course Length</p><span class="course-length">15 weeks</span></li> ##<li><div class="icon length-icon"></div><p>Course Length</p><span class="course-length">15 weeks</span></li>
......
<%!
from courseware.courses import get_course_about_section
%>
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<section id="video-modal" class="modal video-modal"> <section id="video-modal" class="modal video-modal">
<div class="inner-wrapper"> <div class="inner-wrapper">
${course.get_about_section("video")} ${get_course_about_section(course, "video")}
</div> </div>
</section> </section>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment