Commit 3b537e00 by Calen Pennington

Merge remote-tracking branch 'origin/release/1.0'

Conflicts:
	common/djangoapps/student/views.py
parents 2f98db43 361a6791
...@@ -22,3 +22,5 @@ reports/ ...@@ -22,3 +22,5 @@ reports/
\#*\# \#*\#
*.egg-info *.egg-info
Gemfile.lock Gemfile.lock
.env/
see doc/ for documentation. See doc/ for documentation.
...@@ -6,11 +6,7 @@ ...@@ -6,11 +6,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
<%static:css group='base-style'/> <%static:css group='base-style'/>
% else:
<link rel="stylesheet" href="${static.url('css/base-style.css')}">
% endif
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/markitup/skins/simple/style.css')}" /> <link rel="stylesheet" type="text/css" href="${static.url('js/vendor/markitup/skins/simple/style.css')}" />
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/markitup/sets/wiki/style.css')}" /> <link rel="stylesheet" type="text/css" href="${static.url('js/vendor/markitup/sets/wiki/style.css')}" />
<title><%block name="title"></%block></title> <title><%block name="title"></%block></title>
...@@ -27,12 +23,7 @@ ...@@ -27,12 +23,7 @@
<script type="text/javascript" src="${static.url('js/vendor/backbone-min.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/backbone-min.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/markitup/jquery.markitup.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/markitup/jquery.markitup.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/markitup/sets/wiki/set.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/markitup/sets/wiki/set.js')}"></script>
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
<%static:js group='main'/> <%static:js group='main'/>
% else:
<script src="${ STATIC_URL }/js/main.js"></script>
% endif
<%static:js group='module-js'/> <%static:js group='module-js'/>
<script src="${static.url('js/vendor/jquery.inlineedit.js')}"></script> <script src="${static.url('js/vendor/jquery.inlineedit.js')}"></script>
<script src="${static.url('js/vendor/jquery.cookie.js')}"></script> <script src="${static.url('js/vendor/jquery.cookie.js')}"></script>
......
...@@ -10,10 +10,10 @@ ...@@ -10,10 +10,10 @@
<hr> <hr>
</header> </header>
<div id="enroll"> <div id="register">
<form id="enroll_form" method="post"> <form id="register_form" method="post">
<div id="enroll_error" name="enroll_error"></div> <div id="register_error" name="register_error"></div>
<label>E-mail</label> <label>E-mail</label>
<input name="email" type="email" placeholder="E-mail"> <input name="email" type="email" placeholder="E-mail">
<label>Password</label> <label>Password</label>
...@@ -64,17 +64,17 @@ ...@@ -64,17 +64,17 @@
}); });
} }
$('form#enroll_form').submit(function(e) { $('form#register_form').submit(function(e) {
e.preventDefault(); e.preventDefault();
var submit_data = $('#enroll_form').serialize(); var submit_data = $('#register_form').serialize();
postJSON('/create_account', postJSON('/create_account',
submit_data, submit_data,
function(json) { function(json) {
if(json.success) { if(json.success) {
$('#enroll').html(json.value); $('#register').html(json.value);
} else { } else {
$('#enroll_error').html(json.value).stop().css("background-color", "#933").animate({ backgroundColor: "#333"}, 2000); $('#register_error').html(json.value).stop().css("background-color", "#933").animate({ backgroundColor: "#333"}, 2000);
} }
} }
); );
......
...@@ -5,6 +5,24 @@ from static_replace import replace_urls ...@@ -5,6 +5,24 @@ from static_replace import replace_urls
%> %>
<%def name='url(file)'>${staticfiles_storage.url(file)}</%def> <%def name='url(file)'>${staticfiles_storage.url(file)}</%def>
<%def name='css(group)'>${compressed_css(group)}</%def>
<%def name='js(group)'>${compressed_js(group)}</%def> <%def name='css(group)'>
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
${compressed_css(group)}
% else:
% for filename in settings.PIPELINE_CSS[group]['source_filenames']:
<link rel="stylesheet" href="${staticfiles_storage.url(filename.replace('.scss', '.css'))}" type="text/css" media="all" / >
% endfor
%endif
</%def>
<%def name='js(group)'>
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
${compressed_js(group)}
% else:
% for filename in settings.PIPELINE_JS[group]['source_filenames']:
<script type="text/javascript" src="${staticfiles_storage.url(filename.replace('.coffee', '.js'))}"></script>
% endfor
%endif
</%def>
<%def name='replace_urls(text)'>${replace_urls(text)}</%def> <%def name='replace_urls(text)'>${replace_urls(text)}</%def>
##
## One-off script to export 6.002x users into the edX framework
##
## Could be modified to be general by:
## * Changing user_keys and up_keys to handle dates more cleanly
## * Providing a generic set of tables, rather than just users and user profiles
## * Handling certificates and grades
## * Handling merge/forks of UserProfile.meta
import datetime
import json
import os.path
from lxml import etree
from django.core.management.base import BaseCommand
from django.conf import settings
from django.contrib.auth.models import User
from student.models import UserProfile
import mitxmako.middleware as middleware
middleware.MakoMiddleware()
class Command(BaseCommand):
help = \
'''Exports all users and user profiles.
Caveat: Should be looked over before any run
for schema changes.
Current version grabs user_keys from
django.contrib.auth.models.User and up_keys
from student.userprofile. '''
def handle(self, *args, **options):
users = list(User.objects.all())
user_profiles = list(UserProfile.objects.all())
user_profile_dict = dict([(up.user_id, up) for up in user_profiles])
user_tuples = [(user_profile_dict[u.id], u) for u in users if u.id in user_profile_dict]
user_keys = ['id', 'username', 'email', 'password', 'is_staff',
'is_active', 'is_superuser', 'last_login', 'date_joined',
'password']
up_keys = ['language', 'location','meta','name', 'id','user_id']
def extract_dict(keys, object):
d = {}
for key in keys:
item = object.__getattribute__(key)
if type(item) == datetime.datetime:
item = item.isoformat()
d[key] = item
return d
extracted = [{'up':extract_dict(up_keys, t[0]), 'u':extract_dict(user_keys, t[1])} for t in user_tuples]
fp = open('transfer_users.txt', 'w')
json.dump(extracted, fp)
fp.close()
##
## One-off script to import 6.002x users into the edX framework
## See export for more info
import datetime
import json
import dateutil.parser
import os.path
from lxml import etree
from django.core.management.base import BaseCommand
from django.conf import settings
from django.contrib.auth.models import User
from student.models import UserProfile
import mitxmako.middleware as middleware
middleware.MakoMiddleware()
def import_user(u):
user_info = u['u']
up_info = u['up']
# HACK to handle dates
user_info['last_login'] = dateutil.parser.parse(user_info['last_login'])
user_info['date_joined'] = dateutil.parser.parse(user_info['date_joined'])
user_keys = ['id', 'username', 'email', 'password', 'is_staff',
'is_active', 'is_superuser', 'last_login', 'date_joined',
'password']
up_keys = ['language', 'location','meta','name', 'id','user_id']
u = User()
for key in user_keys:
u.__setattr__(key, user_info[key])
u.save()
up = UserProfile()
up.user = u
for key in up_keys:
up.__setattr__(key, up_info[key])
up.save()
class Command(BaseCommand):
help = \
'''Exports all users and user profiles.
Caveat: Should be looked over before any run
for schema changes.
Current version grabs user_keys from
django.contrib.auth.models.User and up_keys
from student.userprofile. '''
def handle(self, *args, **options):
extracted = json.load(open('transfer_users.txt'))
n=0
for u in extracted:
import_user(u)
if n%100 == 0:
print n
n = n+1
...@@ -8,19 +8,22 @@ from django.db import models ...@@ -8,19 +8,22 @@ from django.db import models
class Migration(SchemaMigration): class Migration(SchemaMigration):
def forwards(self, orm): def forwards(self, orm):
# Removing unique constraint on 'CourseEnrollment', fields ['user'] # This table is dropped in a subsequent migration. This migration was causing problems when using InnoDB,
db.delete_unique('student_courseenrollment', ['user_id']) # so we are just dropping it.
pass
# # Removing unique constraint on 'CourseEnrollment', fields ['user']
# Changing field 'CourseEnrollment.user' # db.delete_unique('student_courseenrollment', ['user_id'])
db.alter_column('student_courseenrollment', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])) #
#
# # Changing field 'CourseEnrollment.user'
# db.alter_column('student_courseenrollment', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User']))
def backwards(self, orm): def backwards(self, orm):
pass
# Changing field 'CourseEnrollment.user' # # Changing field 'CourseEnrollment.user'
db.alter_column('student_courseenrollment', 'user_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True)) # db.alter_column('student_courseenrollment', 'user_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True))
# Adding unique constraint on 'CourseEnrollment', fields ['user'] # # Adding unique constraint on 'CourseEnrollment', fields ['user']
db.create_unique('student_courseenrollment', ['user_id']) # db.create_unique('student_courseenrollment', ['user_id'])
models = { models = {
......
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'UserProfile.meta'
db.alter_column('auth_userprofile', 'meta', self.gf('django.db.models.fields.TextField')())
def backwards(self, orm):
# Changing field 'UserProfile.meta'
db.alter_column('auth_userprofile', 'meta', self.gf('django.db.models.fields.CharField')(max_length=255))
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'student.courseenrollment': {
'Meta': {'object_name': 'CourseEnrollment'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'student.pendingemailchange': {
'Meta': {'object_name': 'PendingEmailChange'},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_email': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.pendingnamechange': {
'Meta': {'object_name': 'PendingNameChange'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'rationale': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.registration': {
'Meta': {'object_name': 'Registration', 'db_table': "'auth_registration'"},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.userprofile': {
'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"},
'country': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'gender': ('django.db.models.fields.CharField', [], {'max_length': '6', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'occupation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'telephone_number': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'student.usertestgroup': {
'Meta': {'object_name': 'UserTestGroup'},
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'})
}
}
complete_apps = ['student']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting model 'CourseEnrollment'
db.delete_table('student_courseenrollment')
def backwards(self, orm):
# Adding model 'CourseEnrollment'
db.create_table('student_courseenrollment', (
('course_id', self.gf('django.db.models.fields.CharField')(max_length=255)),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
))
db.send_create_signal('student', ['CourseEnrollment'])
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'student.pendingemailchange': {
'Meta': {'object_name': 'PendingEmailChange'},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_email': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.pendingnamechange': {
'Meta': {'object_name': 'PendingNameChange'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'rationale': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.registration': {
'Meta': {'object_name': 'Registration', 'db_table': "'auth_registration'"},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.userprofile': {
'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"},
'country': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'gender': ('django.db.models.fields.CharField', [], {'max_length': '6', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'occupation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'telephone_number': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'student.usertestgroup': {
'Meta': {'object_name': 'UserTestGroup'},
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'})
}
}
complete_apps = ['student']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'CourseEnrollment'
db.create_table('student_courseenrollment', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('course_id', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)),
))
db.send_create_signal('student', ['CourseEnrollment'])
# Adding unique constraint on 'CourseEnrollment', fields ['user', 'course_id']
db.create_unique('student_courseenrollment', ['user_id', 'course_id'])
def backwards(self, orm):
# Removing unique constraint on 'CourseEnrollment', fields ['user', 'course_id']
db.delete_unique('student_courseenrollment', ['user_id', 'course_id'])
# Deleting model 'CourseEnrollment'
db.delete_table('student_courseenrollment')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'student.courseenrollment': {
'Meta': {'unique_together': "(('user', 'course_id'),)", 'object_name': 'CourseEnrollment'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'student.pendingemailchange': {
'Meta': {'object_name': 'PendingEmailChange'},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_email': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.pendingnamechange': {
'Meta': {'object_name': 'PendingNameChange'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'rationale': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.registration': {
'Meta': {'object_name': 'Registration', 'db_table': "'auth_registration'"},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.userprofile': {
'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"},
'country': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'gender': ('django.db.models.fields.CharField', [], {'max_length': '6', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'occupation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'telephone_number': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'student.usertestgroup': {
'Meta': {'object_name': 'UserTestGroup'},
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'})
}
}
complete_apps = ['student']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'CourseEnrollment.date'
db.add_column('student_courseenrollment', 'date',
self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, null=True, blank=True),
keep_default=False)
# Changing field 'UserProfile.country'
db.alter_column('auth_userprofile', 'country', self.gf('django_countries.fields.CountryField')(max_length=2, null=True))
def backwards(self, orm):
# Deleting field 'CourseEnrollment.date'
db.delete_column('student_courseenrollment', 'date')
# Changing field 'UserProfile.country'
db.alter_column('auth_userprofile', 'country', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'student.courseenrollment': {
'Meta': {'unique_together': "(('user', 'course_id'),)", 'object_name': 'CourseEnrollment'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'student.pendingemailchange': {
'Meta': {'object_name': 'PendingEmailChange'},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_email': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.pendingnamechange': {
'Meta': {'object_name': 'PendingNameChange'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'rationale': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.registration': {
'Meta': {'object_name': 'Registration', 'db_table': "'auth_registration'"},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.userprofile': {
'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"},
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'null': 'True', 'blank': 'True'}),
'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'gender': ('django.db.models.fields.CharField', [], {'max_length': '6', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'occupation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'telephone_number': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'student.usertestgroup': {
'Meta': {'object_name': 'UserTestGroup'},
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'})
}
}
complete_apps = ['student']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Rename 'date' field to 'created'
db.rename_column('student_courseenrollment', 'date', 'created')
def backwards(self, orm):
# Rename 'created' field to 'date'
db.rename_column('student_courseenrollment', 'created', 'date')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'student.courseenrollment': {
'Meta': {'unique_together': "(('user', 'course_id'),)", 'object_name': 'CourseEnrollment'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'student.pendingemailchange': {
'Meta': {'object_name': 'PendingEmailChange'},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_email': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.pendingnamechange': {
'Meta': {'object_name': 'PendingNameChange'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'rationale': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.registration': {
'Meta': {'object_name': 'Registration', 'db_table': "'auth_registration'"},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.userprofile': {
'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"},
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'null': 'True', 'blank': 'True'}),
'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'gender': ('django.db.models.fields.CharField', [], {'max_length': '6', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'occupation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'telephone_number': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'student.usertestgroup': {
'Meta': {'object_name': 'UserTestGroup'},
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'})
}
}
complete_apps = ['student']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding index on 'CourseEnrollment', fields ['created']
db.create_index('student_courseenrollment', ['created'])
def backwards(self, orm):
# Removing index on 'CourseEnrollment', fields ['created']
db.delete_index('student_courseenrollment', ['created'])
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'student.courseenrollment': {
'Meta': {'unique_together': "(('user', 'course_id'),)", 'object_name': 'CourseEnrollment'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'student.pendingemailchange': {
'Meta': {'object_name': 'PendingEmailChange'},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_email': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.pendingnamechange': {
'Meta': {'object_name': 'PendingNameChange'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'rationale': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.registration': {
'Meta': {'object_name': 'Registration', 'db_table': "'auth_registration'"},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.userprofile': {
'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"},
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'null': 'True', 'blank': 'True'}),
'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'gender': ('django.db.models.fields.CharField', [], {'max_length': '6', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'occupation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'telephone_number': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'student.usertestgroup': {
'Meta': {'object_name': 'UserTestGroup'},
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'})
}
}
complete_apps = ['student']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting field 'UserProfile.occupation'
db.delete_column('auth_userprofile', 'occupation')
# Deleting field 'UserProfile.telephone_number'
db.delete_column('auth_userprofile', 'telephone_number')
# Deleting field 'UserProfile.date_of_birth'
db.delete_column('auth_userprofile', 'date_of_birth')
# Deleting field 'UserProfile.country'
db.delete_column('auth_userprofile', 'country')
# Adding field 'UserProfile.year_of_birth'
db.add_column('auth_userprofile', 'year_of_birth',
self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True),
keep_default=False)
# Adding field 'UserProfile.level_of_education'
db.add_column('auth_userprofile', 'level_of_education',
self.gf('django.db.models.fields.CharField')(db_index=True, max_length=6, null=True, blank=True),
keep_default=False)
# Adding field 'UserProfile.goals'
db.add_column('auth_userprofile', 'goals',
self.gf('django.db.models.fields.TextField')(null=True, blank=True),
keep_default=False)
# Adding index on 'UserProfile', fields ['gender']
db.create_index('auth_userprofile', ['gender'])
def backwards(self, orm):
# Removing index on 'UserProfile', fields ['gender']
db.delete_index('auth_userprofile', ['gender'])
# Adding field 'UserProfile.occupation'
db.add_column('auth_userprofile', 'occupation',
self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
keep_default=False)
# Adding field 'UserProfile.telephone_number'
db.add_column('auth_userprofile', 'telephone_number',
self.gf('django.db.models.fields.CharField')(max_length=25, null=True, blank=True),
keep_default=False)
# Adding field 'UserProfile.date_of_birth'
db.add_column('auth_userprofile', 'date_of_birth',
self.gf('django.db.models.fields.DateField')(null=True, blank=True),
keep_default=False)
# Adding field 'UserProfile.country'
db.add_column('auth_userprofile', 'country',
self.gf('django_countries.fields.CountryField')(max_length=2, null=True, blank=True),
keep_default=False)
# Deleting field 'UserProfile.year_of_birth'
db.delete_column('auth_userprofile', 'year_of_birth')
# Deleting field 'UserProfile.level_of_education'
db.delete_column('auth_userprofile', 'level_of_education')
# Deleting field 'UserProfile.goals'
db.delete_column('auth_userprofile', 'goals')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'student.courseenrollment': {
'Meta': {'unique_together': "(('user', 'course_id'),)", 'object_name': 'CourseEnrollment'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'student.pendingemailchange': {
'Meta': {'object_name': 'PendingEmailChange'},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_email': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.pendingnamechange': {
'Meta': {'object_name': 'PendingNameChange'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'rationale': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.registration': {
'Meta': {'object_name': 'Registration', 'db_table': "'auth_registration'"},
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'student.userprofile': {
'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"},
'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}),
'gender': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '6', 'null': 'True', 'blank': 'True'}),
'goals': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'level_of_education': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '6', 'null': 'True', 'blank': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"}),
'year_of_birth': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'})
},
'student.usertestgroup': {
'Meta': {'object_name': 'UserTestGroup'},
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'})
}
}
complete_apps = ['student']
\ No newline at end of file
...@@ -5,14 +5,16 @@ If you make changes to this model, be sure to create an appropriate migration ...@@ -5,14 +5,16 @@ If you make changes to this model, be sure to create an appropriate migration
file and check it in at the same time as your model changes. To do that, file and check it in at the same time as your model changes. To do that,
1. Go to the mitx dir 1. Go to the mitx dir
2. ./manage.py schemamigration user --auto description_of_your_change 2. django-admin.py schemamigration student --auto --settings=lms.envs.dev --pythonpath=. description_of_your_change
3. Add the migration file created in mitx/courseware/migrations/ 3. Add the migration file created in mitx/common/djangoapps/student/migrations/
""" """
from datetime import datetime
import json
import uuid import uuid
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
import json from django_countries import CountryField
#from cache_toolbox import cache_model, cache_relation #from cache_toolbox import cache_model, cache_relation
...@@ -20,23 +22,43 @@ class UserProfile(models.Model): ...@@ -20,23 +22,43 @@ class UserProfile(models.Model):
class Meta: class Meta:
db_table = "auth_userprofile" db_table = "auth_userprofile"
GENDER_CHOICES = (('male', 'Male'), ('female', 'Female'), ('other', 'Other'))
## CRITICAL TODO/SECURITY ## CRITICAL TODO/SECURITY
# Sanitize all fields. # Sanitize all fields.
# This is not visible to other users, but could introduce holes later # This is not visible to other users, but could introduce holes later
user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile') user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile')
name = models.CharField(blank=True, max_length=255, db_index=True) name = models.CharField(blank=True, max_length=255, db_index=True)
language = models.CharField(blank=True, max_length=255, db_index=True)
location = models.CharField(blank=True, max_length=255, db_index=True) # TODO: What are we doing with this?
meta = models.TextField(blank=True) # JSON dictionary for future expansion meta = models.TextField(blank=True) # JSON dictionary for future expansion
courseware = models.CharField(blank=True, max_length=255, default='course.xml') courseware = models.CharField(blank=True, max_length=255, default='course.xml')
gender = models.CharField(blank=True, null=True, max_length=6, choices=GENDER_CHOICES)
date_of_birth = models.DateField(blank=True, null=True) # Location is no longer used, but is held here for backwards compatibility
# for users imported from our first class.
language = models.CharField(blank=True, max_length=255, db_index=True)
location = models.CharField(blank=True, max_length=255, db_index=True)
# Optional demographic data we started capturing from Fall 2012
this_year = datetime.now().year
VALID_YEARS = range(this_year, this_year - 120, -1)
year_of_birth = models.IntegerField(blank=True, null=True, db_index=True)
GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'), ('o', 'Other'))
gender = models.CharField(blank=True, null=True, max_length=6, db_index=True,
choices=GENDER_CHOICES)
LEVEL_OF_EDUCATION_CHOICES = (('p_se', 'Doctorate in science or engineering'),
('p_oth', 'Doctorate in another field'),
('m', "Master's or professional degree"),
('b', "Bachelor's degree"),
('hs', "Secondary/high school"),
('jhs', "Junior secondary/junior high/middle school"),
('el', "Elementary/primary school"),
('none', "None"),
('other', "Other"))
level_of_education = models.CharField(
blank=True, null=True, max_length=6, db_index=True,
choices=LEVEL_OF_EDUCATION_CHOICES
)
mailing_address = models.TextField(blank=True, null=True) mailing_address = models.TextField(blank=True, null=True)
country = models.CharField(blank=True, null=True, max_length=255) goals = models.TextField(blank=True, null=True)
telephone_number = models.CharField(blank=True, null=True, max_length=25)
occupation = models.CharField(blank=True, null=True, max_length=255)
def get_meta(self): def get_meta(self):
js_str = self.meta js_str = self.meta
...@@ -90,8 +112,13 @@ class PendingEmailChange(models.Model): ...@@ -90,8 +112,13 @@ class PendingEmailChange(models.Model):
activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True) activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True)
class CourseEnrollment(models.Model): class CourseEnrollment(models.Model):
user = models.ForeignKey(User, db_index=True) user = models.ForeignKey(User)
course_id = models.CharField(max_length=255) course_id = models.CharField(max_length=255, db_index=True)
created = models.DateTimeField(auto_now_add=True, null=True, db_index=True)
class Meta:
unique_together = (('user', 'course_id'), )
#cache_relation(User.profile) #cache_relation(User.profile)
......
...@@ -5,6 +5,10 @@ import random ...@@ -5,6 +5,10 @@ import random
import string import string
import sys import sys
import uuid import uuid
import feedparser
import urllib
import itertools
from collections import defaultdict
from django.conf import settings from django.conf import settings
from django.contrib.auth import logout, authenticate, login from django.contrib.auth import logout, authenticate, login
...@@ -19,14 +23,18 @@ from django.http import HttpResponse, Http404 ...@@ -19,14 +23,18 @@ from django.http import HttpResponse, Http404
from django.shortcuts import redirect from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string from mitxmako.shortcuts import render_to_response, render_to_string
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from BeautifulSoup import BeautifulSoup
from django.core.cache import cache
from courseware.courses import check_course
from django_future.csrf import ensure_csrf_cookie from django_future.csrf import ensure_csrf_cookie
from student.models import Registration, UserProfile, PendingNameChange, PendingEmailChange, CourseEnrollment from student.models import Registration, UserProfile, PendingNameChange, PendingEmailChange, CourseEnrollment
from util.cache import cache_if_anonymous from util.cache import cache_if_anonymous
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError
from models import Registration, UserProfile, PendingNameChange, PendingEmailChange, CourseEnrollment
from datetime import date
log = logging.getLogger("mitx.student") log = logging.getLogger("mitx.student")
...@@ -43,39 +51,129 @@ def csrf_token(context): ...@@ -43,39 +51,129 @@ def csrf_token(context):
@ensure_csrf_cookie @ensure_csrf_cookie
@cache_if_anonymous @cache_if_anonymous
def index(request): def index(request):
''' Redirects to main page -- info page if user authenticated, or marketing if not ''' Redirects to main page -- info page if user authenticated, or marketing if not
''' '''
if settings.COURSEWARE_ENABLED and request.user.is_authenticated(): if settings.COURSEWARE_ENABLED and request.user.is_authenticated():
return redirect(reverse('dashboard')) return redirect(reverse('dashboard'))
feed_data = cache.get("students_index_rss_feed_data")
if feed_data == None:
if hasattr(settings, 'RSS_URL'):
feed_data = urllib.urlopen(settings.RSS_URL).read()
else: else:
# TODO: Clean up how 'error' is done. feed_data = render_to_string("feed.rss", None)
return render_to_response('index.html', {'courses': modulestore().get_courses()}) cache.set("students_index_rss_feed_data", feed_data, settings.RSS_TIMEOUT)
feed = feedparser.parse(feed_data)
entries = feed['entries'][0:3]
for entry in entries:
soup = BeautifulSoup(entry.description)
entry.image = soup.img['src'] if soup.img else None
entry.summary = soup.getText()
universities = defaultdict(list)
courses = sorted(modulestore().get_courses(), key=lambda course: course.number)
for course in courses:
universities[course.org].append(course)
return render_to_response('index.html', {'universities': universities, 'entries': entries})
def course_from_id(id):
course_loc = CourseDescriptor.id_to_location(id)
return modulestore().get_item(course_loc)
@login_required @login_required
@ensure_csrf_cookie @ensure_csrf_cookie
def dashboard(request): def dashboard(request):
csrf_token = csrf(request)['csrf_token']
user = request.user user = request.user
enrollments = CourseEnrollment.objects.filter(user=user) enrollments = CourseEnrollment.objects.filter(user=user)
def course_from_id(id): # Build our courses list for the user, but ignore any courses that no longer
course_loc = CourseDescriptor.id_to_location(id) # exist (because the course IDs have changed). Still, we don't delete those
return modulestore().get_item(course_loc) # enrollments, because it could have been a data push snafu.
courses = []
for enrollment in enrollments:
try:
courses.append(course_from_id(enrollment.course_id))
except ItemNotFoundError:
log.error("User {0} enrolled in non-existant course {1}"
.format(user.username, enrollment.course_id))
courses = [course_from_id(enrollment.course_id) for enrollment in enrollments] message = ""
if not user.is_active:
message = render_to_string('registration/activate_account_notice.html', {'email': user.email})
context = {'csrf': csrf_token, 'courses': courses} context = {'courses': courses, 'message' : message}
return render_to_response('dashboard.html', context) return render_to_response('dashboard.html', context)
def try_change_enrollment(request):
"""
This method calls change_enrollment if the necessary POST
parameters are present, but does not return anything. It
simply logs the result or exception. This is usually
called after a registration or login, as secondary action.
It should not interrupt a successful registration or login.
"""
if 'enrollment_action' in request.POST:
try:
enrollment_output = change_enrollment(request)
# There isn't really a way to display the results to the user, so we just log it
# We expect the enrollment to be a success, and will show up on the dashboard anyway
log.info("Attempted to automatically enroll after login. Results: {0}".format(enrollment_output))
except Exception, e:
log.exception("Exception automatically enrolling after login: {0}".format(str(e)))
@login_required
def change_enrollment_view(request):
return HttpResponse(json.dumps(change_enrollment(request)))
def change_enrollment(request):
if request.method != "POST":
raise Http404
action = request.POST.get("enrollment_action" , "")
user = request.user
course_id = request.POST.get("course_id", None)
if course_id == None:
return HttpResponse(json.dumps({'success': False, 'error': 'There was an error receiving the course id.'}))
if action == "enroll":
# Make sure the course exists
# We don't do this check on unenroll, or a bad course id can't be unenrolled from
try:
course = course_from_id(course_id)
except ItemNotFoundError:
log.error("User {0} tried to enroll in non-existant course {1}"
.format(user.username, enrollment.course_id))
return {'success': False, 'error': 'The course requested does not exist.'}
enrollment, created = CourseEnrollment.objects.get_or_create(user=user, course_id=course.id)
return {'success': True}
elif action == "unenroll":
try:
enrollment = CourseEnrollment.objects.get(user=user, course_id=course_id)
enrollment.delete()
return {'success': True}
except CourseEnrollment.DoesNotExist:
return {'success': False, 'error': 'You are not enrolled for this course.'}
else:
return {'success': False, 'error': 'Invalid enrollment_action.'}
return {'success': False, 'error': 'We weren\'t able to unenroll you. Please try again.'}
# Need different levels of logging # Need different levels of logging
@ensure_csrf_cookie @ensure_csrf_cookie
def login_user(request, error=""): def login_user(request, error=""):
''' AJAX request to log in the user. ''' ''' AJAX request to log in the user. '''
if 'email' not in request.POST or 'password' not in request.POST: if 'email' not in request.POST or 'password' not in request.POST:
return HttpResponse(json.dumps({'success': False, return HttpResponse(json.dumps({'success': False,
'error': 'Invalid login'})) # TODO: User error message 'value': 'There was an error receiving your login information. Please email us.'})) # TODO: User error message
email = request.POST['email'] email = request.POST['email']
password = request.POST['password'] password = request.POST['password']
...@@ -84,14 +182,14 @@ def login_user(request, error=""): ...@@ -84,14 +182,14 @@ def login_user(request, error=""):
except User.DoesNotExist: except User.DoesNotExist:
log.warning("Login failed - Unknown user email: {0}".format(email)) log.warning("Login failed - Unknown user email: {0}".format(email))
return HttpResponse(json.dumps({'success': False, return HttpResponse(json.dumps({'success': False,
'error': 'Invalid login'})) # TODO: User error message 'value': 'Email or password is incorrect.'})) # TODO: User error message
username = user.username username = user.username
user = authenticate(username=username, password=password) user = authenticate(username=username, password=password)
if user is None: if user is None:
log.warning("Login failed - password for {0} is invalid".format(email)) log.warning("Login failed - password for {0} is invalid".format(email))
return HttpResponse(json.dumps({'success': False, return HttpResponse(json.dumps({'success': False,
'error': 'Invalid login'})) 'value': 'Email or password is incorrect.'}))
if user is not None and user.is_active: if user is not None and user.is_active:
try: try:
...@@ -106,11 +204,14 @@ def login_user(request, error=""): ...@@ -106,11 +204,14 @@ def login_user(request, error=""):
log.exception(e) log.exception(e)
log.info("Login success - {0} ({1})".format(username, email)) log.info("Login success - {0} ({1})".format(username, email))
try_change_enrollment(request)
return HttpResponse(json.dumps({'success':True})) return HttpResponse(json.dumps({'success':True}))
log.warning("Login failed - Account not active for user {0}".format(username)) log.warning("Login failed - Account not active for user {0}".format(username))
return HttpResponse(json.dumps({'success':False, return HttpResponse(json.dumps({'success':False,
'error': 'Account not active. Check your e-mail.'})) 'value': 'This account has not been activated. Please check your e-mail for the activation instructions.'}))
@ensure_csrf_cookie @ensure_csrf_cookie
def logout_user(request): def logout_user(request):
...@@ -121,17 +222,14 @@ def logout_user(request): ...@@ -121,17 +222,14 @@ def logout_user(request):
@login_required @login_required
@ensure_csrf_cookie @ensure_csrf_cookie
def change_setting(request): def change_setting(request):
''' JSON call to change a profile setting: Right now, location and language ''' JSON call to change a profile setting: Right now, location
''' '''
up = UserProfile.objects.get(user=request.user) #request.user.profile_cache up = UserProfile.objects.get(user=request.user) #request.user.profile_cache
if 'location' in request.POST: if 'location' in request.POST:
up.location=request.POST['location'] up.location=request.POST['location']
if 'language' in request.POST:
up.language=request.POST['language']
up.save() up.save()
return HttpResponse(json.dumps({'success':True, return HttpResponse(json.dumps({'success':True,
'language':up.language,
'location':up.location,})) 'location':up.location,}))
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -142,7 +240,7 @@ def create_account(request, post_override=None): ...@@ -142,7 +240,7 @@ def create_account(request, post_override=None):
post_vars = post_override if post_override else request.POST post_vars = post_override if post_override else request.POST
# Confirm we have a properly formed request # Confirm we have a properly formed request
for a in ['username', 'email', 'password', 'location', 'language', 'name']: for a in ['username', 'email', 'password', 'name']:
if a not in post_vars: if a not in post_vars:
js['value'] = "Error (401 {field}). E-mail us.".format(field=a) js['value'] = "Error (401 {field}). E-mail us.".format(field=a)
return HttpResponse(json.dumps(js)) return HttpResponse(json.dumps(js))
...@@ -209,14 +307,23 @@ def create_account(request, post_override=None): ...@@ -209,14 +307,23 @@ def create_account(request, post_override=None):
up = UserProfile(user=u) up = UserProfile(user=u)
up.name = post_vars['name'] up.name = post_vars['name']
up.language = post_vars['language'] up.level_of_education = post_vars['level_of_education']
up.location = post_vars['location'] up.gender = post_vars['gender']
up.mailing_address = post_vars['mailing_address']
up.goals = post_vars['goals']
try:
up.year_of_birth = int(post_vars['year_of_birth'])
except ValueError:
up.year_of_birth = None # If they give us garbage, just ignore it instead
# of asking them to put an integer.
try:
up.save() up.save()
except Exception:
log.exception("UserProfile creation failed for user {0}.".format(u.id))
# TODO (vshnayder): the LMS should probably allow signups without a particular course too
d = {'name': post_vars['name'], d = {'name': post_vars['name'],
'key': r.activation_key, 'key': r.activation_key,
'course_title': getattr(settings, 'COURSE_TITLE', ''),
} }
subject = render_to_string('emails/activation_email_subject.txt', d) subject = render_to_string('emails/activation_email_subject.txt', d)
...@@ -236,9 +343,16 @@ def create_account(request, post_override=None): ...@@ -236,9 +343,16 @@ def create_account(request, post_override=None):
js['value'] = 'Could not send activation e-mail.' js['value'] = 'Could not send activation e-mail.'
return HttpResponse(json.dumps(js)) return HttpResponse(json.dumps(js))
js={'success': True, # Immediately after a user creates an account, we log them in. They are only
'value': render_to_string('registration/reg_complete.html', {'email': post_vars['email'], # logged in until they close the browser. They can't log in again until they click
'csrf': csrf(request)['csrf_token']})} # the activation link from the email.
login_user = authenticate(username=post_vars['username'], password = post_vars['password'] )
login(request, login_user)
request.session.set_expiry(0)
try_change_enrollment(request)
js={'success': True}
return HttpResponse(json.dumps(js), mimetype="application/json") return HttpResponse(json.dumps(js), mimetype="application/json")
def create_random_account(create_account_function): def create_random_account(create_account_function):
...@@ -251,7 +365,6 @@ def create_random_account(create_account_function): ...@@ -251,7 +365,6 @@ def create_random_account(create_account_function):
'email' : id_generator(size=10, chars=string.ascii_lowercase) + "_dummy_test@mitx.mit.edu", 'email' : id_generator(size=10, chars=string.ascii_lowercase) + "_dummy_test@mitx.mit.edu",
'password' : id_generator(), 'password' : id_generator(),
'location' : id_generator(size=5, chars=string.ascii_uppercase), 'location' : id_generator(size=5, chars=string.ascii_uppercase),
'language' : id_generator(size=5, chars=string.ascii_uppercase) + "ish",
'name' : id_generator(size=5, chars=string.ascii_lowercase) + " " + id_generator(size=7, chars=string.ascii_lowercase), 'name' : id_generator(size=5, chars=string.ascii_lowercase) + " " + id_generator(size=7, chars=string.ascii_lowercase),
'honor_code' : u'true', 'honor_code' : u'true',
'terms_of_service' : u'true',} 'terms_of_service' : u'true',}
...@@ -269,14 +382,15 @@ def activate_account(request, key): ...@@ -269,14 +382,15 @@ def activate_account(request, key):
''' '''
r=Registration.objects.filter(activation_key=key) r=Registration.objects.filter(activation_key=key)
if len(r)==1: if len(r)==1:
user_logged_in = request.user.is_authenticated()
already_active = True
if not r[0].user.is_active: if not r[0].user.is_active:
r[0].activate() r[0].activate()
resp = render_to_response("activation_complete.html",{'csrf':csrf(request)['csrf_token']}) already_active = False
return resp resp = render_to_response("registration/activation_complete.html",{'user_logged_in':user_logged_in, 'already_active' : already_active})
resp = render_to_response("activation_active.html",{'csrf':csrf(request)['csrf_token']})
return resp return resp
if len(r)==0: if len(r)==0:
return render_to_response("activation_invalid.html",{'csrf':csrf(request)['csrf_token']}) return render_to_response("registration/activation_invalid.html",{'csrf':csrf(request)['csrf_token']})
return HttpResponse("Unknown error. Please e-mail us to let us know how it happened.") return HttpResponse("Unknown error. Please e-mail us to let us know how it happened.")
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -492,26 +606,3 @@ def accept_name_change(request): ...@@ -492,26 +606,3 @@ def accept_name_change(request):
pnc.delete() pnc.delete()
return HttpResponse(json.dumps({'success': True})) return HttpResponse(json.dumps({'success': True}))
@ensure_csrf_cookie
@cache_if_anonymous
def course_info(request, course_id):
course = check_course(course_id, course_must_be_open=False)
# This is the advertising page for a student to look at the course before signing up
csrf_token = csrf(request)['csrf_token']
# TODO: Couse should be a model
return render_to_response('portal/course_about.html', {'course': course})
@login_required
@ensure_csrf_cookie
def enroll(request, course_id):
course = check_course(course_id, course_must_be_open=False)
user = request.user
if not CourseEnrollment.objects.filter(user=user, course_id=course.id).exists():
enrollment = CourseEnrollment(user=user,
course_id=course.id)
enrollment.save()
return redirect(reverse('dashboard'))
...@@ -12,8 +12,32 @@ class TrackMiddleware: ...@@ -12,8 +12,32 @@ class TrackMiddleware:
if request.META['PATH_INFO'] in ['/event', '/login']: if request.META['PATH_INFO'] in ['/event', '/login']:
return return
event = { 'GET' : dict(request.GET), # Removes passwords from the tracking logs
'POST' : dict(request.POST)} # WARNING: This list needs to be changed whenever we change
# password handling functionality.
#
# As of the time of this comment, only 'password' is used
# The rest are there for future extension.
#
# Passwords should never be sent as GET requests, but
# this can happen due to older browser bugs. We censor
# this too.
#
# We should manually confirm no passwords make it into log
# files when we change this.
censored_strings = ['password', 'newpassword', 'new_password',
'oldpassword', 'old_password']
post_dict = dict(request.POST)
get_dict = dict(request.GET)
for string in censored_strings:
if string in post_dict:
post_dict[string] = '*'*8
if string in get_dict:
get_dict[string] = '*'*8
event = { 'GET' : dict(get_dict),
'POST' : dict(post_dict)}
# TODO: Confirm no large file uploads # TODO: Confirm no large file uploads
event = json.dumps(event) event = json.dumps(event)
......
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
...@@ -40,6 +38,10 @@ class CourseDescriptor(SequenceDescriptor): ...@@ -40,6 +38,10 @@ class CourseDescriptor(SequenceDescriptor):
return "/".join([self.location.org, self.location.course, self.location.name]) return "/".join([self.location.org, self.location.course, self.location.name])
@property @property
def start_date_text(self):
return time.strftime("%b %d, %Y", self.start)
@property
def title(self): def title(self):
return self.metadata['display_name'] return self.metadata['display_name']
...@@ -48,74 +50,9 @@ class CourseDescriptor(SequenceDescriptor): ...@@ -48,74 +50,9 @@ 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
def get_about_section(self, section_key): @property
""" def org(self):
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']:
try:
with self.system.resources_fs.open(path("about") / section_key + ".html") as htmlFile:
return htmlFile.read().decode('utf-8')
except ResourceNotFoundError:
log.exception("Missing about section {key} in course {url}".format(key=section_key, url=self.location.url()))
return "! About section missing !"
elif section_key == "title":
return self.metadata.get('display_name', self.name)
elif section_key == "university":
return self.location.org return self.location.org
\ No newline at end of file
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
from xmodule.modulestore.exceptions import ItemNotFoundError
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):
""" """
...@@ -24,10 +30,88 @@ def check_course(course_id, course_must_be_open=True, course_required=True): ...@@ -24,10 +30,88 @@ def check_course(course_id, course_must_be_open=True, course_required=True):
try: try:
course_loc = CourseDescriptor.id_to_location(course_id) course_loc = CourseDescriptor.id_to_location(course_id)
course = modulestore().get_item(course_loc) course = modulestore().get_item(course_loc)
except KeyError: except (KeyError, ItemNotFoundError):
raise Http404("Course not found.") raise Http404("Course not found.")
if course_must_be_open and not course.has_started(): if course_must_be_open and not course.has_started():
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
from collections import defaultdict
import json
import logging import logging
import urllib import urllib
import itertools
from django.conf import settings from django.conf import settings
from django.core.context_processors import csrf from django.core.context_processors import csrf
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import Http404 from django.http import Http404, HttpResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string from mitxmako.shortcuts import render_to_response, render_to_string
#from django.views.decorators.csrf import ensure_csrf_cookie #from django.views.decorators.csrf import ensure_csrf_cookie
...@@ -18,7 +22,7 @@ from student.models import UserProfile ...@@ -18,7 +22,7 @@ from student.models import UserProfile
from multicourse import multicourse_settings from multicourse import multicourse_settings
from util.cache import cache, cache_if_anonymous from util.cache import cache, cache_if_anonymous
from student.models import UserTestGroup from student.models import UserTestGroup, CourseEnrollment
from courseware import grades from courseware import grades
from courseware.courses import check_course from courseware.courses import check_course
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
...@@ -53,8 +57,12 @@ def format_url_params(params): ...@@ -53,8 +57,12 @@ def format_url_params(params):
@cache_if_anonymous @cache_if_anonymous
def courses(request): def courses(request):
# TODO: Clean up how 'error' is done. # TODO: Clean up how 'error' is done.
context = {'courses': modulestore().get_courses()} courses = sorted(modulestore().get_courses(), key=lambda course: course.number)
return render_to_response("courses.html", context) universities = defaultdict(list)
for course in courses:
universities[course.org].append(course)
return render_to_response("courses.html", { 'universities': universities })
@cache_control(no_cache=True, no_store=True, must_revalidate=True) @cache_control(no_cache=True, no_store=True, must_revalidate=True)
def gradebook(request, course_id): def gradebook(request, course_id):
...@@ -249,3 +257,32 @@ def course_info(request, course_id): ...@@ -249,3 +257,32 @@ def course_info(request, course_id):
course = check_course(course_id) course = check_course(course_id)
return render_to_response('info.html', {'course': course}) return render_to_response('info.html', {'course': course})
@ensure_csrf_cookie
@cache_if_anonymous
def course_about(request, course_id):
def registered_for_course(course, user):
if user.is_authenticated():
return CourseEnrollment.objects.filter(user = user, course_id=course.id).exists()
else:
return False
course = check_course(course_id, course_must_be_open=False)
registered = registered_for_course(course, request.user)
return render_to_response('portal/course_about.html', {'course': course, 'registered': registered})
@ensure_csrf_cookie
@cache_if_anonymous
def university_profile(request, org_id):
all_courses = sorted(modulestore().get_courses(), key=lambda course: course.number)
valid_org_ids = set(c.org for c in all_courses)
if org_id not in valid_org_ids:
raise Http404("University Profile not found for {0}".format(org_id))
# Only grab courses for this org...
courses=[c for c in all_courses if c.org == org_id]
context = dict(courses=courses, org_id=org_id)
template_file = "university_profile/{0}.html".format(org_id).lower()
return render_to_response(template_file, context)
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Removing index on 'Namespace', fields ['name']
db.delete_index('simplewiki_namespace', ['name'])
def backwards(self, orm):
# Adding index on 'Namespace', fields ['name']
db.create_index('simplewiki_namespace', ['name'])
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'simplewiki.article': {
'Meta': {'unique_together': "(('slug', 'namespace'),)", 'object_name': 'Article'},
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': '1', 'blank': 'True'}),
'current_revision': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'current_rev'", 'unique': 'True', 'null': 'True', 'to': "orm['simplewiki.Revision']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'modified_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': '1', 'blank': 'True'}),
'namespace': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['simplewiki.Namespace']"}),
'permissions': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['simplewiki.Permission']", 'null': 'True', 'blank': 'True'}),
'related': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'related_rel_+'", 'null': 'True', 'to': "orm['simplewiki.Article']"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '512'})
},
'simplewiki.articleattachment': {
'Meta': {'object_name': 'ArticleAttachment'},
'article': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['simplewiki.Article']"}),
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
'simplewiki.namespace': {
'Meta': {'object_name': 'Namespace'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'simplewiki.permission': {
'Meta': {'object_name': 'Permission'},
'can_read': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'read'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'can_write': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'write'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'permission_name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'simplewiki.revision': {
'Meta': {'object_name': 'Revision'},
'article': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['simplewiki.Article']"}),
'contents': ('django.db.models.fields.TextField', [], {}),
'contents_parsed': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'counter': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
'deleted': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'previous_revision': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['simplewiki.Revision']", 'null': 'True', 'blank': 'True'}),
'revision_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'revision_text': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'revision_user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'wiki_revision_user'", 'null': 'True', 'to': "orm['auth.User']"})
}
}
complete_apps = ['simplewiki']
\ No newline at end of file
...@@ -17,7 +17,7 @@ class ShouldHaveExactlyOneRootSlug(Exception): ...@@ -17,7 +17,7 @@ class ShouldHaveExactlyOneRootSlug(Exception):
pass pass
class Namespace(models.Model): class Namespace(models.Model):
name = models.CharField(max_length=30, db_index=True, unique=True, verbose_name=_('namespace')) name = models.CharField(max_length=30, unique=True, verbose_name=_('namespace'))
# TODO: We may want to add permissions, etc later # TODO: We may want to add permissions, etc later
@classmethod @classmethod
......
...@@ -16,10 +16,6 @@ if settings.STATIC_GRAB: ...@@ -16,10 +16,6 @@ if settings.STATIC_GRAB:
valid_templates = valid_templates+['server-down.html', valid_templates = valid_templates+['server-down.html',
'server-error.html' 'server-error.html'
'server-overloaded.html', 'server-overloaded.html',
'mitx_global.html',
'mitx-overview.html',
'6002x-faq.html',
'6002x-press-release.html'
] ]
def index(request, template): def index(request, template):
...@@ -41,14 +37,10 @@ def render(request, template): ...@@ -41,14 +37,10 @@ def render(request, template):
""" """
return render_to_response('static_templates/' + template, {}) return render_to_response('static_templates/' + template, {})
def render_404(request):
return render_to_response('static_templates/404.html', {})
valid_auth_templates=[] def render_500(request):
return render_to_response('static_templates/server-error.html', {})
def auth_index(request, template):
if not request.user.is_authenticated():
return redirect('/')
if template in valid_auth_templates:
return render_to_response(template,{})
else:
return redirect('/')
...@@ -104,6 +104,8 @@ LIB_URL = '/static/js/' ...@@ -104,6 +104,8 @@ LIB_URL = '/static/js/'
# Dev machines shouldn't need the book # Dev machines shouldn't need the book
# BOOK_URL = '/static/book/' # BOOK_URL = '/static/book/'
BOOK_URL = 'https://mitxstatic.s3.amazonaws.com/book_images/' # For AWS deploys BOOK_URL = 'https://mitxstatic.s3.amazonaws.com/book_images/' # For AWS deploys
# RSS_URL = r'lms/templates/feed.rss'
RSS_TIMEOUT = 600
# Configuration option for when we want to grab server error pages # Configuration option for when we want to grab server error pages
STATIC_GRAB = False STATIC_GRAB = False
...@@ -260,7 +262,6 @@ TEMPLATE_LOADERS = ( ...@@ -260,7 +262,6 @@ TEMPLATE_LOADERS = (
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
'util.middleware.ExceptionLoggingMiddleware', 'util.middleware.ExceptionLoggingMiddleware',
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
...@@ -292,15 +293,59 @@ PIPELINE_CSS = { ...@@ -292,15 +293,59 @@ PIPELINE_CSS = {
'source_filenames': ['sass/application.scss'], 'source_filenames': ['sass/application.scss'],
'output_filename': 'css/application.css', 'output_filename': 'css/application.css',
}, },
'course': {
'source_filenames': ['sass/application.scss', 'css/vendor/codemirror.css', 'css/vendor/jquery.treeview.css'],
'output_filename': 'css/course.css',
},
'ie-fixes': {
'source_filenames': ['sass/ie.scss'],
'output_filename': 'css/ie.css',
},
} }
PIPELINE_ALWAYS_RECOMPILE = ['sass/application.scss'] PIPELINE_ALWAYS_RECOMPILE = ['sass/application.scss', 'sass/ie.scss']
courseware_only_js = [
PROJECT_ROOT / 'static/coffee/src/' + pth + '.coffee'
for pth
in ['courseware', 'histogram', 'navigation', 'time', ]
]
courseware_only_js += [
pth for pth
in glob2.glob(PROJECT_ROOT / 'static/coffee/src/modules/**/*.coffee')
]
main_vendor_js = [
'js/vendor/jquery.min.js',
'js/vendor/jquery-ui.min.js',
'js/vendor/swfobject/swfobject.js',
'js/vendor/jquery.cookie.js',
'js/vendor/jquery.qtip.min.js',
]
PIPELINE_JS = { PIPELINE_JS = {
'application': { 'application': {
'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in glob2.glob(PROJECT_ROOT / 'static/coffee/src/**/*.coffee')], # Application will contain all paths not in courseware_only_js
'source_filenames': [
pth.replace(PROJECT_ROOT / 'static/', '')
for pth in glob2.glob(PROJECT_ROOT / 'static/coffee/src/**/*.coffee')\
if pth not in courseware_only_js
] + [
'js/form.ext.js',
'js/my_courses_dropdown.js',
'js/toggle_login_modal.js',
'js/sticky_filter.js',
],
'output_filename': 'js/application.js' 'output_filename': 'js/application.js'
}, },
'courseware': {
'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in courseware_only_js],
'output_filename': 'js/courseware.js'
},
'main_vendor': {
'source_filenames': main_vendor_js,
'output_filename': 'js/main_vendor.js',
},
'spec': { 'spec': {
'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in glob2.glob(PROJECT_ROOT / 'static/coffee/spec/**/*.coffee')], 'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in glob2.glob(PROJECT_ROOT / 'static/coffee/spec/**/*.coffee')],
'output_filename': 'js/spec.js' 'output_filename': 'js/spec.js'
......
...@@ -5,3 +5,4 @@ ...@@ -5,3 +5,4 @@
*.orig *.orig
*.DS_Store *.DS_Store
application.css application.css
ie.css
\ No newline at end of file
(function($, undefined) {
var form_ext;
$.form_ext = form_ext = {
ajax: function(options) {
return $.ajax(options);
},
handleRemote: function(element) {
var method = element.attr('method');
var url = element.attr('action');
var data = element.serializeArray();
var options = {
type: method || 'GET',
data: data,
dataType: 'text json',
success: function(data, status, xhr) {
element.trigger("ajax:success", [data, status, xhr]);
},
complete: function(xhr, status) {
element.trigger("ajax:complete", [xhr, status]);
},
error: function(xhr, status, error) {
element.trigger("ajax:error", [xhr, status, error]);
}
}
if(url) { options.url = url; }
return form_ext.ajax(options)
},
CSRFProtection: function(xhr) {
var token = $.cookie('csrftoken');
if (token) xhr.setRequestHeader('X-CSRFToken', token);
},
}
$.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { form_ext.CSRFProtection(xhr); }});
$(document).delegate('form', 'submit', function(e) {
var form = $(this),
remote = form.data("remote") !== undefined;
if(remote) {
form_ext.handleRemote(form);
return false;
}
});
})(jQuery);
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
position: 'fixed' position: 'fixed'
} }
if ($("#lean_overlay").length == 0) {
var overlay = $("<div id='lean_overlay'></div>"); var overlay = $("<div id='lean_overlay'></div>");
$("body").append(overlay); $("body").append(overlay);
}
options = $.extend(defaults, options); options = $.extend(defaults, options);
...@@ -48,6 +50,16 @@ ...@@ -48,6 +50,16 @@
}) })
$(modal_id).fadeTo(200,1); $(modal_id).fadeTo(200,1);
$(modal_id).find(".notice").hide().html("");
var notice = $(this).data('notice')
if(notice !== undefined) {
$notice = $(modal_id).find(".notice");
$notice.show().html(notice);
// This is for activating leanModal links that were in the notice. We should have a cleaner way of
// allowing all dynamically added leanmodal links to work.
$notice.find("a[rel*=leanModal]").leanModal({ top : 120, overlay: 1, closeButton: ".close-modal", position: 'absolute' });
}
window.scrollTo(0, 0);
e.preventDefault(); e.preventDefault();
}); });
...@@ -65,8 +77,13 @@ ...@@ -65,8 +77,13 @@
$(this).leanModal({ top : 120, overlay: 1, closeButton: ".close-modal", position: 'absolute' }); $(this).leanModal({ top : 120, overlay: 1, closeButton: ".close-modal", position: 'absolute' });
embed = $($(this).attr('href')).find('iframe') embed = $($(this).attr('href')).find('iframe')
if(embed.length > 0) { if(embed.length > 0) {
embed.data('src', embed.attr('src') + '?autoplay=1'); if(embed.attr('src').indexOf("?") > 0) {
embed.data('src', embed.attr('src') + '&autoplay=1&rel=0');
embed.attr('src', ''); embed.attr('src', '');
} else {
embed.data('src', embed.attr('src') + '?autoplay=1&rel=0');
embed.attr('src', '');
}
} }
}); });
})(jQuery); })(jQuery);
...@@ -8,13 +8,6 @@ ...@@ -8,13 +8,6 @@
@import 'base/extends'; @import 'base/extends';
@import 'base/animations'; @import 'base/animations';
// Courseware styles
@import 'sass_old/base/variables';
@import 'sass_old/base/extends';
@import 'sass_old/base/functions';
// Multicourse styles // Multicourse styles
@import 'shared/forms'; @import 'shared/forms';
@import 'shared/footer'; @import 'shared/footer';
...@@ -24,20 +17,12 @@ ...@@ -24,20 +17,12 @@
@import 'shared/modal'; @import 'shared/modal';
@import 'shared/activation_messages'; @import 'shared/activation_messages';
@import 'home'; @import 'multicourse/home';
@import 'dashboard'; @import 'multicourse/dashboard';
@import 'courseware_subnav'; @import 'multicourse/courses';
@import 'courses'; @import 'multicourse/course_about';
@import 'course_about'; @import 'multicourse/jobs';
@import 'jobs'; @import 'multicourse/about_pages';
@import 'about_pages'; @import 'multicourse/press_release';
@import 'press_release'; @import 'multicourse/password_reset';
@import 'multicourse/error-pages';
// Courseware styles
@import 'sass_old/courseware/courseware';
@import 'sass_old/courseware/sequence-nav';
@import 'sass_old/courseware/sidebar';
@import 'sass_old/courseware/video';
@import 'sass_old/courseware/amplifier';
@import 'sass_old/courseware/problems';
...@@ -3,7 +3,7 @@ html, body { ...@@ -3,7 +3,7 @@ html, body {
font-family: $sans-serif; font-family: $sans-serif;
font-size: 1em; font-size: 1em;
line-height: 1em; line-height: 1em;
-webkit-font-smoothing: antialiased; //-webkit-font-smoothing: antialiased;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
...@@ -83,7 +83,12 @@ a:link, a:visited { ...@@ -83,7 +83,12 @@ a:link, a:visited {
@include clearfix; @include clearfix;
margin: 0 auto 0; margin: 0 auto 0;
padding: 0px 10px; padding: 0px 10px;
width: grid-width(12); max-width: grid-width(12);
}
span.edx {
text-transform: none;
font: inherit;
} }
.static-container { .static-container {
......
/* Generated by Font Squirrel (http://www.fontsquirrel.com) on January 25, 2012 05:06:34 PM America/New_York */ /* Generated by Font Squirrel (http://www.fontsquirrel.com) on January 25, 2012 05:06:34 PM America/New_York */
@font-face { @font-face {
font-family: 'Open Sans'; font-family: 'Open Sans';
src: url('../fonts/OpenSans-Light-webfont.eot'); src: url('../fonts/OpenSans-Light-webfont.eot');
...@@ -32,7 +31,7 @@ ...@@ -32,7 +31,7 @@
url('../fonts/OpenSans-Regular-webfont.woff') format('woff'), url('../fonts/OpenSans-Regular-webfont.woff') format('woff'),
url('../fonts/OpenSans-Regular-webfont.ttf') format('truetype'), url('../fonts/OpenSans-Regular-webfont.ttf') format('truetype'),
url('../fonts/OpenSans-Regular-webfont.svg#OpenSansRegular') format('svg'); url('../fonts/OpenSans-Regular-webfont.svg#OpenSansRegular') format('svg');
font-weight: 600; font-weight: 400;
font-style: normal; font-style: normal;
} }
...@@ -49,31 +48,6 @@ ...@@ -49,31 +48,6 @@
} }
// Not used in UI
// @font-face {
// font-family: 'Open Sans';
// src: url('../fonts/OpenSans-Semibold-webfont.eot');
// src: url('../fonts/OpenSans-Semibold-webfont.eot?#iefix') format('embedded-opentype'),
// url('../fonts/OpenSans-Semibold-webfont.woff') format('woff'),
// url('../fonts/OpenSans-Semibold-webfont.ttf') format('truetype'),
// url('../fonts/OpenSans-Semibold-webfont.svg#OpenSansSemibold') format('svg');
// font-weight: 600;
// font-style: normal;
// }
// @font-face {
// font-family: 'Open Sans';
// src: url('../fonts/OpenSans-SemiboldItalic-webfont.eot');
// src: url('../fonts/OpenSans-SemiboldItalic-webfont.eot?#iefix') format('embedded-opentype'),
// url('../fonts/OpenSans-SemiboldItalic-webfont.woff') format('woff'),
// url('../fonts/OpenSans-SemiboldItalic-webfont.ttf') format('truetype'),
// url('../fonts/OpenSans-SemiboldItalic-webfont.svg#OpenSansSemiboldItalic') format('svg');
// font-weight: 600;
// font-style: italic;
// }
@font-face { @font-face {
font-family: 'Open Sans'; font-family: 'Open Sans';
src: url('../fonts/OpenSans-Bold-webfont.eot'); src: url('../fonts/OpenSans-Bold-webfont.eot');
......
@import 'bourbon/bourbon';
@import 'base/reset';
@import 'base/font_face';
@import 'base/variables';
@import 'base/base';
@import 'base/mixins';
@import 'base/extends';
@import 'base/animations';
// Course styles
@import 'course/courseware_subnav';
// Courseware styles
@import 'course/old/base/variables';
@import 'course/old/base/extends';
@import 'course/old/base/functions';
@import 'course/old/courseware/courseware';
@import 'course/old/courseware/sequence-nav';
@import 'course/old/courseware/sidebar';
@import 'course/old/courseware/video';
@import 'course/old/courseware/amplifier';
@import 'course/old/courseware/problems';
...@@ -80,15 +80,15 @@ footer { ...@@ -80,15 +80,15 @@ footer {
} }
&.twitter a { &.twitter a {
background: url('../images/twitter.png') 0 0 no-repeat; background: url('../images/social/twitter.png') 0 0 no-repeat;
} }
&.facebook a { &.facebook a {
background: url('../images/facebook.png') 0 0 no-repeat; background: url('../images/social/facebook.png') 0 0 no-repeat;
} }
&.linkedin a { &.linkedin a {
background: url('../images/linkedin.png') 0 0 no-repeat; background: url('../images/social/linkedin.png') 0 0 no-repeat;
} }
} }
} }
......
...@@ -84,7 +84,7 @@ div.leanModal_box { ...@@ -84,7 +84,7 @@ div.leanModal_box {
form { form {
text-align: left; text-align: left;
div#enroll_error, div#login_error, div#pwd_error { div#register_error, div#login_error, div#pwd_error {
$error-color: #333; $error-color: #333;
background-color: $error-color; background-color: $error-color;
border: darken($error-color, 20%); border: darken($error-color, 20%);
......
@import "bourbon/bourbon";
@import "base/variables";
// These are all quick solutions for IE please rewrite
.highlighted-courses .courses .course header.course-preview, .find-courses .courses .course header.course-preview,
.home .highlighted-courses > h2, .home .highlighted-courses > section.outside-app h1, section.outside-app .home .highlighted-courses > h1,
header.global {
background: #FFF;
}
.home > header .title .actions,
.home > header .title:hover .actions {
display: none;
height: auto;
}
.home > header .title {
&:hover {
height: 120px;
> hgroup {
h1 {
border-bottom: 0;
padding-bottom: 0;
}
h2 {
opacity: 1;
}
}
.actions {
opacity: 0;
}
}
}
.last {
margin-right: 0 !important;
}
.home .university-partners .partners a {
.name {
position: static;
}
&:hover {
text-decoration: none;
&::before {
opacity: 1;
}
.name {
bottom: 0px;
}
img {
top: 0px;
}
}
}
.home .university-partners .partners {
width: 660px;
li.partner {
float: left;
display: block;
padding: 0;
width: 220px;
overflow: hidden;
}
}
.highlighted-courses .courses .course, .find-courses .courses .course {
.meta-info {
display: none;
}
.inner-wrapper {
height: 100%;
overflow: visible;
position: relative;
}
header.course-preview {
left: 0px;
position: relative;
top: 0px;
width: 100%;
z-index: 3;
height: auto;
hgroup {
position: relative;
right: 0;
top: 0;
}
}
// }
.info {
height: auto;
position: static;
overflow: visible;
.desc {
height: auto;
}
}
&:hover {
background: rgb(245,245,245);
border-color: rgb(170,170,170);
@include box-shadow(0 1px 16px 0 rgba($blue, 0.4));
.info {
top: 0;
}
.meta-info {
opacity: 0;
}
}
}
...@@ -37,33 +37,67 @@ ...@@ -37,33 +37,67 @@
margin-bottom: 80px; margin-bottom: 80px;
} }
.our-mission {
border-bottom: 1px solid rgb(220,220,220);
@include clearfix;
margin: 0 auto 100px;
padding-bottom: 40px;
.logo {
border-right: 1px solid rgb(200,200,200);
@include box-sizing(border-box);
float: left;
height: 115px;
margin-right: flex-gutter();
text-align: center;
width: flex-grid(3);
> img {
@include inline-block;
margin-top: 26px;
max-height: 60px;
}
}
h2.mission-quote { h2.mission-quote {
@include box-sizing(border-box);
float: right;
font-style: italic; font-style: italic;
margin: 0 auto 120px;; line-height: 1.4;
text-align: center; margin: 0px;
padding: 5px 0px 5px 20px;
text-transform: none; text-transform: none;
width: flex-grid(10); width: flex-grid(9);
}
} }
.message { .message {
border-bottom: 1px solid rgb(220,220,220);
@include clearfix; @include clearfix;
margin-bottom: 60px; margin-bottom: 80px;
padding-bottom: 60px; padding-bottom: 80px;
position: relative; position: relative;
hr { hr {
bottom: 0px; bottom: 0px;
display: none;
margin: 0px; margin: 0px;
position: absolute; position: absolute;
width: 100%; width: 100%;
} }
h2 {
border-bottom: 1px solid rgb(200,200,200);
padding-bottom: 15px;
}
.photo { .photo {
@include box-sizing(border-box); @include box-sizing(border-box);
background: rgb(255,255,255); background: rgb(255,255,255);
border: 1px solid rgb(210,210,210); border: 1px solid rgb(210,210,210);
margin-top: 37px;
padding: 1px; padding: 1px;
width: flex-grid(4); width: flex-grid(3);
img { img {
background: rgb(245,245,245); background: rgb(245,245,245);
...@@ -74,8 +108,10 @@ ...@@ -74,8 +108,10 @@
} }
> article { > article {
@include box-sizing(border-box);
float: left; float: left;
width: flex-grid(8); padding-left: 20px;
width: flex-grid(9);
} }
&.left { &.left {
...@@ -184,15 +220,15 @@ ...@@ -184,15 +220,15 @@
border: 1px solid rgb(120,120,120); border: 1px solid rgb(120,120,120);
@include box-sizing(border-box); @include box-sizing(border-box);
float: left; float: left;
height: 120px; height: 140px;
margin-right: flex-gutter(); margin-right: flex-gutter();
overflow: hidden; overflow: hidden;
width: flex-grid(2); width: flex-grid(2);
img { img {
display: block; display: block;
min-height: 100%; //min-height: 100%;
width: 100%; //width: 100%;
} }
} }
...@@ -226,13 +262,11 @@ ...@@ -226,13 +262,11 @@
.map { .map {
background: rgb(245,245,245); background: rgb(245,245,245);
float: left; float: left;
height: 280px;
margin-right: flex-gutter(); margin-right: flex-gutter();
overflow: hidden; overflow: hidden;
width: flex-grid(6); width: flex-grid(6);
img { img {
min-height: 100%;
max-width: 100%; max-width: 100%;
} }
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
header.course-profile { header.course-profile {
background: rgb(245,245,245); background: rgb(245,245,245);
@include background-image(url('/static/images/shot-2-large.jpg')); @include background-image(url('/static/images/homepage-bg.jpg'));
background-size: cover; background-size: cover;
@include box-shadow(0 1px 80px 0 rgba(0,0,0, 0.5)); @include box-shadow(0 1px 80px 0 rgba(0,0,0, 0.5));
border-bottom: 1px solid rgb(100,100,100); border-bottom: 1px solid rgb(100,100,100);
...@@ -25,8 +25,9 @@ ...@@ -25,8 +25,9 @@
@include clearfix; @include clearfix;
margin: 0 auto; margin: 0 auto;
max-width: 1200px; max-width: 1200px;
min-width: 760px;
position: relative; position: relative;
width: grid-width(12); width: 100%;
z-index: 2; z-index: 2;
...@@ -34,7 +35,6 @@ ...@@ -34,7 +35,6 @@
@include box-sizing(border-box); @include box-sizing(border-box);
@include clearfix; @include clearfix;
float: left; float: left;
height: 180px;
padding: 20px 20px; padding: 20px 20px;
position: relative; position: relative;
width: flex-grid(8) + flex-gutter(); width: flex-grid(8) + flex-gutter();
...@@ -43,17 +43,31 @@ ...@@ -43,17 +43,31 @@
> hgroup { > hgroup {
border-bottom: 1px solid rgb(210,210,210); border-bottom: 1px solid rgb(210,210,210);
@include box-shadow(0 1px 0 0 rgba(255,255,255, 0.6)); @include box-shadow(0 1px 0 0 rgba(255,255,255, 0.6));
margin-bottom: 27px; margin-bottom: 20px;
padding-bottom: 20px; padding-bottom: 20px;
width: 100%; width: 100%;
h1 { h1 {
color: $base-font-color; color: $base-font-color;
font-weight: 700; font-weight: normal;
@include inline-block; @include inline-block;
margin: 0 10px 0 0; margin: 0;
letter-spacing: 0px;
text-align: left;
text-shadow: 0 1px rgba(255,255,255, 0.6);
a {
color: $lighter-base-font-color;
font: italic 800 0.6em/1em $sans-serif;
letter-spacing: 0px; letter-spacing: 0px;
margin-left: 15px;
text-shadow: 0 1px rgba(255,255,255, 0.6); text-shadow: 0 1px rgba(255,255,255, 0.6);
text-transform: none;
&:hover {
color: $blue;
}
}
} }
h2 { h2 {
...@@ -79,7 +93,7 @@ ...@@ -79,7 +93,7 @@
float: left; float: left;
margin-right: flex-gutter(); margin-right: flex-gutter();
@include transition(all, 0.15s, linear); @include transition(all, 0.15s, linear);
width: flex-grid(6); width: flex-grid(12);
> a.find-courses, a.register { > a.find-courses, a.register {
@include button(shiny, $blue); @include button(shiny, $blue);
...@@ -91,18 +105,30 @@ ...@@ -91,18 +105,30 @@
padding: 10px 0px; padding: 10px 0px;
text-transform: uppercase; text-transform: uppercase;
text-align: center; text-align: center;
width: flex-grid(12); width: flex-grid(6);
&:hover { &:hover {
color: rgb(255,255,255); color: rgb(255,255,255);
} }
} }
span.register {
background: lighten($blue, 20%);
border: 1px solid $blue;
@include box-sizing(border-box);
color: darken($blue, 20%);
display: block;
letter-spacing: 1px;
padding: 10px 0px 8px;
text-transform: uppercase;
text-align: center;
width: flex-grid(12);
}
} }
} }
.media { .media {
background: transparent; background: transparent;
border-left: 1px solid rgb(100,100,100);
@include box-sizing(border-box); @include box-sizing(border-box);
display: block; display: block;
float: right; float: right;
...@@ -152,7 +178,7 @@ ...@@ -152,7 +178,7 @@
} }
&:hover { &:hover {
cursor: pointer; text-decoration: none;
.play-intro { .play-intro {
@include background-image(linear-gradient(-90deg, rgba(0,0,0, 0.75), rgba(0,0,0, 0.8))); @include background-image(linear-gradient(-90deg, rgba(0,0,0, 0.75), rgba(0,0,0, 0.8)));
...@@ -232,9 +258,18 @@ ...@@ -232,9 +258,18 @@
.teacher-image { .teacher-image {
background: rgb(255,255,255); background: rgb(255,255,255);
border: 1px solid rgb(200,200,200); border: 1px solid rgb(200,200,200);
height: 115px;
float: left; float: left;
margin: 0 15px 15px 0; margin: 0 15px 0px 0;
overflow: hidden;
padding: 1px; padding: 1px;
width: 115px;
img {
display: block;
min-height: 100%;
max-width: 100%;
}
} }
} }
} }
...@@ -362,6 +397,21 @@ ...@@ -362,6 +397,21 @@
margin-bottom: 20px; margin-bottom: 20px;
padding-bottom: 10px; padding-bottom: 10px;
&.prerequisites {
border: 1px solid rgb(220,220,220);
margin: 0 -10px 0;
padding: 10px;
p {
margin-right: 10px;
}
span {
float: none;
font-weight: normal;
}
}
&:hover { &:hover {
.icon { .icon {
opacity: 1; opacity: 1;
...@@ -383,20 +433,28 @@ ...@@ -383,20 +433,28 @@
@include transition(all, 0.15s, linear); @include transition(all, 0.15s, linear);
width: 19px; width: 19px;
&.start-icon { &.start {
@include background-image(url('/static/images/portal-icons/calendar-icon.png')); @include background-image(url('../images/portal-icons/calendar-icon.png'));
}
&.end {
@include background-image(url('../images/portal-icons/calendar-icon.png'));
}
&.length {
@include background-image(url('../images/portal-icons/chart-icon.png'));
} }
&.final-icon { &.course-number {
@include background-image(url('/static/images/portal-icons/pencil-icon.png')); @include background-image(url('../images/portal-icons/course-info-icon.png'));
} }
&.length-icon { &.effort {
@include background-image(url('/static/images/portal-icons/chart-icon.png')); @include background-image(url('../images/portal-icons/pencil-icon.png'));
} }
&.number-icon { &.prereq {
@include background-image(url('/static/images/portal-icons/course-info-icon.png')); @include background-image(url('../images/portal-icons/prerec-icon.png'));
} }
} }
......
...@@ -15,19 +15,20 @@ ...@@ -15,19 +15,20 @@
height: 120px; height: 120px;
margin: 0 auto; margin: 0 auto;
max-width: 1200px; max-width: 1200px;
min-width: 760px;
padding-top: 200px; padding-top: 200px;
position: relative; position: relative;
text-align: center; text-align: center;
width: flex-grid(12); width: flex-grid(12);
> hgroup { > hgroup {
background: #FFF;
background: rgba(255,255,255, 0.93); background: rgba(255,255,255, 0.93);
border: 1px solid rgb(100,100,100); border: 1px solid rgb(100,100,100);
@include box-shadow(0 4px 25px 0 rgba(0,0,0, 0.5)); @include box-shadow(0 4px 25px 0 rgba(0,0,0, 0.5));
padding: 20px 30px; padding: 20px 30px;
position: relative; position: relative;
z-index: 2; z-index: 2;
} }
&.main-search, &.university-search { &.main-search, &.university-search {
...@@ -79,4 +80,12 @@ ...@@ -79,4 +80,12 @@
} }
} }
} }
section.message {
border-top: 1px solid rgb(220,220,220);
@include clearfix;
margin-top: 20px;
padding-top: 60px;
@include columns(2 20px);
}
} }
...@@ -9,10 +9,13 @@ ...@@ -9,10 +9,13 @@
width: flex-grid(3); width: flex-grid(3);
header.profile { header.profile {
h1.user-name { @include background-image(linear-gradient(-90deg, rgb(255,255,255), rgb(245,245,245)));
border: 1px solid rgb(200,200,200); border: 1px solid rgb(200,200,200);
@include border-radius(4px); @include border-radius(4px);
@include box-sizing(border-box); @include box-sizing(border-box);
width: flex-grid(12);
h1.user-name {
color: $base-font-color; color: $base-font-color;
font: 700 1.2em/1.2em $sans-serif; font: 700 1.2em/1.2em $sans-serif;
margin: 0px; margin: 0px;
...@@ -21,7 +24,7 @@ ...@@ -21,7 +24,7 @@
text-wrap: nowrap; text-wrap: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
text-transform: none; text-transform: none;
width: flex-grid(12); }
} }
.user-info { .user-info {
...@@ -29,10 +32,10 @@ ...@@ -29,10 +32,10 @@
padding: 0px 10px; padding: 0px 10px;
> ul { > ul {
background: rgb(250,250,250); background: rgb(252,252,252);
border: 1px solid rgb(200,200,200); border: 1px solid rgb(200,200,200);
border-top: none; border-top: none;
@include border-bottom-radius(4px); //@include border-bottom-radius(4px);
@include box-sizing(border-box); @include box-sizing(border-box);
@include box-shadow(inset 0 0 3px 0 rgba(0,0,0, 0.15)); @include box-shadow(inset 0 0 3px 0 rgba(0,0,0, 0.15));
@include clearfix; @include clearfix;
...@@ -68,15 +71,19 @@ ...@@ -68,15 +71,19 @@
width: 19px; width: 19px;
&.email-icon { &.email-icon {
@include background-image(url('/static/images/portal-icons/email-icon.png')); @include background-image(url('../images/portal-icons/email-icon.png'));
}
&.name-icon {
@include background-image(url('../images/portal-icons/course-info-icon.png'));
} }
&.location-icon { &.location-icon {
@include background-image(url('/static/images/portal-icons/home-icon.png')); @include background-image(url('../images/portal-icons/home-icon.png'));
} }
&.language-icon { &.language-icon {
@include background-image(url('/static/images/portal-icons/language-icon.png')); @include background-image(url('../images/portal-icons/language-icon.png'));
} }
} }
} }
...@@ -90,7 +97,6 @@ ...@@ -90,7 +97,6 @@
} }
} }
} }
}
.my-courses { .my-courses {
float: left; float: left;
...@@ -103,7 +109,7 @@ ...@@ -103,7 +109,7 @@
} }
.empty-dashboard-message { .empty-dashboard-message {
padding: 80px 0px; padding: 60px 0px;
text-align: center; text-align: center;
p { p {
...@@ -136,15 +142,12 @@ ...@@ -136,15 +142,12 @@
} }
.my-course { .my-course {
background: rgb(250,250,250);
@include background-image(linear-gradient(-90deg, rgb(253,253,253), rgb(240,240,240)));
border: 1px solid rgb(190,190,190);
@include border-radius(3px); @include border-radius(3px);
@include box-shadow(0 1px 8px 0 rgba(0,0,0, 0.1), inset 0 -1px 0 0 rgba(255,255,255, 0.8), inset 0 1px 0 0 rgba(255,255,255, 0.8)); @include box-shadow(0 1px 8px 0 rgba(0,0,0, 0.1), inset 0 -1px 0 0 rgba(255,255,255, 0.8), inset 0 1px 0 0 rgba(255,255,255, 0.8));
@include box-sizing(border-box);
@include clearfix; @include clearfix;
height: 120px;
margin-right: flex-gutter(); margin-right: flex-gutter();
margin-bottom: 25px; margin-bottom: 10px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
width: flex-grid(12); width: flex-grid(12);
...@@ -158,12 +161,15 @@ ...@@ -158,12 +161,15 @@
background: rgb(225,225,225); background: rgb(225,225,225);
background-size: cover; background-size: cover;
background-position: center center; background-position: center center;
border-right: 1px solid rgb(150,150,150); border: 1px solid rgb(120,120,120);
@include border-left-radius(3px); @include border-left-radius(3px);
@include box-shadow(inset 0 0 0 1px rgba(255,255,255, 0.6), 1px 0 0 0 rgba(255,255,255, 0.8)); @include box-shadow(inset 0 0 0 1px rgba(255,255,255, 0.6), 1px 0 0 0 rgba(255,255,255, 0.8));
@include box-sizing(border-box);
float: left; float: left;
height: 120px; height: 100%;
max-height: 100%;
margin: 0px; margin: 0px;
overflow: hidden;
position: relative; position: relative;
@include transition(all, 0.15s, linear); @include transition(all, 0.15s, linear);
width: 200px; width: 200px;
...@@ -171,7 +177,6 @@ ...@@ -171,7 +177,6 @@
.shade { .shade {
@include background-image(linear-gradient(-90deg, rgba(255,255,255, 0.3) 0%, @include background-image(linear-gradient(-90deg, rgba(255,255,255, 0.3) 0%,
rgba(0,0,0, 0.3) 100%)); rgba(0,0,0, 0.3) 100%));
@include border-radius(4px);
bottom: 0px; bottom: 0px;
content: ""; content: "";
display: block; display: block;
...@@ -211,7 +216,15 @@ ...@@ -211,7 +216,15 @@
} }
.info { .info {
background: rgb(250,250,250);
@include background-image(linear-gradient(-90deg, rgb(253,253,253), rgb(240,240,240)));
@include box-sizing(border-box);
border: 1px solid rgb(190,190,190);
border-left: none;
@include border-right-radius(3px);
left: 201px; left: 201px;
height: 100%;
max-height: 100%;
padding: 0px 10px; padding: 0px 10px;
position: absolute; position: absolute;
right: 0px; right: 0px;
...@@ -219,6 +232,7 @@ ...@@ -219,6 +232,7 @@
z-index: 2; z-index: 2;
> hgroup { > hgroup {
@include clearfix;
border-bottom: 1px solid rgb(210,210,210); border-bottom: 1px solid rgb(210,210,210);
@include box-shadow(0 1px 0 0 rgba(255,255,255, 0.6)); @include box-shadow(0 1px 0 0 rgba(255,255,255, 0.6));
padding: 12px 0px; padding: 12px 0px;
...@@ -236,7 +250,8 @@ ...@@ -236,7 +250,8 @@
@include inline-block; @include inline-block;
margin-right: 10px; margin-right: 10px;
padding: 5px 10px; padding: 5px 10px;
vertical-align: middle;
float: left;
&:hover { &:hover {
color: $blue; color: $blue;
...@@ -245,16 +260,17 @@ ...@@ -245,16 +260,17 @@
} }
h3 { h3 {
@include inline-block; display: block;
margin-bottom: 0px; margin-bottom: 0px;
vertical-align: middle; overflow: hidden;
padding-top: 2px;
text-overflow: ellipsis;
white-space: nowrap;
a { a {
color: $base-font-color; color: $base-font-color;
font-weight: 700; font-weight: 700;
text-shadow: 0 1px rgba(255,255,255, 0.6); text-shadow: 0 1px rgba(255,255,255, 0.6);
text-overflow: ellipsis;
white-space: nowrap;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
...@@ -287,7 +303,7 @@ ...@@ -287,7 +303,7 @@
.course-work-icon { .course-work-icon {
@include background-image(url('/static/images/portal-icons/pencil-icon.png')); @include background-image(url('../images/portal-icons/pencil-icon.png'));
background-size: cover; background-size: cover;
float: left; float: left;
height: 22px; height: 22px;
...@@ -367,5 +383,19 @@ ...@@ -367,5 +383,19 @@
} }
} }
} }
a.unenroll {
float: right;
font-style: italic;
color: #a0a0a0;
text-decoration: underline;
font-size: .8em;
@include inline-block;
margin-bottom: 40px;
&:hover {
color: #333;
}
}
} }
} }
section.outside-app {
@extend .container;
text-align: left;
padding: 80px 0;
h1 {
@extend h2;
margin-bottom: 40px;
}
p {
max-width: 600px;
margin: 0 auto;
}
}
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
> header { > header {
background: rgb(255,255,255); background: rgb(255,255,255);
@include background-image(url('/static/images/shot-2-large.jpg')); @include background-image(url('/static/images/homepage-bg.jpg'));
background-size: cover; background-size: cover;
border-bottom: 1px solid rgb(80,80,80); border-bottom: 1px solid rgb(80,80,80);
@include box-shadow(0 1px 0 0 rgba(255,255,255, 0.9), inset 0 -1px 5px 0 rgba(0,0,0, 0.1)); @include box-shadow(0 1px 0 0 rgba(255,255,255, 0.9), inset 0 -1px 5px 0 rgba(0,0,0, 0.1));
@include clearfix; @include clearfix;
height: 430px; height: 460px;
margin-top: -69px; margin-top: -69px;
overflow: hidden; overflow: hidden;
padding: 0px; padding: 0px;
...@@ -17,40 +17,30 @@ ...@@ -17,40 +17,30 @@
.outer-wrapper { .outer-wrapper {
@extend .animation-home-header-pop-up; @extend .animation-home-header-pop-up;
margin: 0 auto; margin: 0 auto;
padding: 200px 10px 0px; padding: 240px 10px 0px;
position: relative; position: relative;
width: grid-width(12); max-width: 1200px;
min-width: 760px;
@include clearfix;
} }
.title { .title {
background: #FFF;
background: rgba(255,255,255, 0.93); background: rgba(255,255,255, 0.93);
border: 1px solid rgb(100,100,100); border: 1px solid rgb(100,100,100);
@include box-shadow(0 4px 25px 0 rgba(0,0,0, 0.5)); @include box-shadow(0 4px 25px 0 rgba(0,0,0, 0.5));
@include box-sizing(border-box); @include box-sizing(border-box);
height: 120px; height: 120px;
@include inline-block; margin-left: grid-width(2) + $gw-gutter;
margin-left: grid-width(1) + $gw-gutter; float: left;
margin-right: $gw-gutter;
position: relative; position: relative;
text-align: center; text-align: center;
@include transition(all, 0.2s, linear); @include transition(all, 0.2s, linear);
vertical-align: top; vertical-align: top;
&:hover { &:hover {
height: 165px;
> hgroup {
h1 {
border-bottom: 1px solid rgb(200,200,200);
padding-bottom: 10px;
}
h2 {
opacity: 0;
}
}
.actions { .actions {
opacity: 1; display: none;
} }
} }
...@@ -78,122 +68,21 @@ ...@@ -78,122 +68,21 @@
text-transform: lowercase; text-transform: lowercase;
} }
} }
.actions {
@include clearfix;
@include box-sizing(border-box);
left: 0px;
opacity: 0;
padding: 20px 30px 0px;
position: absolute;
@include transition(opacity, 0.2s, linear);
top: 75px;
width: flex-grid(12);
.main-cta {
float: left;
margin-right: flex-gutter();
width: flex-grid(6);
> a.find-courses {
@include button(shiny, $blue);
@include box-sizing(border-box);
@include border-radius(3px);
display: block;
font: normal 1.2rem/1.6rem $sans-serif;
letter-spacing: 1px;
padding: 10px 0px;
text-transform: uppercase;
text-align: center;
width: flex-grid(12);
&:hover {
color: rgb(255,255,255);
}
}
}
.secondary-actions {
@include box-sizing(border-box);
@include clearfix;
float: left;
width: flex-grid(6);
.social-sharing {
@include box-sizing(border-box);
float: left;
height: 44px;
margin-right: flex-gutter();
position: relative;
text-align: center;
width: flex-grid(12);
&:hover {
.sharing-message {
opacity: 1;
top: 50px;
}
}
.sharing-message {
@include background-image(linear-gradient(-90deg, rgba(0,0,0, 0.9) 0%,
rgba(0,0,0, 0.7) 100%));
border: 1px solid rgba(0,0,0, 0.5);
@include border-radius(4px);
@include box-shadow(0 4px 25px 0 rgba(0,0,0, 0.5));
@include box-sizing(border-box);
color: rgb(255,255,255);
float: right;
font-family: $serif;
font-size: 0.9em;
font-style: italic;
left: 50%;
margin-left: -110px;
opacity: 0;
padding: 6px 10px;
position: absolute;
text-align: center;
@include transition(all, 0.15s, ease-out);
top: 25px;
width: 220px;
&:hover {
opacity: 0;
} }
}
.share {
height: 44px;
@include inline-block;
margin-right: 10px;
opacity: 0.5;
@include transition(all, 0.15s, linear);
width: 44px;
&:hover { .actions {
opacity: 1; display: none;
}
img {
width: 100%;
}
&:last-child {
margin-right: 0px;
}
}
}
}
}
} }
.media { .media {
background: #FFF;
background: rgba(255,255,255, 0.93); background: rgba(255,255,255, 0.93);
border: 1px solid rgb(100,100,100); border: 1px solid rgb(100,100,100);
border-left: 0;
@include box-sizing(border-box); @include box-sizing(border-box);
@include box-shadow(0 4px 25px 0 rgba(0,0,0, 0.5)); // @include box-shadow(0 4px 25px 0 rgba(0,0,0, 0.5));
height: 120px; height: 120px;
@include inline-block; float: left;
padding: 4px; padding: 4px;
position: relative; position: relative;
vertical-align: top; vertical-align: top;
...@@ -225,6 +114,7 @@ ...@@ -225,6 +114,7 @@
width: 60px; width: 60px;
&::after { &::after {
color: #fff;
color: rgba(255,255,255, 0.8); color: rgba(255,255,255, 0.8);
content: "\25B6"; content: "\25B6";
display: block; display: block;
...@@ -245,14 +135,13 @@ ...@@ -245,14 +135,13 @@
} }
&:hover { &:hover {
cursor: pointer;
.play-intro { .play-intro {
@include background-image(linear-gradient(-90deg, rgba(0,0,0, 0.75), rgba(0,0,0, 0.8))); @include background-image(linear-gradient(-90deg, rgba(0,0,0, 0.75), rgba(0,0,0, 0.8)));
@include box-shadow(0 1px 12px 0 rgba(0,0,0, 0.5)); @include box-shadow(0 1px 12px 0 rgba(0,0,0, 0.5));
border-color: rgba(255,255,255, 0.9); border-color: rgba(255,255,255, 0.9);
&::after { &::after {
color: #fff;
color: rgba(255,255,255, 1); color: rgba(255,255,255, 1);
} }
} }
...@@ -281,14 +170,6 @@ ...@@ -281,14 +170,6 @@
text-align: center; text-align: center;
text-transform: uppercase; text-transform: uppercase;
text-shadow: 0 1px rgba(255,255,255, 0.6); text-shadow: 0 1px rgba(255,255,255, 0.6);
.lowercase {
color: $lighter-base-font-color;
font-family: inherit;
font-size: inherit;
font-style: inherit;
text-transform: none;
}
} }
} }
...@@ -407,6 +288,8 @@ ...@@ -407,6 +288,8 @@
} }
&:hover { &:hover {
text-decoration: none;
&::before { &::before {
opacity: 1; opacity: 1;
} }
......
.container.jobs { .container.jobs {
padding: 60px 0 120px; padding: 60px 0 120px;
q {
display: block;
margin: 10px 0;
font-style: italic;
text-align: justify;
}
small.author {
text-align: right;
display: block;
color: rgb(100, 100, 100);
}
h1 + hr { h1 + hr {
margin-bottom: 80px; margin-bottom: 80px;
} }
...@@ -25,6 +38,34 @@ ...@@ -25,6 +38,34 @@
width: 100%; width: 100%;
} }
} }
header {
float: left;
width: flex-grid(7);
blockquote {
margin-left: 0;
margin-bottom: 40px;
&:last-child {
margin-bottom: 0;
}
p {
margin-left: 0;
font-style: italic;
line-height: 1.4;
font-size: 1.1em;
color: #666;
}
cite {
margin-top: 12px;
display: block;
color: #a0a0a0;
}
}
}
} }
.jobs-wrapper { .jobs-wrapper {
......
.password-reset {
background: rgb(245,245,245);
border: 1px solid rgb(200,200,200);
@include border-radius(4px);
@include box-sizing(border-box);
@include box-shadow(0 5px 50px 0 rgba(0,0,0, 0.3));
margin: 120px auto 0;
padding: 0px 40px 40px;
width: flex-grid(5);
header {
margin-bottom: 30px;
overflow: hidden;
padding: 28px 20px 0px;
position: relative;
z-index: 2;
&::before {
@include background-image(radial-gradient(50% 50%, circle closest-side, rgba(255,255,255, 0.8) 0%, rgba(255,255,255, 0) 100%));
content: "";
display: block;
height: 400px;
left: 0px;
margin: 0 auto;
position: absolute;
top: -140px;
width: 100%;
z-index: 1;
}
hr {
@extend .faded-hr-divider-light;
border: none;
margin: 0px;
position: relative;
z-index: 2;
&::after {
@extend .faded-hr-divider;
bottom: 0px;
content: "";
display: block;
position: absolute;
top: -1px;
}
}
h2 {
position: relative;
text-align: center;
text-shadow: 0 1px rgba(255,255,255, 0.4);
z-index: 2;
}
}
> p {
margin-bottom: 20px;
}
form {
margin-bottom: 12px;
position: relative;
z-index: 2;
label {
display: none;
}
input[type="checkbox"] {
margin-right: 5px;
}
input[type="email"],
input[type="text"],
input[type="password"] {
background: rgb(255,255,255);
display: block;
height: 45px;
margin-bottom: 20px;
width: 100%;
}
.submit {
padding-top: 10px;
input[type="submit"] {
display: block;
height: 45px;
margin: 0 auto;
width: 100%;
}
}
}
}
...@@ -3,21 +3,29 @@ ...@@ -3,21 +3,29 @@
@include clearfix; @include clearfix;
padding: 40px 0px 15px; padding: 40px 0px 15px;
.university-column {
width: flex-grid(4);
margin-right: flex-gutter();
float: left;
&:nth-child(3n+3) {
margin-right: 0;
}
}
.course { .course {
background: rgb(250,250,250); background: rgb(250,250,250);
border: 1px solid rgb(180,180,180); border: 1px solid rgb(180,180,180);
@include border-radius(2px); @include border-radius(2px);
@include box-sizing(border-box); @include box-sizing(border-box);
@include box-shadow(0 1px 10px 0 rgba(0,0,0, 0.15), inset 0 0 0 1px rgba(255,255,255, 0.9)); @include box-shadow(0 1px 10px 0 rgba(0,0,0, 0.15), inset 0 0 0 1px rgba(255,255,255, 0.9));
float: left;
margin-right: flex-gutter();
margin-bottom: 30px; margin-bottom: 30px;
position: relative; position: relative;
width: flex-grid(4); width: 100%;
@include transition(all, 0.15s, linear); @include transition(all, 0.15s, linear);
&:nth-child(3n+3) { a:hover {
margin-right: 0; text-decoration: none;
} }
.meta-info { .meta-info {
...@@ -28,7 +36,7 @@ ...@@ -28,7 +36,7 @@
@include box-shadow(0 1px 5px 0 rgba(0,0,0, 0.15)); @include box-shadow(0 1px 5px 0 rgba(0,0,0, 0.15));
@include clearfix; @include clearfix;
position: absolute; position: absolute;
right: -3px; right: -4px;
@include transition(all, 0.15s, linear); @include transition(all, 0.15s, linear);
p { p {
...@@ -42,7 +50,7 @@ ...@@ -42,7 +50,7 @@
.inner-wrapper { .inner-wrapper {
border: 1px solid rgba(255,255,255, 1); border: 1px solid rgba(255,255,255, 1);
height: 100%; height: 100%;
height: 180px; height: 200px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
} }
...@@ -54,31 +62,53 @@ ...@@ -54,31 +62,53 @@
width: 100%; width: 100%;
z-index: 3; z-index: 3;
> a { // > a {
@include background-image(linear-gradient(-90deg, rgba(255,255,255, 1), rgba(255,255,255, 0.85))); @include background-image(linear-gradient(-90deg, rgba(255,255,255, 1), rgba(255,255,255, 0.85)));
@include box-shadow(inset 0 -1px 0 0 rgba(255,255,255, 0.2)); @include box-shadow(inset 0 -1px 0 0 rgba(255,255,255, 0.2));
border-bottom: 1px solid rgba(150,150,150, 0.7); border-bottom: 1px solid rgba(150,150,150, 0.7);
display: block; display: block;
height: 50px; height: 50px;
&:hover {
@include background-image(linear-gradient(-90deg, rgba(255,255,255, 1), rgba(255,255,255, 0.8)));
text-decoration: none;
.info-link {
color: $blue;
opacity: 1;
}
h2 {
color: $blue;
}
}
hgroup { hgroup {
left: 0px; left: 0px;
padding: 5px 10px; padding: 0px 10px;
position: absolute; position: absolute;
right: 60px; right: 60px;
top: 0px; top: 0px;
h2 { h2 {
color: $base-font-color; color: $base-font-color;
display: table-cell;
font-family: $sans-serif; font-family: $sans-serif;
font-size: 1em; font-size: 0.8em;
font-weight: 700; font-weight: 700;
height: 48px;
letter-spacing: 0px;
margin-bottom: 0px; margin-bottom: 0px;
overflow: hidden; padding-top: 0px;
padding-top: 9px;
text-shadow: 0 1px rgba(255,255,255, 0.6); text-shadow: 0 1px rgba(255,255,255, 0.6);
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; text-transform: none;
vertical-align: middle;
.course-number {
font-weight: 700;
text-transform: none;
}
} }
} }
...@@ -86,7 +116,7 @@ ...@@ -86,7 +116,7 @@
border-left: 1px solid rgba(150,150,150, 0.5); border-left: 1px solid rgba(150,150,150, 0.5);
@include box-sizing(border-box); @include box-sizing(border-box);
color: $base-font-color; color: $base-font-color;
display: block; display: inline-block;
font: bold 1.6em/1.2em $sans-serif; font: bold 1.6em/1.2em $sans-serif;
height: 100%; height: 100%;
opacity: 0.6; opacity: 0.6;
...@@ -97,34 +127,24 @@ ...@@ -97,34 +127,24 @@
text-shadow: 0 1px rgba(255,255,255, 0.6); text-shadow: 0 1px rgba(255,255,255, 0.6);
top: 0px; top: 0px;
width: 60px; width: 60px;
vertical-align: middle;
} }
&:hover {
@include background-image(linear-gradient(-90deg, rgba(255,255,255, 1), rgba(255,255,255, 0.8)));
h2, .info-link {
color: $blue;
opacity: 1;
}
h2 {
text-decoration: underline;
}
}
}
} }
// }
.info { .info {
background: rgb(255,255,255); background: rgb(255,255,255);
height: 180px + 130px; height: 220px + 130px;
left: 0px; left: 0px;
position: absolute; position: absolute;
top: 0px; top: 0px;
@include transition(all, 0.15s, linear); @include transition(all, 0.15s, linear);
width: 100%; width: 100%;
overflow: hidden;
.cover-image { .cover-image {
height: 180px; height: 200px;
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
...@@ -137,7 +157,7 @@ ...@@ -137,7 +157,7 @@
.desc { .desc {
@include box-sizing(border-box); @include box-sizing(border-box);
height: 100px; height: 120px;
overflow: hidden; overflow: hidden;
padding: 10px 10px 12px 10px; padding: 10px 10px 12px 10px;
position: relative; position: relative;
...@@ -155,7 +175,6 @@ ...@@ -155,7 +175,6 @@
padding: 0px 10px 10px 10px; padding: 0px 10px 10px 10px;
width: 100%; width: 100%;
.university { .university {
border-right: 1px solid rgb(200,200,200); border-right: 1px solid rgb(200,200,200);
color: $lighter-base-font-color; color: $lighter-base-font-color;
...@@ -181,7 +200,7 @@ ...@@ -181,7 +200,7 @@
@include box-shadow(0 1px 16px 0 rgba($blue, 0.4)); @include box-shadow(0 1px 16px 0 rgba($blue, 0.4));
.info { .info {
top: -130px; top: -150px;
} }
.meta-info { .meta-info {
...@@ -190,4 +209,15 @@ ...@@ -190,4 +209,15 @@
} }
} }
} }
.university-courses {
.course {
width: flex-grid(4);
margin-right: flex-gutter();
float: left;
&:nth-child(3n+3) {
margin-right: 0;
}
}
}
} }
...@@ -15,7 +15,8 @@ footer { ...@@ -15,7 +15,8 @@ footer {
max-width: 1200px; max-width: 1200px;
margin: 0 auto; margin: 0 auto;
padding: 30px 10px 0; padding: 30px 10px 0;
width: grid-width(12); max-width: grid-width(12);
min-width: 760px;
.top { .top {
border-bottom: 1px solid rgb(200,200,200); border-bottom: 1px solid rgb(200,200,200);
...@@ -110,8 +111,7 @@ footer { ...@@ -110,8 +111,7 @@ footer {
padding: 0; padding: 0;
a { a {
opacity: 0.7; opacity: 0.3;
padding: 0 0 0 10px;
@include transition(all, 0.1s, linear); @include transition(all, 0.1s, linear);
&:hover { &:hover {
......
...@@ -9,6 +9,7 @@ form { ...@@ -9,6 +9,7 @@ form {
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
} }
textarea,
input[type="text"], input[type="text"],
input[type="email"], input[type="email"],
input[type="password"] { input[type="password"] {
...@@ -34,6 +35,10 @@ form { ...@@ -34,6 +35,10 @@ form {
} }
} }
textarea {
height: 60px;
}
input[type="submit"] { input[type="submit"] {
@include button(shiny, $blue); @include button(shiny, $blue);
@include border-radius(3px); @include border-radius(3px);
......
...@@ -13,7 +13,8 @@ header.global { ...@@ -13,7 +13,8 @@ header.global {
margin: 0 auto; margin: 0 auto;
max-width: 1200px; max-width: 1200px;
padding: 14px 10px 0px; padding: 14px 10px 0px;
width: grid-width(12); max-width: grid-width(12);
min-width: 760px;
} }
h1.logo { h1.logo {
...@@ -105,7 +106,7 @@ header.global { ...@@ -105,7 +106,7 @@ header.global {
margin-right: 5px; margin-right: 5px;
> a { > a {
@include background-image(linear-gradient(-90deg, rgb(245,245,245) 0%, rgb(243,243,243) 50%, rgb(237,237,237) 50%, rgb(235,235,235) 100%)); @include background-image(linear-gradient(-90deg, #fff 0%, rgb(250,250,250) 50%, rgb(237,237,237) 50%, rgb(220,220,220) 100%));
border: 1px solid transparent; border: 1px solid transparent;
border-color: rgb(200,200,200); border-color: rgb(200,200,200);
@include border-radius(3px); @include border-radius(3px);
...@@ -128,6 +129,7 @@ header.global { ...@@ -128,6 +129,7 @@ header.global {
} }
&:hover, &.active { &:hover, &.active {
background: #FFF;
} }
} }
} }
...@@ -160,7 +162,7 @@ header.global { ...@@ -160,7 +162,7 @@ header.global {
.avatar { .avatar {
//background: rgb(220,220,220); //background: rgb(220,220,220);
@include background-image(url('/static/images/portal-icons/home-icon.png')); @include background-image(url('../images/portal-icons/home-icon.png'));
background-size: cover; background-size: cover;
//@include border-radius(3px); //@include border-radius(3px);
//border: 1px solid rgb(80,80,80); //border: 1px solid rgb(80,80,80);
......
...@@ -106,7 +106,7 @@ ...@@ -106,7 +106,7 @@
} }
} }
#enroll_error, #login_error { .modal-form-error {
background: $error-red; background: $error-red;
border: 1px solid rgb(202, 17, 17); border: 1px solid rgb(202, 17, 17);
color: rgb(143, 14, 14); color: rgb(143, 14, 14);
...@@ -115,8 +115,21 @@ ...@@ -115,8 +115,21 @@
padding: 12px; padding: 12px;
} }
.activation-message { .notice {
background: $yellow;
border: 1px solid darken($yellow, 60%);
color: darken($yellow, 60%);
display: none;
margin-bottom: 20px;
padding: 12px;
}
.activation-message, .message {
padding: 0 40px 10px; padding: 0 40px 10px;
p {
margin-bottom: 10px;
}
} }
form { form {
...@@ -125,6 +138,14 @@ ...@@ -125,6 +138,14 @@
position: relative; position: relative;
z-index: 2; z-index: 2;
.input-group {
@include clearfix;
border-bottom: 1px solid rgb(210,210,210);
@include box-shadow(0 1px 0 0 rgba(255,255,255, 0.6));
margin-bottom: 30px;
padding-bottom: 10px;
}
label { label {
display: none; display: none;
} }
...@@ -133,6 +154,14 @@ ...@@ -133,6 +154,14 @@
margin-right: 5px; margin-right: 5px;
} }
textarea {
background: rgb(255,255,255);
display: block;
height: 45px;
margin-bottom: 20px;
width: 100%;
}
input[type="email"], input[type="email"],
input[type="text"], input[type="text"],
input[type="password"] { input[type="password"] {
...@@ -164,47 +193,44 @@ ...@@ -164,47 +193,44 @@
} }
} }
.honor-code-summary { .citizenship, .gender, .date-of-birth {
margin-bottom: 20px; margin-bottom: 20px;
padding: 0px;
position: relative;
p { .input-wrapper {
color: $lighter-base-font-color;
font-family: $sans-serif;
} }
hr { label {
@extend .faded-hr-divider-light;
border: none;
margin-top: 30px;
position: relative;
z-index: 2;
&::after {
@extend .faded-hr-divider;
bottom: 0px;
content: "";
display: block; display: block;
position: absolute;
top: -1px;
}
} }
ul { select {
@include box-sizing(border-box);
margin: 0;
padding: 0 0 0 20px;
width: 100%; width: 100%;
}
}
li { .citizenship, .gender {
color: $lighter-base-font-color; float: left;
font: 300 1.2rem/1.6rem $sans-serif; width: flex-grid(4);
margin-bottom: 10px; }
&:last-child { .citizenship {
margin-bottom: 0px; margin-right: flex-gutter();
} }
.date-of-birth {
float: left;
width: flex-grid(12);
select {
@include box-sizing(border-box);
display: block;
float: left;
margin-right: flex-gutter();
max-width: flex-grid(4);
width: flex-grid(4);
&:last-child {
margin: 0px;
} }
} }
} }
......
<%! from django.core.urlresolvers import reverse %>
<%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/>
<section class="container activation">
<section class="message">
<h1>Account already active!</h1>
<hr class="horizontal-divider">
<p> This account has already been activated. You can now <a href="#login-modal" rel="leanModal">login</a>.</p>
</section>
</section>
<%! from django.core.urlresolvers import reverse %>
<%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/>
<section class="container activation">
<section class="message">
<h1 class="valid">Activation Complete!</h1>
<hr class="horizontal-divider">
<p>Thanks for activating your account. You can now <a href="#login-modal" rel="leanModal">login</a>.</p>
</section>
</section>
...@@ -12,20 +12,20 @@ ...@@ -12,20 +12,20 @@
<section class="contact"> <section class="contact">
<div class="map"> <div class="map">
<img src="${static.url('images/edx-location.png')}"> <img src="${static.url('images/contact-page.jpg')}">
</div> </div>
<div class="contacts"> <div class="contacts">
<h2>Class Feedback</h2> <h2>Class Feedback</h2>
<p>We are always seeking feedback to improve our courses. If you are an enrolled student and have any questions, feedback, suggestions, or any other issues specific to a particular class, please post on the discussion forums of that class.</p> <p>We are always seeking feedback to improve our courses. If you are an enrolled student and have any questions, feedback, suggestions, or any other issues specific to a particular class, please post on the discussion forums of that class.</p>
<h2>General Inqueries and Feedback</h2> <h2>General Inquiries and Feedback</h2>
<p>If you have a general question about edX please email <a href="mailto:info@edx.org">info@edx.org</a>. To see if your question has already been answered, visit our <a href="${reverse('faq_edx')}">FAQ page</a>. Though we may not have a chance to respond to every email, we take all feedback into consideration.</p> <p>"If you have a general question about edX please email <a href="mailto:info@edx.org">info@edx.org</a>. To see if your question has already been answered, visit our <a href="${reverse('faq_edx')}">FAQ page</a>. You can also join the discussion on our <a href="http://www.facebook.com/EdxOnline">facebook page</a>. Though we may not have a chance to respond to every email, we take all feedback into consideration.</p>
<h2>Technical Inqueries and Feedback</h2> <h2>Technical Inquiries and Feedback</h2>
<p>If you have suggestions/feedback about the overall edX platform, or are facing general technical issues with the platform (e.g., issues with email addresses and passwords), you can reach us at <a href="mailto:technical@edx.org">technical@edx.org</a>. For technical questions, please make sure you are using a current version of Firefox or Chrome, and include browser and version in your e-mail, as well as screenshots or other pertinent details. If you find a bug or other issues, you can reach us at the following: <a href="mailto:bugs@edx.org">bugs@edx.org</a>.</p> <p>If you have suggestions/feedback about the overall edX platform, or are facing general technical issues with the platform (e.g., issues with email addresses and passwords), you can reach us at <a href="mailto:technical@edx.org">technical@edx.org</a>. For technical questions, please make sure you are using a current version of Firefox or Chrome, and include browser and version in your e-mail, as well as screenshots or other pertinent details. If you find a bug or other issues, you can reach us at the following: <a href="mailto:bugs@edx.org">bugs@edx.org</a>.</p>
<h2>Media</h2> <h2>Media</h2>
<p>Please visit our <a href="${reverse('faq_edx')}">media/press page</a> for more information. 
For any media or press enquiries, please email <a href="mailto:press@edx.org">press@edx.org</a>.</p> <p>Please visit our <a href="${reverse('faq_edx')}">media/press page</a> for more information. 
For any media or press inquiries, please email <a href="mailto:press@edx.org">press@edx.org</a>.</p>
<h2>Universities</h2> <h2>Universities</h2>
<p>If you are a university wishing to Collaborate or with questions about edX, please email <a href="mailto:university@edx.org">university@edx.org</a>.</p> <p>If you are a university wishing to Collaborate or with questions about edX, please email <a href="mailto:university@edx.org">university@edx.org</a>.</p>
......
<%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" />
<article id="${course.id}" class="course">
<article id="${course.id}"class="course"> <a href="${reverse('about_course', args=[course.id])}">
<div class="inner-wrapper"> <div class="inner-wrapper">
<header class="course-preview"> <header class="course-preview">
<a href="${reverse('about_course', args=[course.id])}">
<hgroup> <hgroup>
<h2>${course.number} ${course.get_about_section('title')}</h2> <h2><span class="course-number">${course.number}</span> ${get_course_about_section(course, 'title')}</h2>
</hgroup> </hgroup>
<div class="info-link">&#x2794;</div> <div class="info-link">&#x2794;</div>
</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="${reverse('university_profile', args=[course.org])}" class="university">${get_course_about_section(course, 'university')}</a>
<span class="start-date">7/23/12</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>
</a>
</article> </article>
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%block name="title"><title>Courses</title></%block>
<section class="find-courses"> <section class="find-courses">
<header class="search" style="background: url('/static/images/shot-2-large.jpg')"> <header class="search" style="background: url('/static/images/homepage-bg.jpg')">
<div class="inner-wrapper main-search"> <div class="inner-wrapper main-search">
<hgroup> <hgroup>
<div class="logo"> <div class="logo">
...@@ -18,9 +20,21 @@ ...@@ -18,9 +20,21 @@
## I'm removing this for now since we aren't using it for the fall. ## I'm removing this for now since we aren't using it for the fall.
## <%include file="course_filter.html" /> ## <%include file="course_filter.html" />
<section class="courses"> <section class="courses">
%for course in courses: <section class='university-column'>
%for course in universities['MITx']:
<%include file="course.html" args="course=course" />
%endfor
</section>
<section class='university-column'>
%for course in universities['HarvardX']:
<%include file="course.html" args="course=course" /> <%include file="course.html" args="course=course" />
%endfor %endfor
</section> </section>
<section class='university-column last'>
%for course in universities['BerkeleyX']:
<%include file="course.html" args="course=course" />
%endfor
</section>
</section>
</section> </section>
</section> </section>
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<section class="main-content"> <section class="main-content">
<section class="outside-app"> <section class="outside-app">
<h1>There has been an error on the <em>edX</em> servers</h1> <h1>There has been an error on the <span class="edx">edX</span> servers</h1>
<p>We're sorry, this module is temporarily unavailable. Our staff is working to fix it as soon as possible. Please email us at <a href="mailto:technical@mitx.mit.edu">technical@mitx.mit.edu</a> to report any problems or downtime.</p> <p>We're sorry, this module is temporarily unavailable. Our staff is working to fix it as soon as possible. Please email us at <a href="mailto:technical@mitx.mit.edu">technical@mitx.mit.edu</a> to report any problems or downtime.</p>
</section> </section>
</section> </section>
...@@ -3,16 +3,35 @@ ...@@ -3,16 +3,35 @@
<%block name="bodyclass">courseware</%block> <%block name="bodyclass">courseware</%block>
<%block name="title"><title>Courseware – MITx 6.002x</title></%block> <%block name="title"><title>Courseware – MITx 6.002x</title></%block>
<%block name="headextra">
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
</%block>
<%block name="js_extra"> <%block name="js_extra">
<!-- TODO: http://docs.jquery.com/Plugins/Validation --> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
<script type="text/javascript">
## codemirror
<script type="text/javascript" src="${static.url('js/vendor/codemirror-compressed.js')}"></script>
## alternate codemirror
## <script type="text/javascript" src="${static.url('js/vendor/CodeMirror-2.25/lib/codemirror.js')}"></script>
## <script type="text/javascript" src="${static.url('js/vendor/CodeMirror-2.25/mode/xml/xml.js')}"></script>
## <script type="text/javascript" src="${static.url('js/vendor/CodeMirror-2.25/mode/python/python.js')}"></script>
## image input: for clicking on images (see imageinput.html)
<script type="text/javascript" src="${static.url('js/vendor/imageinput.js')}"></script>
## TODO (cpennington): Remove this when we have a good way for modules to specify js to load on the page
## and in the wiki
<script type="text/javascript" src="${static.url('js/schematic.js')}"></script>
<%static:js group='courseware'/>
<%static:css group='course'/>
<%include file="mathjax_include.html" />
<!-- TODO: http://docs.jquery.com/Plugins/Validation -->
<script type="text/javascript">
document.write('\x3Cscript type="text/javascript" src="' + document.write('\x3Cscript type="text/javascript" src="' +
document.location.protocol + '//www.youtube.com/player_api">\x3C/script>'); document.location.protocol + '//www.youtube.com/player_api">\x3C/script>');
</script> </script>
</%block> </%block>
<%include file="course_navigation.html" args="active_page='courseware'" /> <%include file="course_navigation.html" args="active_page='courseware'" />
......
<%! 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'/>
<%block name="title"><title>Dashboard</title></%block>
<%block name="js_extra">
<script type="text/javascript">
(function() {
$(".unenroll").click(function(event) {
$("#unenroll_course_id").val( $(event.target).data("course-id") );
$("#unenroll_course_number").text( $(event.target).data("course-number") );
});
$(document).delegate('#unenroll_form', 'ajax:success', function(data, json, xhr) {
if(json.success) {
location.href="${reverse('dashboard')}";
} else {
if($('#unenroll_error').length == 0) {
$('#unenroll_form').prepend('<div id="unenroll_error" class="modal-form-error"></div>');
}
$('#unenroll_error').text(json.error).stop().css("display", "block");
}
});
})(this)
</script>
</%block>
<section class="container dashboard"> <section class="container dashboard">
<section class="dashboard-banner">
${message}
<br/>
</section>
<section class="profile-sidebar"> <section class="profile-sidebar">
<header class="profile"> <header class="profile">
<h1 class="user-name">${ user.username }</h1> <h1 class="user-name">${ user.username }</h1>
</header>
<section class="user-info"> <section class="user-info">
<ul> <ul>
<li> <li>
<span class="title"><div class="icon email-icon"></div>Email</span><span class="data">${ user.email }</span> <span class="title"><div class="icon name-icon"></div>Full Name</span><span class="data">${ user.profile.name | h }</span>
</li>
<li>
<span class="title"><div class="icon location-icon"></div>Location</span><span class="data">${ user.profile.location }</span>
</li> </li>
<li> <li>
<span class="title"><div class="icon language-icon"></div>Language</span><span class="data">${ user.profile.language }</span> <span class="title"><div class="icon email-icon"></div>Email</span><span class="data">${ user.email | h }</span>
</li> </li>
</ul> </ul>
</section> </section>
</header>
</section> </section>
<section class="my-courses"> <section class="my-courses">
...@@ -33,17 +64,23 @@ ...@@ -33,17 +64,23 @@
% 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')"> <%
if course.has_started():
course_target = reverse('info', args=[course.id])
else:
course_target = reverse('about_course', args=[course.id])
%>
<a href="${course_target}" 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="${reverse('university_profile', args=[course.org])}" 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="${course_target}">${course.number} ${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>${course.start_date_text}</span></div>
</section> </section>
<section class="meta"> <section class="meta">
<div class="course-work-icon"></div> <div class="course-work-icon"></div>
...@@ -53,11 +90,12 @@ ...@@ -53,11 +90,12 @@
</div> </div>
</div> </div>
<div class="complete"> <div class="complete">
<p><span class="completeness">60%</span> compleat</p> ##<p><span class="completeness">60%</span> complete</p>
</div> </div>
</section> </section>
</section> </section>
</article> </article>
<a href="#unenroll-modal" class="unenroll" rel="leanModal" data-course-id="${course.id}" data-course-number="${course.number}">Unenroll</a>
% endfor % endfor
% else: % else:
...@@ -69,3 +107,30 @@ ...@@ -69,3 +107,30 @@
</section> </section>
</section> </section>
<section id="unenroll-modal" class="modal unenroll-modal">
<div class="inner-wrapper">
<header>
<h2>Are you sure you want to unenroll from <span id="unenroll_course_number"></span>?</h2>
<hr>
</header>
<form id="unenroll_form" method="post" data-remote="true" action="${reverse('change_enrollment')}">
<input name="course_id" id="unenroll_course_id" type="hidden" />
<input name="enrollment_action" type="hidden" value="unenroll" />
<div class="submit">
<input name="submit" type="submit" value="Unenroll" />
</div>
</form>
<div class="close-modal">
<div class="inner">
<p>&#10005;</p>
</div>
</div>
</div>
</section>
Someone, hopefully you, signed up for an account for edX's on-line Thank you for signing up for edX! To activate your account,
offering of "${ course_title}" using this email address. If it was please copy and paste this address into your web browser's
you, and you'd like to activate and use your account, copy and paste address bar:
this address into your web browser's address bar:
% if is_secure: % if is_secure:
https://${ site }/activate/${ key } https://${ site }/activate/${ key }
......
<%! from django.core.urlresolvers import reverse %> <%! from django.core.urlresolvers import reverse %>
This is to confirm that you changed the e-mail associated with MITx This is to confirm that you changed the e-mail associated with edX
from ${old_email} to ${new_email}. If you did not make this request, from ${old_email} to ${new_email}. If you did not make this request,
please contact the course staff immediately. Contact information is please contact the course staff immediately. Contact information is
listed at: listed at:
......
We received a request to change the e-mail associated with your MITx We received a request to change the e-mail associated with your edX
account from ${old_email} to ${new_email}. If this is correct, please account from ${old_email} to ${new_email}. If this is correct, please
confirm your new e-mail address by visiting: confirm your new e-mail address by visiting:
...@@ -10,4 +10,4 @@ confirm your new e-mail address by visiting: ...@@ -10,4 +10,4 @@ confirm your new e-mail address by visiting:
If you didn't request this, you don't need to do anything; you won't If you didn't request this, you don't need to do anything; you won't
receive any more email from us. Please do not reply to this e-mail; if receive any more email from us. Please do not reply to this e-mail; if
you require assistance, check the help section of the MITx web site. you require assistance, check the help section of the edX web site.
Request to change MITx account e-mail Request to change edX account e-mail
MITx's prototype offering, 6.002x, is open. To log in, visit edX has launched! To log in, visit:
% if is_secure: % if is_secure:
https://6002x.mitx.mit.edu https://edx.org
% else: % else:
http://6002x.mitx.mit.edu http://edx.org
% endif % endif
where you will find a login button at the top right-hand corner of the A login button will be at the top right-hand corner of the window.
window.
Please make sure you're using the latest version of Google Chrome or Please make sure you're using the latest version of Google Chrome or
Firefox. If you've forgotten your password, the log-in form has a Firefox. If you've forgotten your password, the log-in form has a
place to reset it. place to reset it.
Once you log in, we recommend that you start the course by reviewing
the "System Usage Sequence" in the Overview section, and the "6.002x
At-a-Glance (Calendar)" handout under the Course Info tab. After you
familiarize yourself with the features of the MITx platform,
you can jump right into the coursework by working on "Administrivia
and Circuit Elements", the first Lecture Sequence in Week 1.
Thanks for joining us for the ride! Thanks for joining us for the ride!
The 6.002x team The edX team
(Please note that this e-mail address does not receive e-mails -- (Please note that this e-mail address does not receive e-mails --
if you need assistance, please use the help section of the web if you need assistance, please use the help section of the web
......
<%! from django.core.urlresolvers import reverse %>\
<?xml version="1.0" encoding="UTF-8"?>
<%namespace name='static' file='static_content.html'/>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
<id>tag:www.edx.org,2012:/blog</id>
<link type="text/html" rel="alternate" href="http://blog.edx.org/"/>
##<link type="application/atom+xml" rel="self" href="https://github.com/blog.atom"/>
<title>EdX Blog</title>
<updated>2012-07-16T14:08:12-07:00</updated>
<entry>
<id>tag:www.edx.org,2012:Post/3</id>
<published>2012-07-16T14:08:12-07:00</published>
<updated>2012-07-16T14:08:12-07:00</updated>
<link type="text/html" rel="alternate" href="#"/>
<title>UC Berkeley joins edX</title>
<content type="html">&lt;img src=&quot;${static.url('images/press/edx_logo_108x81.jpeg')}&quot; /&gt;
&lt;p&gt;edX broadens course offerings&lt;/p&gt;</content>
</entry>
<entry>
<id>tag:www.edx.org,2012:Post/2</id>
<published>2012-07-16T14:08:12-07:00</published>
<updated>2012-07-16T14:08:12-07:00</updated>
<link type="text/html" rel="alternate" href="http://edxonline.tumblr.com/post/27589840852/opening-doors-for-exceptional-students-6-002x-in"/>
<title>Opening Doors For Exceptional Students: 6.002x in Mongolia</title>
<content type="html">&lt;img src=&quot;http://media.tumblr.com/tumblr_m6y5eyXV1F1rsal4c.jpg&quot; /&gt;</content>
</entry>
<entry>
<id>tag:www.edx.org,2012:Post/1</id>
<published>2012-07-16T14:08:12-07:00</published>
<updated>2012-07-16T14:08:12-07:00</updated>
<link type="text/html" rel="alternate" href="http://edxonline.tumblr.com/post/27589835076/beyond-the-circuits-a-students-experience-with-6-002x"/>
<title>Brazilian teen blogs about his 6.002x experience</title>
<content type="html">&lt;img src=&quot;http://media.tumblr.com/tumblr_m7bdkyV9Lp1rsal4c.png&quot; /&gt;</content>
</entry>
</feed>
...@@ -8,15 +8,16 @@ ...@@ -8,15 +8,16 @@
<a href="${reverse('root')}" class="logo"></a> <a href="${reverse('root')}" class="logo"></a>
<a href="${reverse('courses')}">Find Courses</a> <a href="${reverse('courses')}">Find Courses</a>
<a href="${reverse('about_edx')}">About</a> <a href="${reverse('about_edx')}">About</a>
<a href="#">Blog</a> <a href="http://edxonline.tumblr.com/">Blog</a>
<a href="${reverse('jobs')}">Jobs</a> <a href="${reverse('jobs')}">Jobs</a>
<a href="${reverse('contact')}">Contact</a> <a href="${reverse('contact')}">Contact</a>
</section> </section>
<section class="social"> <section class="social">
<a href="#"><img src="${static.url('images/linkedin.png')}" /></a> <a href="http://youtube.com/user/edxonline"><img src="${static.url('images/social/youtube-sharing.png')}" /></a>
<a href="#"><img src="${static.url('images/facebook.png')}" /></a> <a href="https://plus.google.com/108235383044095082735"><img src="${static.url('images/social/google-plus-sharing.png')}" /></a>
<a href="#"><img src="${static.url('images/twitter.png')}" /></a> <a href="http://www.facebook.com/EdxOnline"><img src="${static.url('images/social/facebook-sharing.png')}" /></a>
<a href="https://twitter.com/edXOnline"><img src="${static.url('images/social/twitter-sharing.png')}" /></a>
</section> </section>
</section> </section>
......
<%! from django.core.urlresolvers import reverse %>
<section id="forgot-password-modal" class="modal forgot-password-modal">
<div class="inner-wrapper">
<div id="password-reset">
<header>
<h2>Password reset</h2>
<hr>
</header>
<div class="message">
<p>Enter your e-mail address below, and we will e-mail instructions for setting a new password.</p>
</div>
<form id="pwd_reset_form" action="${reverse('password_reset')}" method="post" data-remote="true">
<label for="id_email">E-mail address:</label>
<input id="id_email" type="email" name="email" maxlength="75" placeholder="Your E-mail"/>
<div class="submit">
<input type="submit" id="pwd_reset_button" value="Reset my password" />
</div>
</form>
</div>
<div class="close-modal">
<div class="inner">
<p>&#10005;</p>
</div>
</div>
</div>
</section>
<script type="text/javascript">
(function() {
$(document).delegate('#pwd_reset_form', 'ajax:success', function(data, json, xhr) {
if(json.success) {
$("#password-reset").html(json.value);
} else {
if($('#pwd_error').length == 0) {
$('#pwd_reset_form').prepend('<div id="pwd_error" class="modal-form-error">Email is incorrect.</div>');
}
$('#pwd_error').stop().css("display", "block");
}
});
})(this)
</script>
<%inherit file="main.html" /> <%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%block name="headextra"> <%block name="js_extra">
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script>
</%block>
<%block name="headextra">
<style type="text/css"> <style type="text/css">
.grade_a {color:green;} .grade_a {color:green;}
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%namespace name="profile_graphs" file="profile_graphs.js"/> <%namespace name="profile_graphs" file="profile_graphs.js"/>
<%block name="headextra"> <%block name="js_extra">
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script>
......
<%! from django.core.urlresolvers import reverse %> <%! from django.core.urlresolvers import reverse %>
<%! from time import strftime %>
<%inherit file="main.html" /> <%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
...@@ -8,7 +9,7 @@ ...@@ -8,7 +9,7 @@
<div class="title"> <div class="title">
<hgroup> <hgroup>
<h1>The Future of Online Education</h1> <h1>The Future of Online Education</h1>
<h2>For anyone, anywhere, anytime.</h2> <h2>For anyone, anywhere, anytime</h2>
</hgroup> </hgroup>
<section class="actions"> <section class="actions">
...@@ -18,15 +19,15 @@ ...@@ -18,15 +19,15 @@
<div class="secondary-actions"> <div class="secondary-actions">
<div class="social-sharing"> <div class="social-sharing">
<div class="sharing-message">Share with friends and family!</div> <div class="sharing-message">Stay up to date with all edX has to offer!</div>
<a href="#" class="share"> <a href="https://twitter.com/edXOnline" class="share">
<img src="${static.url('images/twitter-sharing.png')}"> <img src="${static.url('images/social/twitter-sharing.png')}">
</a> </a>
<a href="#" class="share"> <a href="http://www.facebook.com/EdxOnline" class="share">
<img src="${static.url('images/facebook-sharing.png')}"> <img src="${static.url('images/social/facebook-sharing.png')}">
</a> </a>
<a href="#" class="share"> <a href="https://plus.google.com/108235383044095082735/posts" class="share">
<img src="${static.url('images/email-sharing.png')}"> <img src="${static.url('images/social/google-plus-sharing.png')}">
</a> </a>
</div> </div>
</div> </div>
...@@ -35,40 +36,39 @@ ...@@ -35,40 +36,39 @@
<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/space3.jpg')}" /> <img src="${static.url('images/courses/video-thumb.jpg')}" />
<div class="play-intro"></div> <div class="play-intro"></div>
</div> </div>
</a> </a>
</div> </div>
</header> </header>
<section class="container"> <section class="container">
<section class="highlighted-courses"> <section class="highlighted-courses">
<h2>Explore courses from <span class="lowercase">edX</span> universities</h2> <h2>Explore courses from <span class="edx">edX</span> universities</h2>
<section class="university-partners"> <section class="university-partners">
<ol class="partners"> <ol class="partners">
<li class="partner mit"> <li class="partner mit">
<a href="/university_profile"> <a href="${reverse('university_profile', args=['MITx'])}">
<img src="${static.url('images/mit.png')}" /> <img src="${static.url('images/university/mit/mit.png')}" />
<div class="name"> <div class="name">
<span>MITx</span> <span>MITx</span>
</div> </div>
</a> </a>
</li> </li>
<li class="partner"> <li class="partner">
<a href="/university_profile"> <a href="${reverse('university_profile', args=['HarvardX'])}">
<img src="${static.url('images/harvard.png')}" /> <img src="${static.url('images/university/harvard/harvard.png')}" />
<div class="name"> <div class="name">
<span>HarvardX</span> <span>HarvardX</span>
</div> </div>
</a> </a>
</li> </li>
<li class="partner"> <li class="partner last">
<a href="/university_profile"> <a href="${reverse('university_profile', args=['BerkeleyX'])}">
<img src="${static.url('images/berkeley.png')}" /> <img src="${static.url('images/university/berkeley/berkeley.png')}" />
<div class="name"> <div class="name">
<span>BerkeleyX</span> <span>BerkeleyX</span>
</div> </div>
...@@ -78,54 +78,57 @@ ...@@ -78,54 +78,57 @@
</section> </section>
<section class="courses"> <section class="courses">
%for course in courses: <section class='university-column'>
%for course in universities['MITx']:
<%include file="course.html" args="course=course" />
%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" /> <%include file="course.html" args="course=course" />
%endfor %endfor
</section> </section>
</section> </section>
</section> </section>
</section>
<section class="container"> <section class="container">
<section class="more-info"> <section class="more-info">
<header> <header>
<h2>edX News & Announcements</h2> <h2><span class="edx">edX</span> News &amp; Announcements</h2>
<a href="${reverse('press')}">Read More &rarr;</a> <a href="${reverse('press')}">Read More &rarr;</a>
</header> </header>
<section class="news"> <section class="news">
<section class="blog-posts"> <section class="blog-posts">
%for entry in entries:
<article> <article>
<a href="#" class="post-graphics"> %if entry.image:
<img src="${static.url('images/mongolia_post.jpeg')}" /> <a href="${entry.link}" class="post-graphics" target="_blank"><img src="${entry.image}" /></a>
</a> %endif
<div class="post-name"> <div class="post-name">
<a href="">Opening Doors For Exceptional Students: 6.002x in Mongolia.</a> <a href="${entry.link}" target="_blank">${entry.title}</a>
<p class="post-date">7/12/2012</p> %if entry.summary:
</div> <p>${entry.summary}</p>
</article> %endif
<p class="post-date">${strftime("%m/%d/%y", entry.published_parsed)}</p>
<article>
<a href="#" class="post-graphics">
<img src="${static.url('images/laffont_temp.jpg')}" />
</a>
<div class="post-name">
<a href="">MIT Alumn. Philippe P. Laffont founder of Coatue Capital Management makes $1 million inaugural gift for edX</a>
<p class="post-date">7/12/2012</p>
</div>
</article>
<article>
<a href="#" class="post-graphics">
<img src="${static.url('images/brazilstory_blog_arthur.jpg')}" />
</a>
<div class="post-name">
<a href="">6.002x – Way beyond a learning experience</a>
<p class="post-date">7/12/2012</p>
</div> </div>
</article> </article>
%endfor
</section> </section>
<section class="press-links"> <section class="press-links">
<h3>Press Links:</h3> <h3>edX in the News:</h3>
<a href="${reverse('pressrelease')}">The edX Press Release</a> ##<a href="${reverse('pressrelease')}">The edX Press Release</a>
<a target="_blank" href="http://www.nytimes.com/2012/07/20/education/edlife/anant-agarwal-discusses-free-online-courses-offered-by-a-harvard-mit-partnership.html">New York Times</a>,
<a target="_blank" href="http://www.bostonglobe.com/magazine/2012/07/14/anant-agarwal-believes-online-education-from-mit-and-harvard-should-available-all/Af0kX44dPqpBKRV2IOSjPP/story.html"target="_blank" >Boston Globe</a>,
<a target="_blank" href="http://www.huffingtonpost.co.uk/2012/06/20/harvard-and-mit-create-edx-free-university-courses_n_1612143.html?utm_hp_ref=uk">Huffington Post</a>,
<a target="_blank" href="http://gigaom.com/cloud/everybody-codes/">GigaOM</a>,
<a target="_blank" href="http://web.mit.edu/newsoffice/2012/mitx-edx-first-course-recap-0716.html">MIT News</a>,
<a target="_blank" href="http://spectrum.ieee.org/at-work/education/review-mitxs-online-circuit-design-and-analysis-course">IEEE Spectrum</a>
</section> </section>
</section> </section>
</section> </section>
......
<%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>
......
<!-- TODO: http://docs.jquery.com/Plugins/Validation -->
<div id="login_div">
<header>
<h1>Log in to edX</h1>
<p class="no-account">If you don&rsquo;t have an account yet, <a href="#enroll" rel="leanModal">please enroll here</a></p>
</header>
<!--[if lte IE 9]>
<p class="ie-warning">You are using a browser that is not supported by <em>edX</em>, and you might not be able to complete pieces of the course. Please download the latest version of <a href="http://www.mozilla.org/en-US/firefox/new/">Firefox</a> or <a href="https://www.google.com/chrome">Chrome</a> to get the full experience.</p>
<![endif]-->
<form id="login_form" method="post">
<ol>
<li>
<label>E-mail*</label>
<input name="email" id="li_email" type="email" required>
</li>
<li>
<label>Password*</label>
<input name="password" id="li_password" type="password" required>
</li>
<li class="remember">
<label><input name="remember" id="remember" type="checkbox">Remember me</label>
</li>
</ol>
<input name="submit" id="login_button" type="submit" value="Log in">
</form>
<div class="lost-password">
<div id="lost_password"><a class="" rel="leanModal" href="#pwd_reset">Lost password?</a></div>
</div>
</div>
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<hr> <hr>
</header> </header>
<form id="login_form" method="post"> <form id="login_form" method="post" data-remote="true" action="/login">
<label>E-mail</label> <label>E-mail</label>
<input name="email" type="email" placeholder="E-mail"> <input name="email" type="email" placeholder="E-mail">
<label>Password</label> <label>Password</label>
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
<section class="login-extra"> <section class="login-extra">
<p> <p>
<span>Not enrolled? <a href="#signup-modal" class="close-login" rel="leanModal">Sign up.</a></span> <span>Not enrolled? <a href="#signup-modal" class="close-login" rel="leanModal">Sign up.</a></span>
<a href="#" class="pwd-reset">Forgot password?</a> <a href="#forgot-password-modal" rel="leanModal" class="pwd-reset">Forgot password?</a>
</p> </p>
</section> </section>
...@@ -39,35 +39,15 @@ ...@@ -39,35 +39,15 @@
<script type="text/javascript"> <script type="text/javascript">
(function() { (function() {
function getCookie(name) { $(document).delegate('#login_form', 'ajax:success', function(data, json, xhr) {
return $.cookie(name);
}
function postJSON(url, data, callback) {
$.ajax({type:'POST',
url: url,
dataType: 'json',
data: data,
success: callback,
headers : {'X-CSRFToken':getCookie('csrftoken')}
});
}
$('form#login_form').submit(function(e) {
e.preventDefault();
var submit_data = $('#login_form').serialize();
postJSON('/login',
submit_data,
function(json) {
if(json.success) { if(json.success) {
location.href="${reverse('dashboard')}"; location.href="${reverse('dashboard')}";
} else if($('#login_error').length == 0) {
$('#login_form').prepend('<div id="login_error">Email or password is incorrect.</div>');
} else { } else {
$('#login_error').stop().css("display", "block"); if($('#login_error').length == 0) {
$('#login_form').prepend('<div id="login_error" class="modal-form-error"></div>');
} }
$('#login_error').html(json.value).stop().css("display", "block");
} }
);
}); });
})(this) })(this)
</script> </script>
...@@ -4,79 +4,33 @@ ...@@ -4,79 +4,33 @@
<head> <head>
<%block name="title"><title>edX</title></%block> <%block name="title"><title>edX</title></%block>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:800italic,400,800' rel='stylesheet' type='text/css'> <link rel="icon" type="image/image/x-icon" href="${static.url('images/favicon.ico')}" />
<link rel="stylesheet" href="${static.url('css/vendor/jquery.treeview.css')}" type="text/css" media="all" />
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
<%static:css group='application'/> <%static:css group='application'/>
% endif
% if not settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
<link rel="stylesheet" href="/static/sass/application.css" type="text/css" media="all" / >
% endif
<script type="text/javascript" src="${static.url('js/vendor/jquery.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/jquery-ui.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/swfobject/swfobject.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/jquery.cookie.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/jquery.qtip.min.js')}"></script>
## TODO (cpennington): Remove this when we have a good way for modules to specify js to load on the page
## and in the wiki
<script type="text/javascript" src="${static.url('js/schematic.js')}"></script>
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
<%static:js group='application'/>
% endif
% if not settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
% for jsfn in [ '/static/%s' % x.replace('.coffee','.js') for x in settings.PIPELINE_JS['application']['source_filenames'] ]:
<script type="text/javascript" src="${jsfn}"></script>
% endfor
% endif
## codemirror
<link rel="stylesheet" href="/static/css/codemirror.css" type="text/css" media="all" />
<script type="text/javascript" src="${static.url('js/vendor/codemirror-compressed.js')}"></script>
## alternate codemirror
## <script type="text/javascript" src="${static.url('js/vendor/CodeMirror-2.25/lib/codemirror.js')}"></script>
## <script type="text/javascript" src="${static.url('js/vendor/CodeMirror-2.25/mode/xml/xml.js')}"></script>
## <script type="text/javascript" src="${static.url('js/vendor/CodeMirror-2.25/mode/python/python.js')}"></script>
## image input: for clicking on images (see imageinput.html)
<script type="text/javascript" src="${static.url('js/vendor/imageinput.js')}"></script>
## <script type="text/javascript">
## var codemirror_set = {}; // track all codemirror textareas, so they can be refreshed on page changes
## </script>
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="${static.url('js/html5shiv.js')}"></script> <%static:css group='ie-fixes'/>
<![endif]--> <![endif]-->
<%static:js group='main_vendor'/>
<%block name="headextra"/> <%block name="headextra"/>
<%include file="mathjax_include.html" />
<meta name="path_prefix" content="${MITX_ROOT_URL}"> <meta name="path_prefix" content="${MITX_ROOT_URL}">
</head> </head>
<body class="<%block name='bodyclass'/>"> <body class="<%block name='bodyclass'/>">
<%include file="navigation.html" /> <%include file="navigation.html" />
<!--[if lte IE 9]>
<p class="ie-warning">You are using a browser that is not supported by <em>edX</em>, and you might not be able to complete pieces of the course. Please download the latest version of <a href="http://www.mozilla.org/en-US/firefox/new/">Firefox</a> or <a href="https://www.google.com/chrome">Chrome</a> to get the full experience.</p>
<![endif]-->
<section class="content-wrapper"> <section class="content-wrapper">
${self.body()} ${self.body()}
</section> </section>
<%block name="bodyextra"/> <%block name="bodyextra"/>
<%include file="footer.html" /> <%include file="footer.html" />
<%block name="js_extra"/>
<script src="${static.url('js/my_courses_dropdown.js')}"></script>
<script src="${static.url('js/toggle_login_modal.js')}"></script>
<script src="${static.url('js/sticky_filter.js')}"></script>
<%static:js group='application'/>
<!--[if lt IE 9]>
<script src="${static.url('js/html5shiv.js')}"></script>
<![endif]-->
<%block name="js_extra"/>
</body> </body>
</html> </html>
<%! from django.core.urlresolvers import reverse %>
<%namespace name='static' file='static_content.html'/>
<!DOCTYPE html>
<html>
<head>
<title><%block name="title">MITx: MIT's new online learning initiative</%block></title>
<meta name="description" content="<%block name="description">MITx will offer a portfolio of MIT courses for free to a virtual community of learners around the world</%block>" />
<meta name="keywords" content="<%block name="keywords">MITx, online learning, MIT, online laboratory, education, learners, undergraduate, certificate</%block>" />
<!--link rel="stylesheet" href="${ settings.LIB_URL }jquery.treeview.css" type="text/css" media="all" /-->
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<script type="text/javascript" src="${static.url('js/jquery.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery-ui.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.leanModal.min.js')}"></script>
<!--script type="text/javascript" src="${static.url('js/swfobject/swfobject.js')}"></script-->
<!--script type="text/javascript" src="${static.url('js/jquery.treeview.js')}"></script-->
<!--script type="text/javascript" src="${static.url('js/video_player.js')}"></script-->
<!-- <script type="text/javascript" src="${static.url('js/schematic.js')}"></script> -->
<script src="${static.url('js/html5shiv.js')}"></script>
<%block name="headextra"/>
<script type="text/javascript">
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function postJSON(url, data, callback) {
$.ajax({type:'POST',
url: url,
dataType: 'json',
data: data,
success: callback,
headers : {'X-CSRFToken':getCookie('csrftoken')}
});
}
</script>
</head>
<body>
<%block name="header">
<header class="announcement <%block name="header_class"/>">
<div class="anouncement-wrapper">
<%block name="header_nav">
<nav>
<h1><a href="http://mitx.mit.edu/">MITx</a></h1>
% if settings.COURSEWARE_ENABLED:
<%block name="login_area">
<a rel="leanModal" class="login" href="#login">Log In</a>
</%block>
% endif
</nav>
</%block>
<%block name="header_text">
<section>
<h1><em>MITx</em></h1>
<h2>MIT&rsquo;s new online learning initiative</h2>
</section>
</%block>
</div>
</header>
</%block>
${self.body()}
<%block name="bodyextra"/>
<footer>
<div class="footer-wrapper">
<p> Copyright &copy; 2012. MIT. <a href="${reverse('copyright')}">Some rights reserved.</a></p>
<ul>
<li><a href="${reverse('tos')}">Terms of Service</a></li>
<li><a href="${reverse('privacy')}">Privacy Policy</a></li>
<li><a href="${reverse('honor')}">Honor Code</a></li>
<li><a href="${reverse('help_edx')}">Help</a></li>
</ul>
<ul aria-label="Social Links" class="social">
<li class="linkedin">
<a href="http://www.linkedin.com/groups/Friends-Alumni-MITx-4316538">Linked In</a>
</li>
<li class="twitter">
<a href="https://twitter.com/#!/MyMITx">Twitter</a>
</li>
<li class="facebook">
<a href="http://www.facebook.com/pages/MITx/378592442151504">Facebook</a>
</li>
</ul>
</div>
</footer>
% if settings.COURSEWARE_ENABLED:
<div id="login" class="leanModal_box"><%include file="login.html" /></div>
% endif
<div id="pwd_reset" class="leanModal_box"><%include file="password_reset_form.html" /></div>
<div id="reset_done" class="leanModal_box"></div>
<script>
$(document).ready(function(){
/* Handles when the user tries to log in. Grabs form data. Does AJAX.
Either shows error, or redirects. */
$('form#login_form').submit(function(e) {
e.preventDefault();
var submit_data={};
$.each($("[id^=li_]"), function(index,value){
submit_data[value.name]=value.value;
});
submit_data["remember"] = ($('#remember').attr("checked")? true : false);
postJSON('/login',
submit_data,
function(json) {
if(json.success) {
location.href="/info";
} else if($('#login_error').length == 0) {
$('#login_form').prepend('<div id="login_error">Email or password is incorrect.</div>');
} else {
$('#login_error').stop().css("background-color", "#933").animate({ backgroundColor: "#333"}, 2000);
}
}
);
});
$('form#pwd_reset_form').submit(function(e) {
e.preventDefault();
var submit_data = {};
submit_data['email'] = $('#id_email').val();
postJSON('/password_reset/',
submit_data,
function(json){
if (json.success) {
$('#pwd_reset').html(json.value);
} else {
$('#pwd_error').html(json.error).stop().css("background-color", "#933").animate({ backgroundColor: "#333"}, 2000);
}
}
);
});
});
$(function(){
$("a[rel*=leanModal]").leanModal();
$("a.login").click(function(){
$("#login_form #li_email").focus();
});
$("a.enroll").click(function(){
$("#enroll_form #ca_email").focus();
});
});
</script>
<%block name="js_extra"/>
</body>
</html>
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
<li class="primary"> <li class="primary">
<a href="#" class="dropdown">&#9662</a> <a href="#" class="dropdown">&#9662</a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="#">Account Settings</a></li> ## <li><a href="#">Account Settings</a></li>
<li><a href="${reverse('help')}">Help</a></li> <li><a href="${reverse('help_edx')}">Help</a></li>
<li><a href="${reverse('logout')}">Log Out</a></li> <li><a href="${reverse('logout')}">Log Out</a></li>
</ul> </ul>
</li> </li>
...@@ -35,9 +35,8 @@ ...@@ -35,9 +35,8 @@
<ol class="guest"> <ol class="guest">
<li class="secondary"> <li class="secondary">
<a href="${reverse('about_edx')}">About</a> <a href="${reverse('about_edx')}">About</a>
<a href="#">Blog</a> <a href="http://edxonline.tumblr.com/">Blog</a>
<a href="${reverse('jobs')}">Jobs</a> <a href="${reverse('jobs')}">Jobs</a>
<a href="/t/contact.html">Contact</a>
<a href="#login-modal" id="login" rel="leanModal">Log In</a> <a href="#login-modal" id="login" rel="leanModal">Log In</a>
</li> </li>
<li class="primary"> <li class="primary">
...@@ -51,4 +50,5 @@ ...@@ -51,4 +50,5 @@
%if not user.is_authenticated(): %if not user.is_authenticated():
<%include file="login_modal.html" /> <%include file="login_modal.html" />
<%include file="signup_modal.html" /> <%include file="signup_modal.html" />
<%include file="forgot_password_modal.html" />
%endif %endif
<h1>Password reset</h1>
<p>Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one.</p>
<form id="pwd_reset_form">
<div id="pwd_error"></div>
<label for="id_email">E-mail address:</label>
<input id="id_email" type="email" name="email" maxlength="75" />
<input type="submit" id="pwd_reset_button" value="Reset my password" />
</form>
<%! 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'/>
<%inherit file="../main.html" />
<%block name="js_extra"> <%block name="js_extra">
% if not registered:
%if user.is_authenticated():
## If the user is authenticated, clicking the enroll button just submits a form
<script type="text/javascript">
(function() {
$(".register").click(function() {
$("#class_enroll_form").submit();
});
$(document).delegate('#class_enroll_form', 'ajax:success', function(data, json, xhr) {
if(json.success) {
location.href="${reverse('dashboard')}";
}
});
})(this)
</script>
%else:
## If the user is not authenticated, clicking the enroll button pops up the register
## field. We also slip in the registration fields into the login/register fields so
## the user is automatically registered after logging in / registering
<script type="text/javascript">
(function() {
$(".register").click(function() {
if ($("#login_form .enroll_fieldset").length === 0) {
$("#login_form").append( $(".enroll_fieldset").first().clone() );
}
if ($("#register_form .enroll_fieldset").length === 0) {
$("#register_form").append( $(".enroll_fieldset").first().clone() );
}
});
})(this)
</script>
%endif
%endif
<script src="${static.url('js/course_info.js')}"></script> <script src="${static.url('js/course_info.js')}"></script>
</%block> </%block>
<%inherit file="../main.html" />
<%block name="title"><title>About ${course.number}</title></%block>
<section class="course-info"> <section class="course-info">
<header class="course-profile"> <header class="course-profile">
<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")}<a href="${reverse('university_profile', args=[course.org])}">${get_course_about_section(course, "university")}</a></h1>
</hgroup> </hgroup>
<div class="main-cta"> <div class="main-cta">
<a href="${reverse('enroll', args=[course.id])}" class="register">Register</a> %if user.is_authenticated():
%if registered:
<span class="register disabled">You are registered for this course (${course.number}).</span>
%else:
<a href="#" class="register">Register for ${course.number}</a>
%endif
%else:
<a href="#signup-modal" class="register" rel="leanModal" data-notice='You must Sign Up or <a href="#login-modal" rel="leanModal">Log In</a> to enroll.'>Register for ${course.number}</a>
%endif
</div> </div>
</section> </section>
% 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>
%else:
<div class="media">
<div class="hero">
<img src="${course_image_url(course)}" />
</div>
</div>
% endif
</div> </div>
</header> </header>
...@@ -40,7 +98,7 @@ ...@@ -40,7 +98,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>
...@@ -49,23 +107,35 @@ ...@@ -49,23 +107,35 @@
<header> <header>
<div class="social-sharing"> <div class="social-sharing">
<div class="sharing-message">Share with friends and family!</div> <div class="sharing-message">Share with friends and family!</div>
<a href="#" class="share"> <a href="http://twitter.com/intent/tweet?text=I+just+registered+for+${course.number}+${get_course_about_section(course, 'title')}+through+@edxonline:+http://edx.org/${reverse('about_course', args=[course.id])}" class="share">
<img src="${static.url('images/twitter-sharing.png')}"> <img src="${static.url('images/social/twitter-sharing.png')}">
</a> </a>
<a href="#" class="share"> <a href="http://www.facebook.com/EdxOnline" class="share"> <img src="${static.url('images/social/facebook-sharing.png')}">
<img src="${static.url('images/facebook-sharing.png')}">
</a> </a>
<a href="#" class="share"> <a href="mailto:?subject=Take%20a%20course%20with%20edX%20online&body=I%20just%20registered%20for%20${course.number}%20${get_course_about_section(course, 'title')}%20through%20edX:+http://edx.org/${reverse('about_course', args=[course.id])}" class="share">
<img src="${static.url('images/email-sharing.png')}"> <img src="${static.url('images/social/email-sharing.png')}">
</a> </a>
</div> </div>
</header> </header>
<ol class="important-dates"> <ol class="important-dates">
<li><div class="icon start-icon"></div><p>Classes Start</p><span class="start-date">7/12/12</span></li> <li><div class="icon course-number"></div><p>Course Number</p><span class="course-number">${course.number}</span></li>
##<li><div class="icon final-icon"></div><p>Final Exam</p><span class="final-date">12/09/12</span></li> <li><div class="icon start"></div><p>Classes Start</p><span class="start-date">${course.start_date_text}</span></li>
##<li><div class="icon length-icon"></div><p>Course Length</p><span class="course-length">15 weeks</span></li>
<li><div class="icon number-icon"></div><p>Course Number</p><span class="course-number">${course.number}</span></li> ## End date should come from course.xml, but this is a quick hack
% if get_course_about_section(course, "end_date"):
<li><div class="icon end"></div><p>Classes End</p><span class="final-date">${get_course_about_section(course, "end_date")}</span></li>
% endif
% if get_course_about_section(course, "effort"):
<li><div class="icon effort"></div><p>Estimated Effort</p><span class="start-date">${get_course_about_section(course, "effort")}</span></li>
% endif
##<li><div class="icon length"></div><p>Course Length</p><span class="course-length">15 weeks</span></li>
% if get_course_about_section(course, "prerequisites"):
<li class="prerequisites"><div class="icon prereq"></div><p>Prerequisites</p><span class="start-date">${get_course_about_section(course, "prerequisites")}</span></li>
% endif
</ol> </ol>
</section> </section>
</section> </section>
...@@ -73,4 +143,19 @@ ...@@ -73,4 +143,19 @@
</section> </section>
</section> </section>
%if not registered:
<div style="display: none;">
<form id="class_enroll_form" method="post" data-remote="true" action="${reverse('change_enrollment')}">
<fieldset class="enroll_fieldset">
<input name="course_id" type="hidden" value="${course.id}">
<input name="enrollment_action" type="hidden" value="enroll">
</fieldset>
<div class="submit">
<input name="submit" type="submit" value="enroll">
</div>
</form>
</div>
%endif
<%include file="../video_modal.html" /> <%include file="../video_modal.html" />
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
%> %>
<%block name="headextra"> <%block name="js_extra">
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script>
...@@ -49,26 +49,6 @@ $(function() { ...@@ -49,26 +49,6 @@ $(function() {
} }
}); });
$("#change_language").click(function() {
$(this).hide();
log_event("profile", {"type":"language_show", "old":$("#language_sub").text()});
if(lang) {
lang=false;
$("#language_sub").html('<form>'+'<input id="id_lang_text" type="text" name="lang_text" />'+
'<input type="submit" id="change_lang_button" value="Save" />'+'</form>');
$("#change_lang_button").click(function() {
$("#change_language").show();
postJSON('/change_setting', {'language':$("#id_lang_text").attr("value")}, function(json) {
$("#language_sub").text(json.language);
lang=true;
$("#description").html("");
log_event("profile", {"type":"language_change", "new":json.language});
});
});
}
});
$('#change_password').click(function(){ $('#change_password').click(function(){
$('.modal').trigger('click'); $('.modal').trigger('click');
log_event("profile", {"type":"password_show"}); log_event("profile", {"type":"password_show"});
...@@ -207,9 +187,6 @@ $(function() { ...@@ -207,9 +187,6 @@ $(function() {
Location: <div id="location_sub">${location}</div><div id="description"></div> <a href="#" id="change_location" aria-label="Edit Location">Edit</a> Location: <div id="location_sub">${location}</div><div id="description"></div> <a href="#" id="change_location" aria-label="Edit Location">Edit</a>
</li> </li>
<li> <li>
Language: <div id="language_sub">${language}</div> <a href="#" id="change_language" aria-label="Edit Language">Edit</a>
</li>
<li>
Password reset Password reset
<input id="id_email" type="hidden" name="email" maxlength="75" value="${email}" /> <input id="id_email" type="hidden" name="email" maxlength="75" value="${email}" />
<input type="submit" id="pwd_reset_button" value="Reset" aria-label="Reset Password" /> <input type="submit" id="pwd_reset_button" value="Reset" aria-label="Reset Password" />
...@@ -234,10 +211,10 @@ $(function() { ...@@ -234,10 +211,10 @@ $(function() {
<form id="change_name_form"> <form id="change_name_form">
<div id="change_name_error"> </div> <div id="change_name_error"> </div>
<fieldset> <fieldset>
<p>To uphold the credibility of edX certificates, name changes must go through an approval process. A member of the course staff will review your request, and if approved, update your information. Please allow up to a week for your request to be processed. Thank you.</p> <p>To uphold the credibility of <span class="edx">edX</span> certificates, name changes must go through an approval process. A member of the course staff will review your request, and if approved, update your information. Please allow up to a week for your request to be processed. Thank you.</p>
<ul> <ul>
<li> <li>
<label>Enter your desired full name, as it will appear on the edX Certificate: </label> <label>Enter your desired full name, as it will appear on the <span class="edx">edX</span> Certificate: </label>
<input id="new_name_field" value="" type="text" /> <input id="new_name_field" value="" type="text" />
</li> </li>
<li> <li>
...@@ -278,7 +255,7 @@ $(function() { ...@@ -278,7 +255,7 @@ $(function() {
</div> </div>
<div id="deactivate-account" class="leanModal_box"> <div id="deactivate-account" class="leanModal_box">
<h1>Deactivate edX Account</h1> <h1>Deactivate <span class="edx">edX</span> Account</h1>
<p>Once you deactivate you&rsquo;re MIT<em>x</em> account you will no longer recieve updates and new class announcements from MIT<em>x</em>.</p> <p>Once you deactivate you&rsquo;re MIT<em>x</em> account you will no longer recieve updates and new class announcements from MIT<em>x</em>.</p>
<p>If you&rsquo;d like to still get updates and new class announcements you can just <a href="#unenroll" rel="leanModal">unenroll</a> and keep your account active.</p> <p>If you&rsquo;d like to still get updates and new class announcements you can just <a href="#unenroll" rel="leanModal">unenroll</a> and keep your account active.</p>
......
<h2>Thanks For Registering!</h2>
<p class='activation-message'>Your account is not active yet. An activation link has been sent to <strong>${ email }</strong>, along with
instructions for activating your account.</p>
<%! from django.core.urlresolvers import reverse %>
<%inherit file="../main.html" />
<%namespace name='static' file='../static_content.html'/>
<section class="container activation">
<section class="message">
%if not already_active:
<h1 class="valid">Activation Complete!</h1>
%else:
<h1>Account already active!</h1>
%endif
<hr class="horizontal-divider">
<p>
%if not already_active:
Thanks for activating your account.
%else:
This account has already been activated.
%endif
%if user_logged_in:
Visit your <a href="${reverse('dashboard')}">dashboard</a> to see your courses.
%else:
You can now <a href="#login-modal" rel="leanModal">login</a>.
%endif
</p>
</section>
</section>
<%! from django.core.urlresolvers import reverse %> <%! from django.core.urlresolvers import reverse %>
<%inherit file="main.html" /> <%inherit file="../main.html" />
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<section class="container activation"> <section class="container activation">
......
...@@ -16,33 +16,51 @@ ...@@ -16,33 +16,51 @@
<body> <body>
{% block content %} <header class="global" aria-label="Global Navigation">
<section class="outside-app"> <nav>
<h1 class="logo"><a href="${reverse('root')}"></a></h1>
</nav>
</header>
{% if validlink %} {% block content %}
<section class="password-reset">
<h1>Enter new password</h1> {% if validlink %}
<p>Please enter your new password twice so we can verify you typed it in correctly.</p> <header>
<h2>Enter new password</h2>
<hr>
</header>
<form action="" method="post">{% csrf_token %} <p>Please enter your new password twice so we can verify you typed it in correctly.</p>
{{ form.new_password1.errors }}
<p class="aligned wide"><label for="id_new_password1">New password:</label>{{ form.new_password1 }}</p>
{{ form.new_password2.errors }}
<p class="aligned wide"><label for="id_new_password2">Confirm password:</label>{{ form.new_password2 }}</p>
<p><input type="submit" value="Change my password" /></p>
</form>
{% else %} <form action="" method="post">{% csrf_token %}
{{ form.new_password1.errors }}
<label for="id_new_password1">New password:</label>
{{ form.new_password1 }}
<h1>Password reset unsuccessful</h1> {{ form.new_password2.errors }}
<label for="id_new_password2">Confirm password:</label>
{{ form.new_password2 }}
<p>The password reset link was invalid, possibly because the link has already been used. Please request a new password reset.</p> <div class="submit">
<input type="submit" value="Change my password" />
</div>
</form>
{% endif %} {% else %}
</section> <header>
{% endblock %} <h1>Password reset unsuccessful</h1>
<hr>
</header>
<p>The password reset link was invalid, possibly because the link has already been used. Please request a new password reset.</p>
{% endif %}
</section>
{% endblock %}
</body> </body>
</html> </html>
<h1>Password reset successful</h1> <header>
<h2>Password reset successful</h2>
<hr>
</header>
<p>We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly.</p> <div class="message">
<p>We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly.</p>
</div>
<header>
<h2>Thanks For Registering!</h2>
<hr>
</header>
<p class='activation-message'>Please check your email. An activation link has been sent to <strong>${ email }</strong>, along with
instructions for activating your account.</p>
<%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 django_countries.countries import COUNTRIES %>
<%! from student.models import UserProfile %>
<%! from datetime import date %>
<%! import calendar %>
<section id="signup-modal" class="modal signup-modal"> <section id="signup-modal" class="modal signup-modal">
<div class="inner-wrapper"> <div class="inner-wrapper">
<div id="enroll"> <div id="register">
<header> <header>
<h2>Sign Up for edX</h2> <h2>Sign Up for <span class="edx">edX</span></h2>
<hr> <hr>
</header> </header>
<form id="enroll_form" method="post"> <form id="register_form" method="post" data-remote="true" action="/create_account">
<div id="enroll_error" name="enroll_error"></div> <div class="notice"></div>
<label>E-mail</label> <div id="register_error" class="modal-form-error" name="register_error"></div>
<input name="email" type="email" placeholder="E-mail"> <div id="register_error" name="register_error"></div>
<label>Password</label>
<input name="password" type="password" placeholder="Password"> <div class="input-group">
<label>Public Username</label> <label>E-mail*</label>
<input name="username" type="text" placeholder="Public Username"> <input name="email" type="email" placeholder="E-mail*">
<label>Password*</label>
<input name="password" type="password" placeholder="Password*">
<label>Public Username*</label>
<input name="username" type="text" placeholder="Public Username*">
<label>Full Name</label> <label>Full Name</label>
<input name="name" type="text" placeholder="Full Name"> <input name="name" type="text" placeholder="Full Name*">
<label>Your Location</label> </div>
<input name="location" type="text" placeholder="Your Location">
<label>Preferred Language</label> <div class="input-group">
<input name="language" type="text" placeholder="Preferred Language"> <section class="citizenship">
<label>Ed. completed</label>
<div class="input-wrapper">
<select name="level_of_education">
<option value="">--</option>
%for code, ed_level in UserProfile.LEVEL_OF_EDUCATION_CHOICES:
<option value="${code}">${ed_level}</option>
%endfor
</select>
</div>
</section>
<section class="gender">
<label>Gender</label>
<div class="input-wrapper">
<select name="gender">
<option value="">--</option>
%for code, gender in UserProfile.GENDER_CHOICES:
<option value="${code}">${gender}</option>
%endfor
</select>
</div>
</section>
<section class="gender">
<label>Year of birth</label>
<div class="input-wrapper">
<select name="year_of_birth">
<option value="">--</option>
%for year in UserProfile.VALID_YEARS:
<option value="${year}">${year}</option>
%endfor
</select>
##<input name="year_of_birth" type="text" placeholder="Year of birth">
</div>
</section>
<label>Mailing address</label>
<textarea name="mailing_address" placeholder="Mailing address"></textarea>
<label>Goals in signing up for edX</label>
<textarea name="goals" placeholder="Goals in signing up for edX"></textarea>
</div>
<div class="input-group">
<label class="terms-of-service"> <label class="terms-of-service">
<input name="terms_of_service" type="checkbox" value="true"> <input name="terms_of_service" type="checkbox" value="true">
I agree to the I agree to the
<a href="${reverse('tos')}">Terms of Service</a> <a href="${reverse('tos')}" target="_blank">Terms of Service</a>*
</label> </label>
<label class="honor-code"> <label class="honor-code">
<input name="honor_code" type="checkbox" value="true"> <input name="honor_code" type="checkbox" value="true">
I agree to the I agree to the
<a href="${reverse('honor')}" target="blank">Honor Code</a> <a href="${reverse('honor')}" target="_blank">Honor Code</a>*
</label> </label>
</div>
<!--
-<div class="honor-code-summary">
- <ul>
- <li>
- <p>Complete all mid-terms and final exams with only my own work.</p>
- </li>
- <li>
- <p>Maintain only one account, and not share the username or password.</p>
- </li>
- <li>
- <p>Not engage in any activity that would dishonestly improve my results, or improve or hurt those of others.</p>
- </li>
- <li>
- <p>Not post answers to problems that are being used to assess student performance.</p>
- </li>
- </ul>
- <hr>
-</div>
-->
<div class="submit"> <div class="submit">
<input name="submit" type="submit" value="Create My Account"> <input name="submit" type="submit" value="Create My Account">
...@@ -77,34 +111,12 @@ ...@@ -77,34 +111,12 @@
<script type="text/javascript"> <script type="text/javascript">
(function() { (function() {
function getCookie(name) { $(document).delegate('#register_form', 'ajax:success', function(data, json, xhr) {
return $.cookie(name);
}
function postJSON(url, data, callback) {
$.ajax({type:'POST',
url: url,
dataType: 'json',
data: data,
success: callback,
headers : {'X-CSRFToken':getCookie('csrftoken')}
});
}
$('form#enroll_form').submit(function(e) {
e.preventDefault();
var submit_data = $('#enroll_form').serialize();
postJSON('/create_account',
submit_data,
function(json) {
if(json.success) { if(json.success) {
$('#enroll').html(json.value); location.href="${reverse('dashboard')}";
} else { } else {
$('#enroll_error').html(json.value).stop().css("display", "block"); $('#register_error').html(json.value).stop().css("display", "block");
}
} }
);
}); });
})(this) })(this)
</script> </script>
...@@ -8,9 +8,13 @@ ...@@ -8,9 +8,13 @@
from simplewiki.views import wiki_reverse from simplewiki.views import wiki_reverse
%> %>
<%block name="headextra"> <%block name="js_extra">
<script type="text/javascript" src="${static.url('js/simplewiki-AutoSuggest_c_2.0.js')}"></script> <script type="text/javascript" src="${static.url('js/simplewiki-AutoSuggest_c_2.0.js')}"></script>
## TODO (cpennington): Remove this when we have a good way for modules to specify js to load on the page
## and in the wiki
<script type="text/javascript" src="${static.url('js/schematic.js')}"></script>
<script type="text/javascript"> <script type="text/javascript">
function set_related_article_id(s) { function set_related_article_id(s) {
document.getElementById('wiki_related_input_id').value = s.id; document.getElementById('wiki_related_input_id').value = s.id;
......
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<%block name="title"><title>404</title></%block>
<section class="outside-app"> <section class="outside-app">
<h1>Page not found</h1> <h1>Page not found</h1>
<p>The page that you were looking for was not found. Go back to the <a href="/">homepage</a> or let us know about any pages that may have been moved at <a href="mailto:technical@mitx.mit.edu">technical@mitx.mit.edu</a>.</p> <p>The page that you were looking for was not found. Go back to the <a href="/">homepage</a> or let us know about any pages that may have been moved at <a href="mailto:technical@edx.org">technical@edx.edu</a>.</p>
</section> </section>
<%inherit file="marketing.html" />
<%block name="login_area">
</%block>
<section class="subpage">
<div>
<h1>
More about 6.002x
</h1>
<h2> Answering common questions about the first course on <i>MITx</i>, the
Institute&rsquo;s online-learning initiative.</h2>
<p>
This set of questions and answers accompanies MIT&rsquo;s February 13,
2012, announcement regarding <i>MITx</i>&rsquo;s prototype course &mdash;
6.002x: Circuits and Electronics.
</p>
<h2> How do I register? </h2>
<p> We will have a link to a form where you can sign up for our database and mailing list shortly. Please check back in the next two weeks to this website for further instruction. </p>
<h2> Where can I find a list of courses available? When do the next classes begin? </h2>
<p> Courses will begin again in the Fall Semester (September). We anticipate offering 4-5 courses this Fall, one of which will be 6.002x again. The additional classes will be announced in early summer. </p>
<h2> I tried to register for the course, but it says the username
is already taken.</h2>
<p> The system only allows each username to be used once. Probably,
someone else already signed up with that username. Try a different,
more unique username. For example, try adding a random number to the
end.</p>
<h2> I forgot my password </h2>
<p> The log-in form will have a link to reset your password once the
course opens. </p>
<h2> The videos stall out </h2>
<p> You should confirm your internet connection is fast enough to stream
videos, and that Youtube is not blocked by your internet
provider. Since the videos are hosted by YouTube, we have no control
over most technical problems with video playback (aside from those
related specifically to our player). </p>
<p> You should also confirm you have a current version of Flash installed.
While our player supports YouTube's HTML5 API (which allows playback without
Flash), this support is experimental.</p>
<a name="othercourses" ></a>
<h2> I am interested in a different subject. What other courses do
you offer? </h2>
<p> 6.002x is the pilot course for MITx. While we plan to offer a
range of courses in the future, at present, 6.002x is the only course
available. Specific future offerings will be announced later. </p>
<a name="start" ></a>
<h2>How will I know that the course has started?</h2>
<p> The course will start on March 5. Check the website
mitx.mit.edu as the date approaches. A login button will appear on
the course website 6.002x.mitx.mit.edu on or slightly before March 5
so you can login, begin to get familiar with the site and start the
course.</p>
<a name="login" ></a>
<h2> I can't log in</h2>
<p> You will not be able to log into the course until either the
starting date, or shortly before. If you have problems logging in once
the course has started, please verify that you are using the latest
version of either Firefox or Google Chrome, and have JavaScript and
cookies enabled. </p>
<a name="schedule" ></a>
<h2> Does the class have a schedule?</h2>
<p> The lectures are on-line videos, and may be watched at your own
pace and schedule. The course will have fixed deadlines for homework
assignments and exams. </p>
<a name="enrollissues" ></a>
<h2> I just enrolled for the course. I have not received any form
of acknowledgement that I have enrolled.</h2>
<p> You should receive a single activation e-mail. If you did not, the
most common issues are:
<ul>
<li> Typo in e-mail address
<li> Old browser. We recommend downloading the current version of
Firefox or Chrome. The course requires a modern browser.
<li> JavaScript disabled
<li> Activation e-mail in spam folder. Check spam folder.
<li> Non-unique username. Try adding a random string at the end.
</ul>
<p>If you run into issues, try recreating your account. There is no need
to do anything about the old account, if any. If it is not activated
through the link in the e-mail, it will disappear later.
<a name="howdropcourse" ></a>
<h2> How do I drop the course?</h2>
<p> You do not have to do anything. You can simply stop working on the
course at any time you choose to do so.</p>
<a name="ifdropcourse" ></a>
<h2>What happens if I drop the course?</h2>
<p> For the prototype course, learners achieving grades of "A," "B,"
or "C" will receive an electronic Certificate of completion with the
learner's name and grade on it. If you receive a grade below a "C" or
do not complete the course, you will not receive a Certificate and no
grade record attaching your name to your participation in the class
will be disclosed outside of MITx. You can also choose to opt for a
no record at any time. However, the posts you make while enrolled in
the class will remain visible. </p>
<a name="whatismitx" ></a>
<h2>
What is <i>MITx</i>?</h2>
<p> MIT seeks through the development of <i>MITx</i> to improve
education both on the MIT campus and around the world.
<p> On campus, <i>MITx</i> will be coupled with an Institute-wide research
initiative on online teaching and learning. The online learning tools
that <i>MITx</i> develops will benefit the educational experience of
residential students by supplementing and reinforcing the classroom
and laboratory experiences.</p>
<p>
Beyond the MIT campus, <i>MITx</i> will endeavor to break down barriers to
education in two ways. First, it will offer the online teaching of MIT
courses to people around the world and the opportunity for able
learners to gain certification of mastery of MIT material. Second, it
will make freely available to educational institutions everywhere the
open-source software infrastructure on which <i>MITx</i> courses are based.
</p>
<p>
Since it launched OpenCourseWare 10 years ago, MIT has been committed
to using technology to improve and greatly widen access to
education. The launch of <i>MITx</i> represents a next step forward in that
effort.
</p>
<a name="differentcampus" ></a>
<h2>
What is 6.002x, and how is it different from the on-campus version of
6.002?
</h2>
<p>
At MIT, each course is assigned a number. All courses in the
Department of Electrical Engineering and Computer Science (EECS) start
with the number 6, and 6.002 (also known as Circuits and Electronics)
is one of the introductory courses for EECS
undergraduates. <i>MITx</i>&rsquo;s 6.002x is modeled on the on-campus
version of 6.002.
</p>
<p>
The course introduces engineering in the context of the lumped
circuit abstraction. Topics covered include: resistive elements and
networks; independent and dependent sources; switches and MOS
transistors; digital abstraction; amplifiers; energy storage
elements; dynamics of first- and second-order networks; design in
the time and frequency domains; and analog and digital circuits and
applications.
</p>
<p>
6.002x is built on the content created collaboratively by MIT
professors Anant Agarwal and Jeffrey H. Lang for 6.002.
</p>
<a name="howenroll" ></a>
<h2>
How do I enroll in 6.002x?
</h2>
<p>
To enroll, visit <a href="http://mitx.mit.edu">http://mitx.mit.edu</a>
and sign up.
</p>
<a name="whenavailable" ></a>
<h2>
When will the course be available online?
</h2>
<p>
6.002x will become available online on Monday, March 5.
</p>
<a name="timeline" ></a>
<h2>
Do I need to follow a set timeline in completing 6.002x?
</h2>
<p>
In this pilot course of <i>MITx</i>, learners seeking a certificate will have
weekly deadlines for homework and labs. Similarly, the midterm and
final exam will be given within a specific range of days. However,
faster-paced learners can proceed multiple weeks ahead if they choose.
</p>
<a name="workrequired" ></a>
<h2>
How much time is required to complete the course?
</h2>
<p>
Students should expect to spend approximately 10 hours per week on the
course. However, the time taken by individual students might vary
considerably depending on background and skill.
</p>
<a name="instructors" ></a>
<h2>
Who are the instructors for 6.002x?
</h2>
<p>
There are four instructors for 6.002x: Anant Agarwal, Chris Terman,
Gerald Sussman and Piotr Mitros. The team also includes several
teaching assistants (TAs).
</p>
<a name="worklike" ></a>
<h2>
What is the work like in 6.002x?
</h2>
<p>
Students taking 6.002x will have weekly video lectures, readings from
the textbook, practice exercises and homework; design and laboratory
exercises are also significant components of the course. The course
will also provide additional tutorial material. There will be a
midterm and a final exam. An interactive laboratory playground will
also be made available for students to experiment creatively.
</p>
<p>
In general, for any given week, learners are expected to work through
a couple of lecture sequences containing a few videos (each 5 to 10
minutes in length) and a few interactive practice exercises. Learners
can also read appropriate parts of the textbook linked to the
videos. Lab and homework exercises will round out the week. Tutorials
are also provided as additional reference material.
</p>
<a name="questionsduringcourse" ></a>
<h2>
What if I have a question during the course?
</h2>
<p>
The course will include a discussion forum for learners to ask
questions, to post answers, and for discussions. Several helpful
documents, FAQs, tutorials and videos on using the various components
of the course will also be provided.
</p>
<a name="collaboration" ></a>
<h2>
Will 6.002x offer any means for collaboration among online learners?
</h2>
<p>
Yes. 6.002x will offer modest support for collaborative work through a
prototype wiki and discussion forum.
</p>
<a name="prereqs" ></a>
<h2>
Are there prerequisites to take the course?
</h2>
<p>
While <i>MITx</i> courses are open to all, there are some skills required to
succeed in taking the course.
</p>
<p>
In 6.002x, students are encouraged to have the knowledge obtained from
a college-level physics course in electricity and
magnetism (or from an advanced secondary-education course in electricity and magnetism, as with an Advanced Placement course in the United States). Students must know basic calculus and linear algebra, and
have some basic background in differential equations.
</p>
<p>
Since more advanced mathematics will not show up until the second half
of the course, the first half of the course will include an optional
remedial differential equations component for students with weaker
math backgrounds.
</p>
<a name="cost" ></a>
<h2>
How much does the course cost?
</h2>
<p>
All of the courses on <i>MITx</i> will be free of charge. Those who have the
ability and motivation to demonstrate mastery of content can receive a
credential for a modest fee. For this prototype course, the fee for a
credential will be waived.
</p>
<a name="credential" ></a>
<h2>
What is a credential?
</h2>
<p>
Any learner who successfully completes 6.002x will receive an
electronic certificate indicating a grade. This certificate will
indicate that you earned it from <i>MITx</i>&rsquo;s pilot course. In
this prototype version, <i>MITx</i> will not require that you be
tested in a testing center or otherwise have your identity certified
in order to receive this certificate. MITx certificates are not
planned to count towards MIT course credit.
</p>
<a name="whograding" ></a>
<h2>
Who is grading the course?
</h2>
<p>
<i>MITx</i> courses will use automated technologies to check student work
including practice exercises, homework assignments, labs and exams.
</p>
<a name="whatpassing" ></a>
<h2>
What is a passing grade?
</h2>
<p>
Grading schemes for each course will be announced with the
course. 6.002x will be graded on an absolute scale. The components
affecting a student&rsquo;s grade and the grade thresholds will be
posted on the course website when the course comes online.
</p>
<a name="textbook" ></a>
<h2>
Do I need to buy a textbook?
</h2>
<p>
The course uses the textbook Foundations of Analog and Digital
Electronic Circuits, by Anant Agarwal and Jeffrey H. Lang. Morgan
Kaufmann Publishers, Elsevier, July 2005. Relevant sections will be
provided electronically as part of the online course. While the
textbook is recommended, it is not required. The electronic text is
provided for personal use in connection with this course only. The
copyright for the book is owned by Elsevier. The book can be purchased
on <a href="http://www.amazon.com/exec/obidos/ASIN/1558607358/ref=nosim/mitopencourse-20" target="_blank">Amazon</a>.
</p>
<a name="technicalrequirements" ></a>
<h2>
Do I need to have special software to access 6.002x?
</h2>
<p>
No, you do not need special software to access 6.002x, as you will
access the online interactive course through your browser. The course
website was developed and tested primarily with the current version of
Google Chrome. We support current versions of Mozilla Firefox as
well. The video player is based on Youtube, and is designed to work
with Flash. We provide a partial non-Flash fallback for the video, but
this uses Google's experimental HTML5 API, and hence we cannot
guarantee those will continue to function for the duration of the
semester. We provide partial support for Internet Explorer, as well as
other browsers and tablets, but portions of the functionality will be
unavailable.
</p>
<a name="futurecourses" ></a>
<h2>
When will the next courses become available and what topics will they be on?
</h2>
<p>
Additional courses will be announced
on <a href="http://mitx.mit.edu">mitx.mit.edu</a> as they become
available. We expect this will happen in fall 2012. We also have
accounts
on <a href="https://twitter.com/#!/MyMITx">Twitter</a>, <a href="http://www.facebook.com/pages/MITx/378592442151504">Facebook</a>,
and <a href="http://www.linkedin.com/groups/Friends-Alumni-MITx-4316538">LinkedIn</a>.
</p>
</div>
</section>
<%inherit file="../marketing.html" />
<%block name="login_area">
</%block>
<section class="subpage">
<div>
<h1> <i>MITx</i> prototype course opens for enrollment&mdash;Online-learning
initiative&rsquo;s first offering, &lsquo;6.002x: Circuits and
Electronics,&rsquo; accepting registrants now.</h1>
<p> MIT News Office</p>
<p> In December,
MIT <a href="http://web.mit.edu/newsoffice/2011/mitx-education-initiative-1219.html">announced </a>the
launch of an online learning initiative called &ldquo;<i>MITx</i>.&rdquo;
Starting this week, interested learners can now enroll for free in the
initiative&rdquo;s prototype course -- 6.002x: Circuits and
Electronics.</p>
<p>Students can sign up for the course
at <a href="http://mitx.mit.edu">mitx.mit.edu</a>. The course will
officially begin on March 5 and run through June 8.</p>
<p> Modeled after MIT&rsquo;s 6.002 &mdash; an introductory course for
undergraduate students in MIT&rsquo;s Department of Electrical
Engineering and Computer Science (EECS) &mdash; 6.002x will introduce
engineering in the context of the lumped circuit abstraction, helping
students make the transition from physics to the fields of electrical
engineering and computer science. It will be taught by Anant Agarwal,
EECS professor and director of MIT's Computer Science and
Artificial Intelligence Laboratory (CSAIL); Chris Terman, CSAIL
co-director; EECS Professor Gerald Sussman; and CSAIL Research
Scientist Piotr Mitros.</p>
<blockquote>
<p>
&ldquo;We are very excited to begin <i>MITx</i> with this prototype
class,&rdquo; says MIT Provost L. Rafael Reif. &ldquo;We will use
this prototype course to optimize the tools we have built by
soliciting and acting on feedback from learners.&rdquo;
</p>
</blockquote>
<p>
To access the course, registered students will log in
at <a href="http://mitx.mit.edu">mitx.mit.edu</a>, where they will
find a course schedule, an e-textbook for the course, and a discussion
board. Each week, students will watch video lectures and
demonstrations, work with practice exercises, complete homework
assignments, and participate in an online interactive lab specifically
designed to replicate its real-world counterpart. Students will also
take exams and be able to check their grades as they progress in the
course. Overall, students can expect to spend approximately 10 hours
each week on the course.
</p>
<blockquote>
&ldquo;We invite you to join us for this pilot course of <i>MITx</i>,&rdquo;
Agarwal says. &ldquo;The 6.002x team of professors and teaching
assistants is excited to work with you on the discussion forum, and we
look forward to your feedback to improve the learning
experience.&rdquo;
</blockquote>
<p> <a href="http://mitx.mit.edu"> A video introduction to 6.002x can
be found here.</a></p>
<p> <a href="/6002x-faq.html"> A set of Frequently Asked Questions
about 6.002x can be found here.</a></p>
<p>
<a href="http://web.mit.edu/newsoffice/2011/mitx-faq-1219">
FAQs about <i>MITx</i> as a whole can be found here.
</a>
</p>
<p>
At the end of the prototype course, students who demonstrate their
mastery will be able to receive a certificate of completion for
free. In future <i>MITx</i> courses, students who complete the mastery
requirement on <i>MITx</i> will be able to receive the credential for a
modest fee.
</p>
<p>
Further courses are expected to become
available beginning in the fall.
</p>
<h3>
RELATED:
</h3>
<p>
<a href="/index.html">
6.002x course website
</a>
</p>
<p>
<a href="/6002x-faq.html">
6.002x FAQ
</a>
</p>
<h3>
ARCHIVE: &quot;MIT launches online learning initiative&quot;
</h3>
<a href="http://web.mit.edu/newsoffice/2011/mitx-education-initiative-1219.html">
http://web.mit.edu/newsoffice/2011/mitx-education-initiative-1219.html
</a>
<h3>
<i>MITx</i> website
</h3>
<a href="http://mitx.mit.edu">
http://mitx.mit.edu
</a>
<!--h3>
TAGS:
</h3>
<p>
<i>MITx</i>; students; education, teaching, academics; innovation and
invention; faculty; mit administration; learning; electrical
engineering and computer science; csail
</p-->
</div>
</section>
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<%block name="title"><title>About edX</title></%block>
<section class="container about"> <section class="container about">
<nav> <nav>
<a href="${reverse('about_edx')}" class="active">Vision</a> <a href="${reverse('about_edx')}" class="active">Vision</a>
...@@ -12,43 +14,44 @@ ...@@ -12,43 +14,44 @@
</nav> </nav>
<section class="vision"> <section class="vision">
<h2 class="mission-quote">“The mission of edX is to enhance human fulfillment worldwide through online learning, transforming education in quality, efficiency and scale through technology and research, for the benefit of campus-based students and the worldwide community of online learners.”</h2> ## <div class="our-mission">
## <div class="logo">
## <img src="${static.url('images/edx-logo-large-bw.png')}">
## </div>
## <h2 class="mission-quote">&ldquo;The mission of <span class="edx">edX</span> is to enhance human fulfillment worldwide through online ## learning, transforming education in quality, efficiency and scale through technology and research, for the benefit of campus-based ## students and the worldwide community of online learners.&rdquo;</h2>
## </div>
<section class="message left"> <section class="message left">
<div class="photo"> <div class="photo">
<img src="${static.url('images/about_1.jpg')}"> <img src="${static.url('images/about_1.jpg')}">
</div> </div>
<article> <article>
<h2>About edX</h2> <h2>About <span class="edx">edX</span></h2>
<p>EdX is a joint partnership between The Massachusetts Institute of Technology (MIT) and Harvard University to offer online learning to millions of people around the world. EdX offers Harvard and MIT classes online for free. Through this partnership, with other partners to follow, the institutions aim to extend their collective reach to build a global community of online students</p> <p>EdX is a not-for-profit enterprise of its founding partners Harvard University and the Massachusetts Institute of Technology that features learning designed specifically for interactive study via the web. Based on a long history of collaboration and their shared educational missions, the founders are creating a new distance-learning experience. Anant Agarwal, former Director of MIT's Computer Science and Artificial Intelligence Laboratory, serves as the first president of edX. Along with offering online courses, the institutions will use edX to research how students learn and how technology can transform learning&mdash;both on-campus and worldwide. EdX is based in Cambridge, Massachusetts and is governed by MIT and Harvard.</p>
<p>MIT’s Director of the Computer Science and Artificial Intelligence Laboratory Anant Agarwal serves as the first president of edX, and Harvard’s Faculty of Arts and Sciences Dean Michael D. Smith leads faculty in developing courses. Along with offering online courses, the institutions will use edX to research how students learn and how technology can facilitate teaching—both on-campus and online.</p>
<p>EdX is based on an open-source technological platform that provides interactive educational materials designed specifically for the web, and is available to anyone in the world with an internet connection.</p>
<p>EdX is a Cambridge-based not-for-profit, equally owned and funded by Harvard and MIT.</p>
</article> </article>
<hr class="fade-right-hr-divider"> <hr class="fade-right-hr-divider">
</section> </section>
<section class="message right"> <section class="message left">
<div class="photo"> <div class="photo">
<img src="${static.url('images/about-harvard.jpg')}"> <img src="${static.url('images/university/harvard/about-harvard.jpg')}">
</div> </div>
<article> <article>
<h2>Harvard University</h2> <h2>Harvard University</h2>
<p>Harvard University is devoted to excellence in teaching, learning, and research, and to developing leaders in many disciplines who make a difference globally. Harvard faculty are engaged with teaching and research to push the boundaries of human knowledge. For students who are excited to investigate the biggest issues of the 21st century, Harvard offers an unparalleled student experience and a generous financial aid program, with over $160 million awarded to more than 60% of our undergraduate students. The University has twelve degree-granting Schools in addition to the Radcliffe Institute for Advanced Study, offering a truly global education.</p> <p>Harvard University is devoted to excellence in teaching, learning, and research, and to developing leaders in many disciplines who make a difference globally. Harvard faculty are engaged with teaching and research to push the boundaries of human knowledge. The University has twelve degree-granting Schools in addition to the Radcliffe Institute for Advanced Study.</p>
<p>Established in 1636, Harvard is the oldest institution of higher education in the United States. The University, which is based in Cambridge and Boston, Massachusetts, has an enrollment of over 20,000 degree candidates, including undergraduate, graduate, and professional students. Harvard has more than 360,000 alumni around the world. <p>Established in 1636, Harvard is the oldest institution of higher education in the United States. The University, which is based in Cambridge and Boston, Massachusetts, has an enrollment of over 20,000 degree candidates, including undergraduate, graduate, and professional students. Harvard has more than 360,000 alumni around the world.</p>
Massachusetts Institute of Technology</p>
</article> </article>
<hr class="fade-left-hr-divider"> <hr class="fade-left-hr-divider">
</section> </section>
<section class="message left"> <section class="message left">
<div class="photo"> <div class="photo">
<img src="${static.url('images/about-mit.jpg')}"> <img src="${static.url('images/university/mit/about-mit.jpg')}">
</div> </div>
<article> <article>
<h2>Massachusetts Institute of Technology</h2> <h2>Massachusetts Institute of Technology</h2>
<p>The Massachusetts Institute of Technology — a coeducational, privately endowed research university founded in 1861 — is dedicated to advancing knowledge and educating students in science, technology, and other areas of scholarship that will best serve the nation and the world in the 21st century. The Institute has close to 1,000 faculty and 10,000 undergraduate and graduate students. It is organized into five Schools: Architecture and Urban Planning; Engineering; Humanities, Arts, and Social Sciences; Sloan School of Management; and Science.</p> <p>The Massachusetts Institute of Technology &mdash; a coeducational, privately endowed research university founded in 1861 &mdash; is dedicated to advancing knowledge and educating students in science, technology, and other areas of scholarship that will best serve the nation and the world in the 21st century. The Institute has close to 1,000 faculty and 10,000 undergraduate and graduate students. It is organized into five Schools: Architecture and Urban Planning; Engineering; Humanities, Arts, and Social Sciences; Sloan School of Management; and Science.</p>
<p>MIT's commitment to innovation has led to a host of scientific breakthroughs and technological advances. Seventy-eight MIT alumni, faculty, researchers and staff have won Nobel Prizes.</p> <p>MIT's commitment to innovation has led to a host of scientific breakthroughs and technological advances. Achievements of the Institute's faculty and graduates have included the first chemical synthesis of penicillin and vitamin A, the development of inertial guidance systems, modern technologies for artificial limbs, and the magnetic core memory that made possible the development of digital computers. 78 alumni, faculty, researchers and staff have won Nobel Prizes.</p>
<p>Current areas of research and education include neuroscience and the study of the brain and mind, bioengineering, cancer, energy, the environment and sustainable development, information sciences and technology, new media, financial technology, and entrepreneurship.</p> <p>Current areas of research and education include neuroscience and the study of the brain and mind, bioengineering, cancer, energy, the environment and sustainable development, information sciences and technology, new media, financial technology, and entrepreneurship.</p>
</article> </article>
</section> </section>
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<%block name="title"><title>Contact edX</title></%block>
<section class="container about"> <section class="container about">
<nav> <nav>
<a href="${reverse('about_edx')}">Vision</a> <a href="${reverse('about_edx')}">Vision</a>
...@@ -13,28 +15,20 @@ ...@@ -13,28 +15,20 @@
<section class="contact"> <section class="contact">
<div class="map"> <div class="map">
<img src="${static.url('images/edx-location.png')}"> <img src="${static.url('images/contact-page.jpg')}">
</div> </div>
<div class="contacts"> <div class="contacts">
<h2>Email Contacts</h2>
<ul>
<li><p>System-related questions: <a href="mailto:technical@mitx.mit.edu">technical@mitx.mit.edu</a></p></li>
<li><p>Content-related questions: <a href="mailto:content@mitx.mit.edu">content@mitx.mit.edu</a></p></li>
<li><p>Bug reports: <a href="mailto:bugs@mitx.mit.edu">bugs@mitx.mit.edu</a></p></li>
<li><p>Suggestions: <a href="mailto:suggestions@mitx.mit.edu">suggestions@mitx.mit.edu</a></p></li>
</ul>
<h2>Class Feedback</h2> <h2>Class Feedback</h2>
<p>We are always seeking feedback to improve our courses. If you are an enrolled student and have any questions, feedback, suggestions, or any other issues specific to a particular class, please post on the discussion forums of that class.</p> <p>We are always seeking feedback to improve our courses. If you are an enrolled student and have any questions, feedback, suggestions, or any other issues specific to a particular class, please post on the discussion forums of that class.</p>
<h2>General Inqueries and Feedback</h2> <h2>General Inquiries and Feedback</h2>
<p>If you have a general question about edX please email <a href="mailto:info@edx.org">info@edx.org</a>. To see if your question has already been answered, visit our <a href="${reverse('faq_edx')}">FAQ page</a>. Though we may not have a chance to respond to every email, we take all feedback into consideration.</p> <p>"If you have a general question about edX please email <a href="mailto:info@edx.org">info@edx.org</a>. To see if your question has already been answered, visit our <a href="${reverse('faq_edx')}">FAQ page</a>. You can also join the discussion on our <a href="http://www.facebook.com/EdxOnline">facebook page</a>. Though we may not have a chance to respond to every email, we take all feedback into consideration.</p>
<h2>Technical Inqueries and Feedback</h2> <h2>Technical Inquiries and Feedback</h2>
<p>If you have suggestions/feedback about the overall edX platform, or are facing general technical issues with the platform (e.g., issues with email addresses and passwords), you can reach us at <a href="mailto:technical@edx.org">technical@edx.org</a>. For technical questions, please make sure you are using a current version of Firefox or Chrome, and include browser and version in your e-mail, as well as screenshots or other pertinent details. If you find a bug or other issues, you can reach us at the following: <a href="mailto:bugs@edx.org">bugs@edx.org</a>.</p> <p>If you have suggestions/feedback about the overall edX platform, or are facing general technical issues with the platform (e.g., issues with email addresses and passwords), you can reach us at <a href="mailto:technical@edx.org">technical@edx.org</a>. For technical questions, please make sure you are using a current version of Firefox or Chrome, and include browser and version in your e-mail, as well as screenshots or other pertinent details. If you find a bug or other issues, you can reach us at the following: <a href="mailto:bugs@edx.org">bugs@edx.org</a>.</p>
<h2>Media</h2> <h2>Media</h2>
<p>Please visit our <a href="${reverse('faq_edx')}">media/press page</a> for more information. 
For any media or press enquiries, please email <a href="mailto:press@edx.org">press@edx.org</a>.</p> <p>Please visit our <a href="${reverse('press')}">media/press page</a> for more information. For any media or press enquiries, please email <a href="mailto:press@edx.org">press@edx.org</a>.</p>
<h2>Universities</h2> <h2>Universities</h2>
<p>If you are a university wishing to Collaborate or with questions about edX, please email <a href="mailto:university@edx.org">university@edx.org</a>.</p> <p>If you are a university wishing to Collaborate or with questions about edX, please email <a href="mailto:university@edx.org">university@edx.org</a>.</p>
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%block name="title"><title>Copyright</title></%block>
<section class="static-container copyright"> <section class="static-container copyright">
<h1> Licensing Information </h1> <h1> Licensing Information </h1>
<hr class="horizontal-divider"> <hr class="horizontal-divider">
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<%block name="title"><title>FAQ</title></%block>
<section class="container about"> <section class="container about">
<nav> <nav>
<a href="${reverse('about_edx')}">Vision</a> <a href="${reverse('about_edx')}">Vision</a>
...@@ -15,114 +17,86 @@ ...@@ -15,114 +17,86 @@
<section class="responses"> <section class="responses">
<section id="the-organization" class="category"> <section id="the-organization" class="category">
<h2>Category</h2> <h2>Organization</h2>
<article class="response"> <article class="response">
<h3>What is edX?</h3> <h3>What is edX?</h3>
<p>edX is a Cambridge-based not-for-profit, equally owned and governed by the Massachusetts Institute of Technology (MIT) and Harvard University to offer online learning to millions of people around the world. edX offers Harvard, MIT and Berkeley classes online for free. Through this partnership, with other partners to follow, the institutions aim to extend their collective reach to build a global community of online students.</p> <p>EdX is a not-for-profit enterprise, governed by the Massachusetts Institute of Technology (MIT) and Harvard University to offer online learning to on-campus students and to millions of people around the world. To do so, edX is building an open-source online learning platform and hosts an online web portal at <a href="www.edx.org">www.edx.org</a> for online education.</p>
<p>EdX currently offers HarvardX, <em>MITx</em> and BerkeleyX classes online for free. These institutions aim to extend their collective reach to build a global community of online students. Along with offering online courses, the three universities undertake research on how students learn and how technology can transform learning – both on-campus and online throughout the world.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>Why was edX established?</h3> <h3>What are "X Universities"?</h3>
<p>To transform learning and enhance education on campus and around the world:</p> <p>Harvard, MIT and UC Berkeley, as the first universities whose courses are delivered on the edX website, are "X Universities." The three institutions will work collaboratively to establish the X University Consortium, whose membership will expand to include additional X Universities as soon as possible. Each member of the consortium will offer courses on the edX platform as an X University. The gathering of many universities' educational content together on one site will enable learners worldwide to access the course content of any participating university from a single website, and to use a set of online educational tools shared by all participating universities.</p>
<ul>
<li><p>On campus, edX research will enhance our understanding of how students learn and how technologies can best be used as part of our larger efforts to improve teaching and learning.</p></li>
<li><p>Beyond our campuses, edX will expand access to education, allow for certificates of mastery to be earned by able learners.</p></li>
</ul>
</article> </article>
<article class="response"> <article class="response">
<h3>What are MITx, HarvardX and BerkeleyX?</h3> <h3>Why is UC Berkeley joining edX?</h3>
<p>Portfolios of MIT, Harvard and Berkeley online courses offered to learners around the world through edX.</p> <p>Like Harvard and MIT, UC Berkeley seeks to advance the edX mission "to enhance human fulfillment worldwide through online learning, transforming education in quality, efficiency and scale through technology and research, for the benefit of campus-based students and the worldwide community of online learners".</p>
<p>UC Berkeley shares the edX commitment to the not-for-profit and open-platform model as a way to transform learning and enhance education on campus and around the world and is providing significant new, open source software to the collaboration.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>What technology will edX use?</h3> <h3>What will UC Berkeley's direct participation entail?</h3>
<p>An open-source online learning platform that will feature teaching designed specifically for the web. Features will include: self-paced learning, online discussion groups, wiki-based collaborative learning, assessment of learning as a student progresses through a course, and online laboratories. The platform will also serve as a laboratory from which data will be gathered to better understand how students learn. Because it is open source, the platform will be continuously improved.</p> <p>UC Berkeley will begin by offering two courses on edX in Fall 2012, and will collaborate on the development of the technology platform. We will explore, experiment and innovate together.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>How is this different from what other universities are doing online?</h3> <h3>Why is edX only adding one X University?</h3>
<p>edX is a not-for-profit built by the shared educational missions of its founding partners, Harvard University and MIT. Also, a primary goal of edX is to improve teaching and learning on campus by supporting faculty in conducting significant research on how students learn.</p> <p>More than 120 universities from around the world have expressed interested in collaborating with edX since Harvard and MIT announced its creation in May. EdX is obsessed with quality and developing the best non-profit model for online education. In addition to providing online courses on the edX platform, the X University Consortium will be a forum in which members can share experiences around online learning.</p>
<p>EdX will actively explore the addition of other institutions from around the world to the X University platform based on a series of priorities, including, for example: adherence to the edX non-profit model; diversifying the geographic base of X Universities; and bringing together the world’s thought leaders in online education, among other criteria.</p>
</article>
<article class="response">
<h3>Who leads edX?</h3>
<p>Anant Agarwal, formerly Director of the Computer Science and Artificial Intelligence Laboratory at MIT, serves as the first president of edX, and edX is governed by a board consisting of key leaders from Harvard and MIT, along with Agarwal, as President of edX. UC Berkeley will participate on the board as the Chair of the X University Consortium.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>Who will lead edX?</h3> <h3>How may another university participate in edX?</h3>
<p>edX is governed by a board made up by key leaders from Harvard and MIT. MIT Professor Anant Agarwal, formerly Director of the Computer Science and Artificial Intelligence Laboratory at MIT, serves as the first president of edX.</p> <p>If you are from a university interested in discussing edX, please email <a href="mailto:university@edxonline.org">university@edxonline.org</a></p>
</article> </article>
</section> </section>
<section id="" class="category"> ##<section id="objectives" class="category">
<h2>Category</h2> ## <h2>Objectives</h2>
##</section>
<section id="students" class="category">
<h2>Students</h2>
<article class="response"> <article class="response">
<h3>Who can take edX courses? Will there be an admissions process?</h3> <h3>Who can take edX courses? Will there be an admissions process?</h3>
<p>edX will be available to anyone in the world with an internet connection, and in general, there will not be an admissions process.</p> <p>EdX will be available to anyone in the world with an internet connection, and in general, there will not be an admissions process.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>Will certificates be awarded?</h3> <h3>How may I apply to study with edX?</h3>
<p>Online learners who demonstrate mastery of subjects could earn a certificate of completion. Such certificates will be issued by edX under the name of the underlying X University from where the course originated, i.e. HarvardX, MITx or BerkeleyX.</p> <p>Simply complete the <a href="#signup-modal" rel="leanModal">sign up form</a>. Enrolling will create your unique student record in the edX database, allow you to register for classes, and to receive a certificate on successful completion.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>What will the scope of the online courses be? How many? Which faculty?</h3> <h3>Will certificates be awarded?</h3>
<p>Our goal is to offer a wide variety of courses across disciplines. There are currently seven courses planned for the Fall 2012 [Link to courses page].</p> <p>Yes. Online learners who demonstrate mastery of subjects can earn a certificate of completion. Certificates will be issued by edX under the name of the underlying X University from where the course originated, i.e. HarvardX, <em>MITx</em> or BerkeleyX. For the courses in fall 2012, those certificates will be free. There is plan to charge a modest fee for certificates in the future. Exact pricing has not been determined, and pricing may vary by student location, but a charge in the range of $100-$200 per course has been discussed.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>Will on-campus students at partner institutions be able to take these courses for credit?</h3> <h3>What will the scope of the online courses be? How many? Which faculty?</h3>
<p>No. Courses will not be offered for credit at partner universities. The online content will be used to extend and enrich on campus courses. Do we need to keep this?</p> <p>Our goal is to offer a wide variety of courses across disciplines. There are currently seven courses offered for <a href="${reverse('courses')}">Fall 2012.</a></p>
</article> </article>
<article class="response"> <article class="response">
<h3>Who is the learner? Domestic or international? Age range?</h3> <h3>Who is the learner? Domestic or international? Age range?</h3>
<p>Improving teaching and learning for students on our campuses is one of our primary goals. Beyond that, we don’t have a target group of potential learners, as the goal is to make these courses available to anyone in the world – from any demographic – who has interest in advancing their own knowledge. The only requirement is to have a computer with an internet connection. Add stats from first course – how many countries… age range.</p> <p>Improving teaching and learning for students on our campuses is one of our primary goals. Beyond that, we don’t have a target group of potential learners, as the goal is to make these courses available to anyone in the world – from any demographic – who has interest in advancing their own knowledge. The only requirement is to have a computer with an internet connection. More than 150,000 students from over 160 countries registered for <em>MITx</em>'s first course, 6.002x: Circuits and Electronics. The age range of students certified in this course was from 14 to 74 years-old.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>Many institutions are partnering in this space. Will other institutions be able to collaborate with edX?</h3> <h3>Will participating universities' standards apply to all courses offered on the edX platform?</h3>
<p>In July of 2012 edX announced the addition of the University of California Berkeley to the edX educational space. The gathering (or consortium) of many universities’ educational content together on one site will enable learners worldwide to access the course content of any participating university from a single website, and to use a set of online educational tools shared by all participating universities. We plan to add many more institutions to this growing online initiative. </p> <p>Yes: the reach changes exponentially, but the rigor remains the same.</p>
</article>
<article class="response">
<h3>Why is Berkeley joining edX? </h3>
<p>Like Harvard and MIT, Berkeley shares edX mission “to enhance human fulfillment worldwide through online learning, transforming education in quality, efficiency and scale through technology and research, for the benefit of campus-based students and the worldwide community of online learners”.</p>
<p>Berkeley shares edX commitment to the not-for-profit model as a way to transform learning and enhance education on campus and around the world.</p>
</article> </article>
</section> </section>
<section id="technology-platform" class="category"> <section id="technology-platform" class="category">
<h2>Category</h2> <h2>Technology Platform</h2>
<article class="response"> <article class="response">
<h3>What are the specific arrangements between Berkeley and edX? </h3> <h3>What technology will edX use?</h3>
<p>Berkeley will chair the to-be-formed X University consortium, which is the consortium of universities offering courses on the edX platform. As chair, Berkeley will also get a non-voting board seat on the edX board, currently comprised of the MIT and Harvard leaders, and the edX
president. Berkeley will collaborate with the edX development team on the common edX
platform, which will be released as open source.</p> <p>The edX open-source online learning platform will feature interactive learning designed specifically for the web. Features will include: self-paced learning, online discussion groups, wiki-based collaborative learning, assessment of learning as a student progresses through a course, and online laboratories. The platform will also serve as a laboratory from which data will be gathered to better understand how students learn. Because it is open source, the platform will be continuously improved by a worldwide community of collaborators.</p>
</article> <p>The first version of the technology was used in the first <em>MITx</em> course, 6.002x Circuits and Electronics, which launched in Spring, 2012.</p>
<article class="response">
<h3>What will Berkeley’s direct participation entail?</h3>
<p>Berkeley will offer two courses on edX in Fall 2012, and will be collaborating on the development of the technology platform. We will explore, experiment and innovate together.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>Will the partner university’s standards apply to edX programming?</h3> <h3>How is this different from what other universities are doing online?</h3>
<p>The reach changes exponentially, but the rigor remains the same.</p> <p>EdX is a not-for-profit enterprise built by the shared educational missions of its founding partners, Harvard University and MIT. The edX platform will be available as open source. Also, a primary goal of edX is to improve teaching and learning on campus by experimenting with blended models of learning and by supporting faculty in conducting significant research on how students learn.</p>
</article> </article>
<article class="response"> <article class="response">
<h3>How do you intend to test whether this approach is improving learning?</h3> <h3>How do you intend to test whether this approach is improving learning?</h3>
<p>edx institutions have assembled faculty who will look at data collection and analytical tools to assess results and the impact edX is having on learning.</p> <p>EdX institutions have assembled faculty who will study data collection and analytical tools to assess results and the impact edX is having on learning.</p>
</article>
<article class="response">
<h3>How may I apply to study with edX?</h3>
<p>Simply complete the online registration form here[link], or click on the "SIGN UP" tab at the top of this page). Enrolling will create your unique student record in the edX database, allows you to enroll in classes, and to receive a certificate on successful completion.</p>
</article>
<article class="response">
<h3>How may another University participate in edX?</h3>
<p>If you are from a university interested in discussing edX, please email university@edx.org</p>
</article> </article>
</section> </section>
...@@ -130,11 +104,13 @@ ...@@ -130,11 +104,13 @@
<nav class="categories"> <nav class="categories">
<a href="#organization">Organization</a> <a href="#organization">Organization</a>
<a href="#objectives">Objectives</a> ##<a href="#objectives">Objectives</a>
<a href="#students">Students</a> <a href="#students">Students</a>
<a href="#technology-platform">Technology Platform</a> <a href="#technology-platform">Technology Platform</a>
</nav> </nav>
</section> </section>
</section> </section>
%if user.is_authenticated():
<%include file="../signup_modal.html" />
%endif
...@@ -3,33 +3,22 @@ ...@@ -3,33 +3,22 @@
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%block name="title"><title>Help - MITx 6.002x</title></%block> <%block name="title"><title>edX Help</title></%block>
<section class="static-container help"> <section class="static-container help">
<h1>Help</h1> <h1>Help</h1>
<hr class="horizontal-divider"> <hr class="horizontal-divider">
<div class="inner-wrapper"> <div class="inner-wrapper">
<h2>Self-help</h2>
<ul>
<li><p>Read the <a href="${reverse('faq_edx')}">FAQ</a> carefully</p></li>
<li><p>Check the <a href="/info">course updates</a> -- we will announce major errors and issues there </p></li>
<li><p>Check whether the issues has been asked on the <a href="/discussion">discussion forums</a>, and if not, ask</p></li>
<li><p>Ask in the IRC channel (irc.mitx.mit.edu, channel #6002)]</p></li>
<li><p>Check the <a href="/info">course handouts.</a></p></li>
</ul>
<h2>Help email</h2> <h2>Help email</h2>
<p> If you can't solve your problems with self-help, we have several e-mail addresses set up:</p>
<ul> <ul>
<li><p>System-related questions: <a href="mailto:technical@mitx.mit.edu">technical@mitx.mit.edu</a></p></li> <li><p>System-related questions: <a href="mailto:technical@edx.org">technical@edx.org</a></p></li>
<li><p>Content-related questions: <a href="mailto:content@mitx.mit.edu">content@mitx.mit.edu</a></p></li> <li><p>Content-related questions: <a href="mailto:content@edx.org">content@edx.org</a></p></li>
<li><p>Bug reports: <a href="mailto:bugs@mitx.mit.edu">bugs@mitx.mit.edu</a></p></li> <li><p>Bug reports: <a href="mailto:bugs@edx.org">bugs@edx.org</a></p></li>
<li><p>Suggestions: <a href="mailto:suggestions@mitx.mit.edu">suggestions@mitx.mit.edu</a></p></li> <li><p>Suggestions: <a href="mailto:suggestions@edx.org">suggestions@edx.org</a></p></li>
</ul> </ul>
<p>Please bear in mind that while we read them, we do not expect to have time to respond to all e-mails. For technical questions, please make sure you are using the latest version of <a href="http://www.mozilla.org/en-US/firefox/new/">Firefox</a> or <a href="https://www.google.com/chrome/">Chrome</a>, and include browser and version in your e-mail, as well as screenshots or other pertinent details.</p>
</div> </div>
</section> </section>
...@@ -4,8 +4,10 @@ ...@@ -4,8 +4,10 @@
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%block name="title"><title>Honor Code</title></%block>
<section class="static-container honor-code"> <section class="static-container honor-code">
<h1> Collaboration Policy </h1> <h1> Honor Code </h1>
<hr class="horizontal-divider"> <hr class="horizontal-divider">
<div class="inner-wrapper"> <div class="inner-wrapper">
......
...@@ -2,18 +2,30 @@ ...@@ -2,18 +2,30 @@
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<%block name="title"><title>Jobs</title></%block>
<section class="container jobs"> <section class="container jobs">
<h1>Want to change the future of education?</h1> <h1>Do You Want to Change the Future of Education?</h1>
<hr class="horizontal-divider"> <hr class="horizontal-divider">
<section class="message"> <section class="message">
<div class="inner-wrapper"> <div class="inner-wrapper">
<div class="photo"> <div class="photo">
<img src="${static.url('images/courses/space2.jpg')}"> <img src="${static.url('images/jobs.jpeg')}">
</div> </div>
<h2>Our Mission is to Educate 1 billion people around the world</h2> <header>
<p>“EdX represents a unique opportunity to improve education on our own campuses through online learning, while simultaneously creating a bold new educational path for millions of learners worldwide,” MIT President Susan Hockfield said.</p> <h2>Our mission is to transform learning.</h2>
<p>Harvard President Drew Faust said, “edX gives Harvard and MIT an unprecedented opportunity to dramatically extend our collective reach by conducting groundbreaking research into effective education and by extending online access to quality higher education.”
<blockquote>
<p>&ldquo;EdX represents a unique opportunity to improve education on our campuses though online learning, while simultaneously creating a bold new educational path for millions of learners worldwide.&rdquo;</p>
<cite>&mdash;Rafael Reif, MIT President </cite>
</blockquote>
<blockquote>
<p>&ldquo;EdX gives Harvard and MIT an unprecedented opportunity to dramatically extend our collective reach by conducting groundbreaking research into effective education and by extending online access to quality higher education.&rdquo;</p>
<cite>&mdash;Drew Faust, Harvard President</cite>
</blockquote>
</header>
</div> </div>
</section> </section>
<hr class="horizontal-divider"> <hr class="horizontal-divider">
...@@ -25,18 +37,18 @@ ...@@ -25,18 +37,18 @@
<article id="technology-team" class="job"> <article id="technology-team" class="job">
<div class="inner-wrapper"> <div class="inner-wrapper">
<h3>Technology Team</h3> <h3>Technology Team</h3>
<p>[Looking for both back-end and front-end developers. Strong backgrounds in machine learning, education, user interaction design, big data, or social network analysis are desirable, but team members do wear many hats. Best candidate would be a masterful hacker who went and did startups after finishing their Ph.D. We should find a way to make some positions that parallel fellows, and can leverage MIT/Harvard prestige]</p> <p>We’re looking for both back-end and front-end developers. Strong backgrounds in machine learning, education, user interaction design, big data, or social network analysis are desirable, but team members do wear many hats. Best candidate would be a masterful hacker who went out and did start ups after finishing their Ph.D.</p>
<p>If you're interested in this position, send an e-mail to <a href="">content-engineer@edxonline.org</a></p> <p>If you are interested in this position, please send an email to <a href='mailto:content-engineers@edx.org'>content-engineers@edx.org</a></p>
</div> </div>
</article> </article>
<article id="edx-fellow" class="job"> ## <article id="edx-fellow" class="job">
<div class="inner-wrapper"> ## <div class="inner-wrapper">
<h3>edX Fellow</h3> ## <h3>edX Fellow</h3>
<p>The edX fellows program is intended as an alternative to the traditional academic track for candidates with a strong focus on teaching. Fellows act as contact points for departments at MIT and Harvard, and help facilitate putting together on-line courses. </p> ## <p>The edX fellows program is intended as an alternative to the traditional academic track for candidates with a ## strong focus on teaching. Fellows act as contact points for departments at MIT and Harvard , and help facilitate ## putting together online courses.</p>
<p>If you're interested in this position, send an e-mail to <a href="">fellow-jobs@edxonline.org</a></p> ## <p>If you're interested in this position, send an e-mail to <a href="mailto:fellow-jobs@edx.org">fellow-jobs@edx.org## </a></p>
</div> ## </div>
</article> ## </article>
<article id="content-engineer" class="job"> <article id="content-engineer" class="job">
<div class="inner-wrapper"> <div class="inner-wrapper">
...@@ -54,7 +66,7 @@ ...@@ -54,7 +66,7 @@
</li> </li>
</ul> </ul>
<p>Knowledge of Python, XML, and/or JavaScript is desired. Strong interest and background in pedagogy and education is desired as well.</p> <p>Knowledge of Python, XML, and/or JavaScript is desired. Strong interest and background in pedagogy and education is desired as well.</p>
<p>If you're interested in this position, send an e-mail to <a href="">content-engineer@edxonline.org</a></p> <p>If you're interested in this position, send an e-mail to <a href="mailto:content-engineers@edx.org">content-engineers@edx.org</a></p>
</div> </div>
</article> </article>
</section> </section>
......
<%inherit file="marketing.html" />
<%block name="login_area">
</%block>
<section class="subpage">
<div>
<h1> <i>MITx</i> Advances MIT&rsquo;s Vision for Online Learning</h1>
<p> Education has entered an era of rapid, exciting,
technology-enabled change. At MIT, we welcome the opportunity to
harness the power of on-line technology for our students and for the
world. On December 19, 2011, we announced <i>MITx</i>, an initiative to
offer exciting, challenging and enriching courses to anyone,
anywhere, who has the motivation and ability to engage MIT&rsquo;s
educational content.</p>
<p> Ten years ago, MIT
launched <a href="http://ocw.mit.edu/index.htm">OpenCourseWare</a>,
which places online the course materials for substantially the entire
MIT curriculum, and was the genesis of today&rsquo;s worldwide
movement in free, open educational resources. <i>MITx</i> is the next step
in opening MIT&rsquo;s educational doors to the world. Through OCW and
<i>MITx</i>, MIT invites the world to join it in the passion, hard work and
thrill of learning and discovery.</p>
<h2><i>MITx</i> will e-publish interactive online courses that:</h2>
<ul>
<li>Empower students to learn at their own pace;</li>
<li>Offer online laboratories where students can experiment and apply their learning;</li>
<li>Connect students to each other in online discussion groups and wiki-based collaborative learning; </li>
<li>Challenge learners with MIT-rigor course materials; and</li>
<li>Assess individual student learning as the student progresses through the course.</li>
</ul>
<p> <i>MITx</i> students who demonstrate their mastery of a subject can earn
a certificate of completion awarded by <i>MITx</i>.</p>
<p> <i>MITx</i> courses will be available to the world through an Internet
platform that MIT will make freely available. MIT hopes that other
educational institutions, anywhere in the world, will adapt and use
the platform to publish their own educational content online for the
benefit of learners. Because the platform will be open-source and
scalable, adopters and users can continuously improve it, for the
benefit of everyone.</p>
<h2> Why Is MIT Creating <i>MITx</i>?</h2>
<p> Excellence in teaching and learning. MIT must always provide its
students the very best teaching and learning tools possible. MIT
began experimenting with online technologies in its educational
programs long before we launched OCW in 2001. We have only increased
our emphasis in recent years, as several MIT committees have studied
how MIT might enhance the learning experience of its students and
expand its impact worldwide through new online offerings.</p>
<p> These efforts, combined with those of numerous individual MIT
faculty members, confirmed MIT&rsquo;s conviction that digital
technologies enrich learning. Many other innovative institutions and
enterprises believe the same and are bringing creative online
offerings forward. Having brain-stormed, investigated and studied,
we were ready to act and eager to start. We announced our <i>MITx</i>
aspiration to capture and encourage the energy of our faculty in
creating new online teaching and learning tools. </p>
<p> Once up and running, <i>MITx</i> will be a laboratory for online
learning. Whether <i>MITx</i> learners are MIT&rsquo;s on-campus students,
university students elsewhere, or independent learners, <i>MITx</i> will help
us understand how online learning occurs and how virtual communities
of learners assemble -- information that in turn will allow us to
improve both <i>MITx</i> and our on-campus teaching. </p>
<p> Access to higher education. <i>MITx</i> will help shatter barriers to
education. The constraints of MIT&rsquo;s physical campus allow us to
admit less than 10 percent of our undergraduate applicants. We teach
on-campus only a tiny fraction of the people in the world with the
ability and motivation to learn MIT content. Online technology
provides a new and different portal into MIT-quality education.
Through <i>MITx</i>, MIT educational content can reach, augment, and enrich
the education and livelihood of many learners who cannot attend
MIT. </p>
<p> <i>MITx</i> does not provide a full MIT education. Our residential
campus is the heart of MIT&rsquo;s knowledge creation and
dissemination. MIT students enjoy a comprehensive curriculum and
distinct educational environment. Without MIT, there would be no
<i>MITx</i>. </p>
<p> Advancing the public good. <i>MITx</i> is an opportunity to help
preserve and expand higher education as a public good. Historically,
the investment of public and private assets in enormous amounts has
produced the public benefits of knowledge creation and dissemination,
leading to capable citizens, innovation, job creation, economic
development, and broader welfare.</p>
<p> Today, as computation and Internet technologies enable higher
education to migrate online, MIT sees the opportunity to democratize
education with unprecedented efficiency and scalability. We possess a
strong desire and feel a compelling obligation to offer a
not-for-profit, mission-driven, open-technology approach to online
learning. <i>MITx</i> is our contribution. </p>
</div>
</section>
<%inherit file="marketing.html" />
<%namespace name='static' file='static_content.html'/>
<%block name="header_class">home</%block>
<section class="index-content">
<section class="about">
<section class="intro">
<section class="intro-text">
<p><em>MITx</em> will offer a portfolio of MIT courses for free to a virtual community of learners around the world. It will also enhance the educational experience of its on-campus students, offering them online tools that supplement and enrich their classroom and laboratory experiences.</p>
<p>The first <em>MITx</em> course, 6.002x (Circuits and Electronics), was launched in an experimental prototype form. Watch this space for further upcoming courses, which will become available in Fall 2012.</p>
</section>
<section class="intro-video">
<a id="video-overlay-link" rel="leanModal" href="#video-overlay"><img src="${static.url('images/video-image.png')}" id="video-img" alt="Link to MITx introduction video" /><span> Watch intro video</span></a>
</section>
</section>
<section class="features">
<h2><em>MIT<span>x</span></em> courses will be offered on an online learning platform that:</h2>
<ul>
<li>organizes and presents course material to enable students to learn worldwide</li>
<li>features interactive instruction, online laboratories and student-to-student and student-to-professor communication</li>
<li>allows for the individual assessment of any student&rsquo;s work and allows students who demonstrate their mastery of subjects to earn certificates awarded by <em>MITx</em></li>
<li>operates on an open-source, scalable software infrastructure in order to make it continuously improving and readily available to other educational institutions, such as universities and K-12 school systems.</li>
</ul>
<p><strong>Press &amp; links:</strong> <a href="/6002x-press-release.html">6.002x Press Release</a>, <a href="/6002x-faq.html">6.002x FAQ</a>, <a href="/mitx-overview.html">MITx overview</a>, <a href="http://www.boston.com/news/local/massachusetts/articles/2011/12/19/mit_to_launch_online_only_graded_courses_free_to_all/?page=full" target="_blank">Boston Globe</a>, <a href="http://www.nytimes.com/2011/12/19/education/mit-expands-free-online-courses-offering-certificates.html?_r=3&hpw=" target="_blank">New York Times</a>, <a href="http://web.mit.edu/newsoffice/2011/mitx-education-initiative-1219.html" target="_blank">MIT Press Release</a>, <a href="http://web.mit.edu/newsoffice/2011/mitx-faq-1219" target="_blank"><em>MITx</em> FAQ</a>, <a href="http://ocw.mit.edu/index.htm" target="_blank">OpenCourseWare</a></p>
</section>
</section>
<section class="course">
<div class="announcement">
<h1> Announcement </h1>
<img src="/static/images/marketing/edx-logo.png" alt="" />
<p>
On May 2, it was announced that Harvard University will join MIT as a partner in edX. MITx, which offers online versions of MIT courses, will be a core offering of edX, as will Harvardx, a set of course offerings from Harvard.
</p>
<p class="announcement-button">
<a href="http://edxonline.org">Read more details here <span class="arrow">&#8227;</span></a>
</p>
</div>
<hgroup>
<h1>Spring 2012 Course offering</h1>
<h2>Circuits and Electronics</h2>
<h3>6.002x</h3>
</hgroup>
<p>
<a href="http://6002x.mitx.mit.edu/" class="more-info">More information <span>&amp;</span> Enroll <span class="arrow">&#8227;</span></a>
</p>
<p>Taught by Anant Agarwal, with Gerald Sussman and Piotr Mitros, 6.002x (Circuits and Electronics) is an on-line adaption of 6.002, MIT&rsquo;s first undergraduate analog design course. This prototype course is running, free of charge, for students worldwide from March 5, 2012 through June 8, 2012. Students are given the opportunity to demonstrate their mastery of the material and earn a certificate from <em>MITx</em>.</p>
</section>
</section>
<div id="video-overlay" class="leanModal_box">
<iframe id="player" type="text/html" width="560" height="390" src="http://www.youtube.com/embed/p2Q6BrNhdh8?enablejsapi=1" frameborder="0">
</iframe>
</div>
<%block name="js_extra">
<script>
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
});
}
$(function() {
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
$("a#video-overlay-link").click(function(){
player.playVideo();
$("a.modal_close, #lean_overlay").click(function(){
player.pauseVideo();
});
});
// TODO: Clean up as per http://stackoverflow.com/questions/169506/obtain-form-input-fields-using-jquery
/* Handles when the user hits 'enroll'. Grabs form data. Does AJAX.
Either shows error, or shows success. */
$('#create_account_button').click(function() {
var submit_data={};
$.each($("[id^=ca_]"), function(index,value){
submit_data[value.name]=value.value;
});
$.each($("[id^=cb_]"), function(index,value){
submit_data[value.name]=value.checked;
});
postJSON('/create_account',
submit_data,
function(json) {
if(json.success) {
$('#enroll').html(json.value);
} else {
$('#enroll_error').html(json.value);
}
}
);
});
/* Activate stupid spinner drop-downs in enrollment form */
var spinner_array=$("[id^=spinner_]");
spinner_array.each(function(i) {
var s=spinner_array[i];
$("#"+s.id).click(function(){
$("#sregion"+s.id.substring(7)).toggle();
});
})
/*$("sregion"+$("[id^=spinner_]")[1].id.substring(7)) */
});
</script>
</%block>
...@@ -3,6 +3,131 @@ ...@@ -3,6 +3,131 @@
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<%block name="title"><title>edX in the Press</title></%block>
<%!
from collections import namedtuple
Article = namedtuple('Article',
'title url author image deck publication publish_date')
articles = [
Article(title="Review: MITx's Online Circuit Design and Analysis Course",
url="http://spectrum.ieee.org/at-work/education/review-mitxs-online-circuit-design-and-analysis-course",
author="Steven J. Frank",
image="ieee_logo_178x138.jpeg",
deck="This latest experiment in remote learning is not for a casual audience.",
publication="IEEE Spectrum",
publish_date="July 2012"),
Article(title="More universities sign on to free online course initiative",
url="http://www.universityworldnews.com/article.php?story=20120719082235228",
author="Alison Moodie",
image="univworldnews_logo_178x138.jpeg",
deck=None,
publication="University World News",
publish_date="7/19/2012 Issue No:231"),
Article(title="One Course, 150,000 Students",
url="http://nyti.ms/LtlQ5k",
author="Tamar Lewin",
image="nyt_logo_178x138.jpeg",
deck=None,
publication="The New York Times",
publish_date="7/18/2012"),
Article(title="Lessons learned from MITx's prototype course",
url="http://mitne.ws/Mdabcp",
author="Larry Hardesty, MIT News Office",
image="mit_logo_178x138.jpeg",
deck="As the team behind MIT's ambitious online learning program gears up to introduce new courses in the fall, it takes stock of its initial experiences.",
publication="MIT News",
publish_date="7/16/2012"),
Article(title="Software coding: not just for programmers anymore",
url="http://gigaom.com/cloud/everybody-codes/",
author="Barb Darrow",
image="gigaom_logo_178x138.jpeg",
deck=None,
publication="GigaOM",
publish_date="7/16/2012"),
Article(title="Anant Agarwal believes an online education from MIT and Harvard should be available to all",
url="http://b.globe.com/P6XKlB",
author="Jon Marcus",
image="bostonglobe_logo_178x138.jpeg",
deck=None,
publication="The Boston Globe",
publish_date="7/15/2012"),
Article(title="Online Classes Cut Costs, But Do They Dilute Brands?",
url="http://n.pr/Lt5ydM",
author="Tovia Smith",
image="npr_logo_178x138.jpeg",
deck=None,
publication="NPR",
publish_date="7/02/2012"),
Article(title="Coming Your Way: Free Virtual Courses From Top U.S. Universities",
url="http://www.openequalfree.org/coming-your-way-free-virtual-courses-from-top-u-s-universities/13993",
author=None,
image="oef_logo_178x138.jpeg",
deck=None,
publication="Open Equal Free",
publish_date="6/29/2012"),
Article(title="Open Online Courses Are No Substitute for Classroom Learning",
url="http://bit.ly/MMEdEX",
author="Joshua Kim",
image="usnews_logo_178x138.jpeg",
deck=None,
publication="US News",
publish_date="6/29/2012"),
Article(title="Harvard and MIT create edX to offer free video online courses to the world",
url="http://huff.to/LBucd3",
author="Lucy Sheriff",
image="huffpost_logo_178x138.jpeg",
deck=None,
publication="The Huffington Post",
publish_date="6/20/2012"),
Article(title="Top universities put their reputations online",
url="http://bbc.in/M5avea",
author="Irina Khokhlova",
image="bbc_logo_178x138.jpeg",
deck=None,
publication="BBC News",
publish_date="6/20/2012"),
Article(title="MIT receives $1 million to support edX partnership",
url="http://mitne.ws/Md5Aaa",
author=None,
image="mit_logo_178x138.jpeg",
deck="Institute receives award as part of Gates Foundation efforts to boost postsecondary graduation rates.",
publication="MIT News",
publish_date="6/19/2012"),
Article(title="Column: Ivy League education? Online is the new option",
url="http://usat.ly/J73NW7",
author="Katrina Trinko",
image="usa_logo_178x138.jpeg",
deck=None,
publication="USA Today",
publish_date="5/15/2012"),
Article(title="What is edX?",
url="http://mitne.ws/PgYhya",
author=None,
image="mit_logo_178x138.jpeg",
deck="Answering common questions about MIT and Harvard's new partnership in online education.",
publication="MIT News",
publish_date="5/02/2012"),
Article(title="MIT and Harvard announce edX",
url="http://mitne.ws/Md5yit",
author=None,
image="mit_logo_178x138.jpeg",
deck="Joint partnership builds on MITx and Harvard distance learning; aims to benefit campus-based education and beyond.",
publication="MIT News",
publish_date="5/02/2012"),
Article(title="MIT and Harvard launch a 'revolution in education'",
url="http://mitne.ws/PgZQvY",
author=None,
image="mit_logo_178x138.jpeg",
deck="Online edX courses will open both universities' classrooms to the world while enhancing on-campus learning.",
publication="MIT News",
publish_date="5/02/2012"),
]
%>
<section class="container about"> <section class="container about">
<nav> <nav>
<a href="${reverse('about_edx')}">Vision</a> <a href="${reverse('about_edx')}">Vision</a>
...@@ -12,61 +137,27 @@ ...@@ -12,61 +137,27 @@
</nav> </nav>
<section class="press"> <section class="press">
% for article in articles:
<article class="press-story"> <article class="press-story">
<div class="article-cover"> <div class="article-cover">
<img src="${static.url('images/courses/circuits.jpeg')}" /> <a href="${article.url}" target="_blank"/><img src="${static.url('images/press/' + article.image)}" /></a>
</div>
<div class="press-info">
<header>
<h3>Online Classes Cut Costs, But Do They Dilute Brands?</h3>
<span class="post-date">7/12/2012</span>
<a href="http://www.npr.org/2012/07/02/156122748/online-classes-cut-costs-but-do-they-dilute-brands">http://n.pr/Lt5ydM</a>
</header>
<p>"You know this is the Wild West. There's a lot of things we have to figure out," Agarwal says. "And you know if anybody says they know exactly what they're doing, I think that would be a far cry from reality."</p>
</div>
</article>
<article class="press-story">
<div class="article-cover">
<img src="${static.url('images/courses/circuits.jpeg')}" />
</div>
<div class="press-info">
<header>
<h3>Online Classes Cut Costs, But Do They Dilute Brands?</h3>
<span class="post-date">7/12/2012</span>
<a href="http://www.npr.org/2012/07/02/156122748/online-classes-cut-costs-but-do-they-dilute-brands">http://n.pr/Lt5ydM</a>
</header>
<p>"You know this is the Wild West. There's a lot of things we have to figure out," Agarwal says. "And you know if anybody says they know exactly what they're doing, I think that would be a far cry from reality."</p>
</div>
</article>
<article class="press-story">
<div class="article-cover">
<img src="${static.url('images/courses/circuits.jpeg')}" />
</div>
<div class="press-info">
<header>
<h3>Online Classes Cut Costs, But Do They Dilute Brands?</h3>
<span class="post-date">7/12/2012</span>
<a href="http://www.npr.org/2012/07/02/156122748/online-classes-cut-costs-but-do-they-dilute-brands">http://n.pr/Lt5ydM</a>
</header>
<p>"You know this is the Wild West. There's a lot of things we have to figure out," Agarwal says. "And you know if anybody says they know exactly what they're doing, I think that would be a far cry from reality."</p>
</div>
</article>
<article class="press-story">
<div class="article-cover">
<img src="${static.url('images/courses/circuits.jpeg')}" />
</div> </div>
<div class="press-info"> <div class="press-info">
<header> <header>
<h3>Online Classes Cut Costs, But Do They Dilute Brands?</h3> <h3>${article.title}</h3>
<span class="post-date">7/12/2012</span> % if article.deck:
<a href="http://www.npr.org/2012/07/02/156122748/online-classes-cut-costs-but-do-they-dilute-brands">http://n.pr/Lt5ydM</a> <p>${article.deck}</p>
% endif
<span class="post-date">${article.publication} | ${article.publish_date}
% if article.author:
| By ${article.author}
% endif
</span><br/>
</header> </header>
<p>"You know this is the Wild West. There's a lot of things we have to figure out," Agarwal says. "And you know if anybody says they know exactly what they're doing, I think that would be a far cry from reality."</p> <a href="${article.url}" target="_blank">${article.url}</a>
</div> </div>
</article> </article>
% endfor
</section> </section>
</section> </section>
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%block name="title"><title>MIT and Harvard announce edX</title></%block>
<section class="pressrelease"> <section class="pressrelease">
<section class="container"> <section class="container">
<h1>MIT and Harvard announce edX</h1> <h1>MIT and Harvard announce edX</h1>
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%block name="title"><title>Privacy Policy</title></%block>
<section class="static-container privacy-policy"> <section class="static-container privacy-policy">
<h1>Privacy Policy</h1> <h1>Privacy Policy</h1>
<hr class="horizontal-divider"> <hr class="horizontal-divider">
......
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<section class="outside-app"> <section class="outside-app">
<h1>There has been an error on the <em>edX</em> servers</h1> <h1>There has been a 500 error on the <em>edX</em> servers</h1>
<p>Our staff is currently working to get the site back up as soon as possible. Please email us at <a href="mailto:technical@mitx.mit.edu">technical@mitx.mit.edu</a> to report any problems or downtime.</p> <p>Our staff is currently working to get the site back up as soon as possible. Please email us at <a href="mailto:technical@mitx.mit.edu">technical@mitx.mit.edu</a> to report any problems or downtime.</p>
</section> </section>
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%block name="title"><title>Terms of Service</title></%block>
<section class="static-container tos"> <section class="static-container tos">
<h1>MITx Terms of Service</h1> <h1>MITx Terms of Service</h1>
<hr class="horizontal-divider"> <hr class="horizontal-divider">
......
<%inherit file="../main.html" />
<%namespace name='static' file='../static_content.html'/>
<section class="university-profile">
<header class="search" style="background: url('/static/images/shot-5-large.jpg')">
<div class="inner-wrapper university-search">
<hgroup>
<div class="logo">
<img src="${static.url('images/mit.png')}" />
</div>
<h1>MITx</h1>
</hgroup>
</div>
</header>
<section class="container">
<section class="courses">
</section>
</section>
</section>
<%inherit file="../main.html" />
<%namespace name='static' file='../static_content.html'/>
<section class="find-courses">
<%block name="university_header"/>
<section class="container">
<section class="courses university-courses">
%for course in courses:
<%include file="../course.html" args="course=course" />
%endfor
</section>
<section class="message left">
<%block name="university_description" />
</section>
</section>
</section>
<%inherit file="base.html" />
<%namespace name='static' file='../static_content.html'/>
<%block name="title"><title>BerkeleyX</title></%block>
<%block name="university_header">
<header class="search" style="background: url('/static/images/university/berkeley/berkeley_fountain_2025x550.jpg')">
<div class="inner-wrapper university-search">
<hgroup>
<div class="logo">
<img src="${static.url('images/university/berkeley/berkeley.png')}" />
</div>
<h1>BerkeleyX</h1>
</hgroup>
</div>
</header>
</%block>
<%block name="university_description">
<p>The University of California, Berkeley was chartered in 1868 and its flagship campus — envisioned as a "City of Learning" — was established at Berkeley, on San Francisco Bay. Berkeley Faculty consists of 1,582 fulltime and 500 part-time faculty members dispersed among more than 130 academic departments and more than 80 interdisciplinary research units. 28 Nobel prizes have been awarded to Berkeley Alumni. There are eight Nobel Laureates, 32 MacArthur Fellows, and four Pulitzer Prize winners among the current faculty.</p>
</%block>
${parent.body()}
<%inherit file="base.html" />
<%namespace name='static' file='../static_content.html'/>
<%block name="title"><title>HarvardX</title></%block>
<%block name="university_header">
<header class="search" style="background: url('/static/images/university/harvard/about_harvard_page_2025x550.jpg')">
<div class="inner-wrapper university-search">
<hgroup>
<div class="logo">
<img src="${static.url('images/university/harvard/harvard.png')}" />
</div>
<h1>HarvardX</h1>
</hgroup>
</div>
</header>
</%block>
<%block name="university_description">
<p>Harvard University is devoted to excellence in teaching, learning, and research, and to developing leaders in many disciplines who make a difference globally. Harvard faculty are engaged with teaching and research to push the boundaries of human knowledge. The University has twelve degree-granting Schools in addition to the Radcliffe Institute for Advanced Study.</p>
<p>Established in 1636, Harvard is the oldest institution of higher education in the United States. The University, which is based in Cambridge and Boston, Massachusetts, has an enrollment of over 20,000 degree candidates, including undergraduate, graduate, and professional students. Harvard has more than 360,000 alumni around the world.</p>
</%block>
${parent.body()}
<%inherit file="base.html" />
<%namespace name='static' file='../static_content.html'/>
<%block name="title"><title>MITx</title></%block>
<%block name="university_header">
<header class="search" style="background: url('/static/images/university/mit/shot-2-large.jpg')">
<div class="inner-wrapper university-search">
<hgroup>
<div class="logo">
<img src="${static.url('images/university/mit/mit.png')}" />
</div>
<h1>MITx</h1>
</hgroup>
</div>
</header>
</%block>
<%block name="university_description">
<p>The Massachusetts Institute of Technology &mdash; a coeducational, privately endowed research university founded in 1861 &mdash; is dedicated to advancing knowledge and educating students in science, technology, and other areas of scholarship that will best serve the nation and the world in the 21st century. The Institute has close to 1,000 faculty and 10,000 undergraduate and graduate students. It is organized into five Schools: Architecture and Urban Planning; Engineering; Humanities, Arts, and Social Sciences; Sloan School of Management; and Science.</p>
<p>MIT's commitment to innovation has led to a host of scientific breakthroughs and technological advances. Achievements of the Institute's faculty and graduates have included the first chemical synthesis of penicillin and vitamin A, the development of inertial guidance systems, modern technologies for artificial limbs, and the magnetic core memory that made possible the development of digital computers. 78 alumni, faculty, researchers and staff have won Nobel Prizes.</p>
<p>Current areas of research and education include neuroscience and the study of the brain and mind, bioengineering, cancer, energy, the environment and sustainable development, information sciences and technology, new media, financial technology, and entrepreneurship.</p>
</%block>
${parent.body()}
<%!
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>
...@@ -13,22 +13,24 @@ if settings.DEBUG: ...@@ -13,22 +13,24 @@ if settings.DEBUG:
urlpatterns = ('', urlpatterns = ('',
url(r'^$', 'student.views.index', name="root"), # Main marketing page, or redirect to courseware url(r'^$', 'student.views.index', name="root"), # Main marketing page, or redirect to courseware
url(r'^dashboard$', 'student.views.dashboard', name="dashboard"), url(r'^dashboard$', 'student.views.dashboard', name="dashboard"),
url(r'^change_email$', 'student.views.change_email_request'), url(r'^change_email$', 'student.views.change_email_request'),
url(r'^email_confirm/(?P<key>[^/]*)$', 'student.views.confirm_email_change'), url(r'^email_confirm/(?P<key>[^/]*)$', 'student.views.confirm_email_change'),
url(r'^change_name$', 'student.views.change_name_request'), url(r'^change_name$', 'student.views.change_name_request'),
url(r'^accept_name_change$', 'student.views.accept_name_change'), url(r'^accept_name_change$', 'student.views.accept_name_change'),
url(r'^reject_name_change$', 'student.views.reject_name_change'), url(r'^reject_name_change$', 'student.views.reject_name_change'),
url(r'^pending_name_changes$', 'student.views.pending_name_changes'), url(r'^pending_name_changes$', 'student.views.pending_name_changes'),
url(r'^gradebook$', 'courseware.views.gradebook'),
url(r'^event$', 'track.views.user_track'), url(r'^event$', 'track.views.user_track'),
url(r'^t/(?P<template>[^/]*)$', 'static_template_view.views.index'), url(r'^t/(?P<template>[^/]*)$', 'static_template_view.views.index'), # TODO: Is this used anymore? What is STATIC_GRAB?
url(r'^login$', 'student.views.login_user'), url(r'^login$', 'student.views.login_user'),
url(r'^login/(?P<error>[^/]*)$', 'student.views.login_user'), url(r'^login/(?P<error>[^/]*)$', 'student.views.login_user'),
url(r'^logout$', 'student.views.logout_user', name='logout'), url(r'^logout$', 'student.views.logout_user', name='logout'),
url(r'^create_account$', 'student.views.create_account'), url(r'^create_account$', 'student.views.create_account'),
url(r'^activate/(?P<key>[^/]*)$', 'student.views.activate_account'), url(r'^activate/(?P<key>[^/]*)$', 'student.views.activate_account'),
# url(r'^reactivate/(?P<key>[^/]*)$', 'student.views.reactivation_email'),
url(r'^password_reset/$', 'student.views.password_reset'), url(r'^password_reset/$', 'student.views.password_reset', name='password_reset'),
## Obsolete Django views for password resets ## Obsolete Django views for password resets
## TODO: Replace with Mako-ized views ## TODO: Replace with Mako-ized views
url(r'^password_change/$', django.contrib.auth.views.password_change, url(r'^password_change/$', django.contrib.auth.views.password_change,
...@@ -42,10 +44,10 @@ urlpatterns = ('', ...@@ -42,10 +44,10 @@ urlpatterns = ('',
name='auth_password_reset_complete'), name='auth_password_reset_complete'),
url(r'^password_reset_done/$', django.contrib.auth.views.password_reset_done, url(r'^password_reset_done/$', django.contrib.auth.views.password_reset_done,
name='auth_password_reset_done'), name='auth_password_reset_done'),
## Feedback
url(r'^send_feedback$', 'util.views.send_feedback'),
url(r'^heartbeat$', include('heartbeat.urls')),
url(r'^university_profile/(?P<org_id>[^/]+)$', 'courseware.views.university_profile', name="university_profile"),
#Semi-static views (these need to be rendered and have the login bar, but don't change) #Semi-static views (these need to be rendered and have the login bar, but don't change)
url(r'^404$', 'static_template_view.views.render', url(r'^404$', 'static_template_view.views.render',
...@@ -74,17 +76,11 @@ urlpatterns = ('', ...@@ -74,17 +76,11 @@ urlpatterns = ('',
{'template': 'honor.html'}, name="honor"), {'template': 'honor.html'}, name="honor"),
(r'^favicon\.ico$', 'django.views.generic.simple.redirect_to', {'url': '/static/images/favicon.ico'}),
#Temporarily static, for testing # TODO: These urls no longer work. They need to be updated before they are re-enabled
url(r'^university_profile$', 'static_template_view.views.render', # url(r'^send_feedback$', 'util.views.send_feedback'),
{'template': 'university_profile.html'}, name="university_profile"), # url(r'^reactivate/(?P<key>[^/]*)$', 'student.views.reactivation_email'),
#TODO: Convert these pages to the new edX layout
# 'tos.html',
# 'privacy.html',
# 'honor.html',
# 'copyright.html',
) )
if settings.PERFSTATS: if settings.PERFSTATS:
...@@ -97,21 +93,21 @@ if settings.COURSEWARE_ENABLED: ...@@ -97,21 +93,21 @@ if settings.COURSEWARE_ENABLED:
url(r'^modx/(?P<id>.*?)/(?P<dispatch>[^/]*)$', 'courseware.module_render.modx_dispatch'), #reset_problem'), url(r'^modx/(?P<id>.*?)/(?P<dispatch>[^/]*)$', 'courseware.module_render.modx_dispatch'), #reset_problem'),
url(r'^xqueue/(?P<userid>[^/]*)/(?P<id>.*?)/(?P<dispatch>[^/]*)$', 'courseware.module_render.xqueue_callback'), url(r'^xqueue/(?P<userid>[^/]*)/(?P<id>.*?)/(?P<dispatch>[^/]*)$', 'courseware.module_render.xqueue_callback'),
url(r'^change_setting$', 'student.views.change_setting'), url(r'^change_setting$', 'student.views.change_setting'),
url(r'^s/(?P<template>[^/]*)$', 'static_template_view.views.auth_index'),
# url(r'^course_info/$', 'student.views.courseinfo'),
# url(r'^show_circuit/(?P<circuit>[^/]*)$', 'circuit.views.show_circuit'),
url(r'^edit_circuit/(?P<circuit>[^/]*)$', 'circuit.views.edit_circuit'),
url(r'^save_circuit/(?P<circuit>[^/]*)$', 'circuit.views.save_circuit'),
url(r'^calculate$', 'util.views.calculate'),
url(r'^heartbeat$', include('heartbeat.urls')),
# Multicourse related: # TODO: These views need to be updated before they work
# url(r'^calculate$', 'util.views.calculate'),
# url(r'^gradebook$', 'courseware.views.gradebook'),
# TODO: We should probably remove the circuit package. I believe it was only used in the old way of saving wiki circuits for the wiki
# url(r'^edit_circuit/(?P<circuit>[^/]*)$', 'circuit.views.edit_circuit'),
# url(r'^save_circuit/(?P<circuit>[^/]*)$', 'circuit.views.save_circuit'),
url(r'^courses/?$', 'courseware.views.courses', name="courses"), url(r'^courses/?$', 'courseware.views.courses', name="courses"),
url(r'^change_enrollment$',
'student.views.change_enrollment_view', name="change_enrollment"),
#About the course #About the course
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/about$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/about$',
'student.views.course_info', name="about_course"), 'courseware.views.course_about', name="about_course"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/enroll$',
'student.views.enroll', name="enroll"),
#Inside the course #Inside the course
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/info$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/info$',
...@@ -139,9 +135,6 @@ if settings.WIKI_ENABLED: ...@@ -139,9 +135,6 @@ if settings.WIKI_ENABLED:
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/wiki/', include('simplewiki.urls')), url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/wiki/', include('simplewiki.urls')),
) )
if settings.ENABLE_MULTICOURSE:
urlpatterns += (url(r'^mitxhome$', 'multicourse.views.mitxhome'),)
if settings.QUICKEDIT: if settings.QUICKEDIT:
urlpatterns += (url(r'^quickedit/(?P<id>[^/]*)$', 'dogfood.views.quickedit'),) urlpatterns += (url(r'^quickedit/(?P<id>[^/]*)$', 'dogfood.views.quickedit'),)
urlpatterns += (url(r'^dogfood/(?P<id>[^/]*)$', 'dogfood.views.df_capa_problem'),) urlpatterns += (url(r'^dogfood/(?P<id>[^/]*)$', 'dogfood.views.df_capa_problem'),)
...@@ -162,3 +155,9 @@ urlpatterns = patterns(*urlpatterns) ...@@ -162,3 +155,9 @@ urlpatterns = patterns(*urlpatterns)
if settings.DEBUG: if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
#Custom error pages
handler404 = 'static_template_view.views.render_404'
handler500 = 'static_template_view.views.render_500'
...@@ -158,7 +158,7 @@ task :package do ...@@ -158,7 +158,7 @@ task :package do
# as the makeitso user # as the makeitso user
if [[ -d "#{INSTALL_DIR_PATH}" ]]; then if [[ -d "#{INSTALL_DIR_PATH}" ]]; then
sudo -u makeitso rm -rf "#{INSTALL_DIR_PATH}" sudo rm -rf "#{INSTALL_DIR_PATH}"
fi fi
AFTERREMOVE AFTERREMOVE
...@@ -171,7 +171,6 @@ task :package do ...@@ -171,7 +171,6 @@ task :package do
set -e set -e
set -x set -x
chown -R makeitso:makeitso #{INSTALL_DIR_PATH}
service gunicorn stop || echo "Unable to stop gunicorn. Continuing" service gunicorn stop || echo "Unable to stop gunicorn. Continuing"
rm -f #{LINK_PATH} rm -f #{LINK_PATH}
...@@ -184,6 +183,7 @@ task :package do ...@@ -184,6 +183,7 @@ task :package do
pip install -r #{PIP_REPO_REQUIREMENTS} pip install -r #{PIP_REPO_REQUIREMENTS}
fi fi
chown -R makeitso:makeitso #{INSTALL_DIR_PATH}
# Delete mako temp files # Delete mako temp files
rm -rf /tmp/tmp*mako rm -rf /tmp/tmp*mako
......
...@@ -15,6 +15,7 @@ django_debug_toolbar ...@@ -15,6 +15,7 @@ django_debug_toolbar
django-staticfiles>=1.2.1 django-staticfiles>=1.2.1
fs fs
beautifulsoup beautifulsoup
feedparser
requests requests
sympy sympy
newrelic newrelic
......
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