Commit 5fe68e3a by Piotr Mitros

Merge to default for next developments

--HG--
branch : pmitros-mod-template
parents 8174e496 ffba3c59
......@@ -4,6 +4,7 @@ import math
import operator
import numpy
import scipy.constants
from pyparsing import Word, alphas, nums, oneOf, Literal
from pyparsing import ZeroOrMore, OneOrMore, StringStart
......@@ -24,18 +25,26 @@ default_functions = {'sin' : numpy.sin,
'abs':numpy.abs
}
default_variables = {'j':numpy.complex(0,1),
'e':numpy.complex(numpy.e)
'e':numpy.e,
'pi':numpy.pi,
'k':scipy.constants.k,
'c':scipy.constants.c,
'T':298.15,
'q':scipy.constants.e
}
log = logging.getLogger("mitx.courseware.capa")
def evaluator(variables, functions, string):
''' Evaluate an expression. Variables are passed as a dictionary
from string to value. Unary functions are passed as a dictionary
from string to function '''
log.debug(u"Evaluating: {0} with vars: {1}, funcs: {2}"
.format(string, variables, functions))
from string to function. Variables must be floats.
TODO: Fix it so we can pass integers and complex numbers in variables dict
'''
# log.debug("variables: {0}".format(variables))
# log.debug("functions: {0}".format(functions))
# log.debug("string: {0}".format(string))
all_variables = copy.copy(default_variables)
all_variables.update(variables)
......@@ -125,7 +134,10 @@ def evaluator(variables, functions, string):
# Handle variables passed in. E.g. if we have {'R':0.5}, we make the substitution.
# Special case for no variables because of how we understand PyParsing is put together
if len(all_variables)>0:
varnames = sreduce(lambda x,y:x|y, map(lambda x: CaselessLiteral(x), all_variables.keys()))
# We sort the list so that var names (like "e2") match before
# mathematical constants (like "e"). This is kind of a hack.
all_variables_keys = sorted(all_variables.keys(), key=len, reverse=True)
varnames = sreduce(lambda x,y:x|y, map(lambda x: CaselessLiteral(x), all_variables_keys))
varnames.setParseAction(lambda x:map(lambda y:all_variables[y], x))
else:
varnames=NoMatch()
......@@ -153,7 +165,9 @@ if __name__=='__main__':
print "X",evaluator(variables, functions, "10000||sin(7+5)-6k")
print "X",evaluator(variables, functions, "13")
print evaluator({'R1': 2.0, 'R3':4.0}, {}, "13")
#
print evaluator({'e1':1,'e2':1.0,'R3':7,'V0':5,'R5':15,'I1':1,'R4':6}, {},"e2")
print evaluator({'a': 2.2997471478310274, 'k': 9, 'm': 8, 'x': 0.66009498411213041}, {}, "5")
print evaluator({},{}, "-1")
print evaluator({},{}, "-(7+5)")
......
......@@ -19,24 +19,36 @@ global_context={'random':random,
'calc':calc,
'eia':eia}
def compare_with_tolerance(v1, v2, tol):
''' Compare v1 to v2 with maximum tolerance tol
tol is relative if it ends in %; otherwise, it is absolute
'''
relative = "%" in tol
if relative:
tolerance_rel = evaluator(dict(),dict(),tol[:-1]) * 0.01
tolerance = tolerance_rel * max(abs(v1), abs(v2))
else:
tolerance = evaluator(dict(),dict(),tol)
return abs(v1-v2) <= tolerance
class numericalresponse(object):
def __init__(self, xml, context):
self.xml = xml
self.correct_answer = contextualize_text(xml.get('answer'), context)
self.correct_answer = float(self.correct_answer)
self.tolerance = xml.xpath('//*[@id=$id]//responseparam[@type="tolerance"]/@default',
self.tolerance_xml = xml.xpath('//*[@id=$id]//responseparam[@type="tolerance"]/@default',
id=xml.get('id'))[0]
self.tolerance = contextualize_text(self.tolerance, context)
self.tolerance = evaluator(dict(),dict(),self.tolerance)
self.tolerance = contextualize_text(self.tolerance_xml, context)
self.answer_id = xml.xpath('//*[@id=$id]//textline/@id',
id=xml.get('id'))[0]
def grade(self, student_answers):
''' Display HTML for a numeric response '''
student_answer = student_answers[self.answer_id]
error = abs(evaluator(dict(),dict(),student_answer) - self.correct_answer)
allowed_error = abs(self.correct_answer*self.tolerance)
if error <= allowed_error:
correct = compare_with_tolerance (evaluator(dict(),dict(),student_answer), self.correct_answer, self.tolerance)
if correct:
return {self.answer_id:'correct'}
else:
return {self.answer_id:'incorrect'}
......@@ -77,10 +89,9 @@ class formularesponse(object):
self.xml = xml
self.correct_answer = contextualize_text(xml.get('answer'), context)
self.samples = contextualize_text(xml.get('samples'), context)
self.tolerance = xml.xpath('//*[@id=$id]//responseparam[@type="tolerance"]/@default',
self.tolerance_xml = xml.xpath('//*[@id=$id]//responseparam[@type="tolerance"]/@default',
id=xml.get('id'))[0]
self.tolerance = contextualize_text(self.tolerance, context)
self.tolerance = evaluator(dict(),dict(),self.tolerance)
self.tolerance = contextualize_text(self.tolerance_xml, context)
self.answer_id = xml.xpath('//*[@id=$id]//textline/@id',
id=xml.get('id'))[0]
self.context = context
......@@ -105,7 +116,7 @@ class formularesponse(object):
student_result = evaluator(student_variables,dict(),student_answers[self.answer_id])
if math.isnan(student_result) or math.isinf(student_result):
return {self.answer_id:"incorrect"}
if abs( student_result - instructor_result ) > self.tolerance:
if not compare_with_tolerance(student_result, instructor_result, self.tolerance):
return {self.answer_id:"incorrect"}
return {self.answer_id:"correct"}
......
......@@ -11,6 +11,7 @@ from mako.lookup import TemplateLookup
try: # This lets us do __name__ == ='__main__'
from django.conf import settings
from student.models import UserProfile
from student.models import UserTestGroup
except:
settings = None
......@@ -149,7 +150,11 @@ def course_file(user):
filename = UserProfile.objects.get(user=user).courseware
data_template = template_lookup.get_template(filename)
options = {'dev_content':settings.DEV_CONTENT}
# TODO: Rewrite in Django
groups = [u.name for u in UserTestGroup.objects.raw("select * from auth_user, student_usertestgroup, student_usertestgroup_users where auth_user.id = student_usertestgroup_users.user_id and student_usertestgroup_users.usertestgroup_id = student_usertestgroup.id and auth_user.id = %s", [user.id])]
options = {'dev_content':settings.DEV_CONTENT,
'groups' : groups}
tree = etree.XML(data_template.render(**options))
id_tag(tree)
......
......@@ -8,6 +8,7 @@ from django.contrib.auth.models import User
from mitx.courseware.content_parser import course_file
import mitx.courseware.module_render
import mitx.courseware.modules
class Command(BaseCommand):
help = "Does basic validity tests on course.xml."
......@@ -24,7 +25,7 @@ class Command(BaseCommand):
check = False
print "Confirming all modules render. Nothing should print during this step. "
for module in course.xpath('//problem|//html|//video|//vertical|//sequential|/tab'):
module_class=mitx.courseware.module_render.modx_modules[module.tag]
module_class=mitx.courseware.modules.modx_modules[module.tag]
# TODO: Abstract this out in render_module.py
try:
instance=module_class(etree.tostring(module),
......
......@@ -60,8 +60,6 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
ajax_url = '/modx/'+module+'/'+id+'/'
# id_tag=courseware.modules.get_module_class(module)
# Grab the XML corresponding to the request from course.xml
xml = content_parser.module_xml(content_parser.course_file(request.user), module, 'id', id)
......@@ -118,7 +116,10 @@ def render_x_module(user, request, xml_module, module_object_preload):
smod.save() # This may be optional (at least in the case of no instance in the dB)
module_object_preload.append(smod)
# Grab content
content = {'content':instance.get_html(),
content = instance.get_html()
if user.is_staff:
content=content+render_to_string("staff_problem_info.html", {'xml':etree.tostring(xml_module)})
content = {'content':content,
"destroy_js":instance.get_destroy_js(),
'init_js':instance.get_init_js(),
'type':module_type}
......
......@@ -253,7 +253,7 @@ class Module(XModule):
for key in get:
answers['_'.join(key.split('_')[1:])]=get[key]
print "XXX", answers, get
# print "XXX", answers, get
event_info['answers']=answers
......
......@@ -27,6 +27,9 @@ class ModelsTest(unittest.TestCase):
self.assertEqual(calc.evaluator({},{}, "-1"), -1)
self.assertEqual(calc.evaluator({},{}, "-0.33"), -.33)
self.assertEqual(calc.evaluator({},{}, "-.33"), -.33)
self.assertEqual(calc.evaluator(variables, functions, "R1*R3"), 8.0)
self.assertTrue(abs(calc.evaluator(variables, functions, "sin(e)-0.41"))<0.01)
self.assertTrue(abs(calc.evaluator(variables, functions, "k*T/q-0.025"))<0.001)
exception_happened = False
try:
evaluator({},{}, "5+7 QWSEKO")
......
import json
import logging
import os
import random
import sys
import StringIO
import urllib
......@@ -41,19 +42,19 @@ def profile(request):
return redirect('/')
dom=content_parser.course_file(request.user)
hw=[]
course = dom.xpath('//course/@name')[0]
chapters = dom.xpath('//course[@name=$course]/chapter', course=course)
xmlChapters = dom.xpath('//course[@name=$course]/chapter', course=course)
responses=StudentModule.objects.filter(student=request.user)
response_by_id = {}
for response in responses:
response_by_id[response.module_id] = response
total_scores = {}
for c in chapters:
chapters=[]
for c in xmlChapters:
sections = []
chname=c.get('name')
for s in dom.xpath('//course[@name=$course]/chapter[@name=$chname]/section',
course=course, chname=chname):
......@@ -71,7 +72,7 @@ def profile(request):
if response.grade!=None:
correct=response.grade
total=courseware.modules.capa_module.LoncapaModule(etree.tostring(p), "id").max_score() # TODO: Add state. Not useful now, but maybe someday problems will have randomized max scores?
total=courseware.modules.capa_module.Module(etree.tostring(p), "id").max_score() # TODO: Add state. Not useful now, but maybe someday problems will have randomized max scores?
scores.append((int(correct),total, graded ))
......@@ -89,9 +90,7 @@ def profile(request):
format_scores.append( graded_total )
total_scores[ format ] = format_scores
score={'course':course,
'section':s.get("name"),
'chapter':c.get("name"),
score={'section':s.get("name"),
'scores':scores,
'section_total' : section_total,
'format' : format,
......@@ -99,7 +98,12 @@ def profile(request):
'due' : s.get("due") or "",
'graded' : graded,
}
hw.append(score)
sections.append(score)
chapters.append({'course':course,
'chapter' : c.get("name"),
'sections' : sections,})
def totalWithDrops(scores, drop_count):
#Note that this key will sort the list descending
......@@ -125,9 +129,17 @@ def profile(request):
else:
percentage = 0
summary = "0% (?/?)"
if settings.GENERATE_PROFILE_SCORES:
points_possible = random.randrange(10, 50)
points_earned = random.randrange(5, points_possible)
percentage = points_earned / float(points_possible)
summary = "{0:.0%} ({1}/{2})".format( percentage, points_earned, points_possible )
summary = "Homework {0} - {1}".format(i + 1, summary)
label = "HW {0:02d}".format(i + 1)
homework_percentages.append( {'percentage': percentage, 'summary': summary} )
homework_percentages.append( {'percentage': percentage, 'summary': summary, 'label' : label} )
homework_total, homework_dropped_indices = totalWithDrops(homework_percentages, 2)
#Figure the lab scores
......@@ -140,8 +152,17 @@ def profile(request):
else:
percentage = 0
summary = "0% (?/?)"
if settings.GENERATE_PROFILE_SCORES:
points_possible = random.randrange(10, 50)
points_earned = random.randrange(5, points_possible)
percentage = points_earned / float(points_possible)
summary = "{0:.0%} ({1}/{2})".format( percentage, points_earned, points_possible )
summary = "Lab {0} - {1}".format(i + 1, summary)
lab_percentages.append( {'percentage': percentage, 'summary': summary} )
label = "Lab {0:02d}".format(i + 1)
lab_percentages.append( {'percentage': percentage, 'summary': summary, 'label' : label} )
lab_total, lab_dropped_indices = totalWithDrops(lab_percentages, 2)
......@@ -152,12 +173,21 @@ def profile(request):
final_score = ('?', '?')
final_percentage = 0
if settings.GENERATE_PROFILE_SCORES:
midterm_score = (random.randrange(50, 150), 150)
midterm_percentage = midterm_score[0] / float(midterm_score[1])
final_score = (random.randrange(100, 300), 300)
final_percentage = final_score[0] / float(final_score[1])
grade_summary = [
{
'category': 'Homework',
'subscores' : homework_percentages,
'dropped_indices' : homework_dropped_indices,
'totalscore' : {'score' : homework_total, 'summary' : "Homework Average - {0:.0%}".format(homework_total)},
'totallabel' : 'HW Avg',
'weight' : 0.15,
},
{
......@@ -165,16 +195,19 @@ def profile(request):
'subscores' : lab_percentages,
'dropped_indices' : lab_dropped_indices,
'totalscore' : {'score' : lab_total, 'summary' : "Lab Average - {0:.0%}".format(lab_total)},
'totallabel' : 'Lab Avg',
'weight' : 0.15,
},
{
'category': 'Midterm',
'totalscore' : {'score' : midterm_percentage, 'summary' : "Midterm - {0:.0%} ({1}/{2})".format(midterm_percentage, midterm_score[0], midterm_score[1])},
'totallabel' : 'Midterm',
'weight' : 0.30,
},
{
'category': 'Final',
'totalscore' : {'score' : final_percentage, 'summary' : "Final - {0:.0%} ({1}/{2})".format(final_percentage, final_score[0], final_score[1])},
'totallabel' : 'Final',
'weight' : 0.40,
}
]
......@@ -186,7 +219,7 @@ def profile(request):
'location':user_info.location,
'language':user_info.language,
'email':request.user.email,
'homeworks':hw,
'chapters':chapters,
'format_url_params' : format_url_params,
'grade_summary' : grade_summary,
'csrf':csrf(request)['csrf_token']
......
......@@ -14,6 +14,9 @@ LIB_URL = 'https://mitxstatic.s3.amazonaws.com/js/'
BOOK_URL = '/static/book/'
BOOK_URL = 'https://mitxstatic.s3.amazonaws.com/book_images/'
# Feature Flags. These should be set to false until they are ready to deploy, and then eventually flag mechanisms removed
GENERATE_PROFILE_SCORES = False # If this is true, random scores will be generated for the purpose of debugging the profile graphs
# Our parent dir (mitx_all) is the BASE_DIR
BASE_DIR = os.path.abspath(os.path.join(__file__, "..", ".."))
......
......@@ -14,7 +14,8 @@ valid_templates=['index.html',
'privacy.html',
'honor.html',
'copyright.html',
'404.html']
'404.html',
'mitx_help.html']
if settings.STATIC_GRAB:
valid_templates = valid_templates+['server-down.html',
......
# encoding: 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 'UserTestGroup'
db.create_table('student_usertestgroup', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=32, db_index=True)),
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('student', ['UserTestGroup'])
# Adding M2M table for field users on 'UserTestGroup'
db.create_table('student_usertestgroup_users', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('usertestgroup', models.ForeignKey(orm['student.usertestgroup'], null=False)),
('user', models.ForeignKey(orm['auth.user'], null=False))
))
db.create_unique('student_usertestgroup_users', ['usertestgroup_id', 'user_id'])
def backwards(self, orm):
# Deleting model 'UserTestGroup'
db.delete_table('student_usertestgroup')
# Removing M2M table for field users on 'UserTestGroup'
db.delete_table('student_usertestgroup_users')
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.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'}),
'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'}),
'meta': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': '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']
......@@ -27,6 +27,10 @@ class UserProfile(models.Model):
meta = models.CharField(blank=True, max_length=255) # JSON dictionary for future expansion
courseware = models.CharField(blank=True, max_length=255, default='course.xml')
class UserTestGroup(models.Model):
users = models.ManyToManyField(User, db_index=True)
name = models.CharField(blank=False, max_length=32, db_index=True)
description = models.TextField(blank=True)
class Registration(models.Model):
''' Allows us to wait for e-mail before user is registered. A
......
......@@ -32,23 +32,14 @@ def index(request):
else:
csrf_token = csrf(request)['csrf_token']
# TODO: Clean up how 'error' is done.
return render_to_response('index.html', {'error' : '',
'csrf': csrf_token })
return render_to_response('index.html', {'csrf': csrf_token })
# def courseinfo(request):
# if request.user.is_authenticated():
# return redirect('/courseware')
# else:
# csrf_token = csrf(request)['csrf_token']
# # TODO: Clean up how 'error' is done.
# return render_to_response('courseinfo.html', {'error' : '',
# 'csrf': csrf_token })
# Need different levels of logging
@ensure_csrf_cookie
def login_user(request, error=""):
if 'email' not in request.POST or 'password' not in request.POST:
return render_to_response('login.html', {'error':error.replace('+',' ')})
return HttpResponse(json.dumps({'success':False,
'error': 'Invalid login'})) # TODO: User error message
email = request.POST['email']
password = request.POST['password']
......@@ -136,9 +127,15 @@ def create_account(request, post_override=None):
# TODO: Confirm e-mail is not from a generic domain (mailinator, etc.)? Not sure if
# this is a good idea
# TODO: Check password is sane
for a in ['username', 'email', 'password', 'terms_of_service', 'honor_code']:
for a in ['username', 'email', 'name', 'password', 'terms_of_service', 'honor_code']:
if len(post_vars[a])<2:
js['value']="{field} is required.".format(field=a)
error_str = {'username' : 'Username of length 2 or greater',
'email' : 'Properly formatted e-mail',
'name' : 'Your legal name ',
'password': 'Valid password ',
'terms_of_service': 'Accepting Terms of Service',
'honor_code': 'Agreeing to the Honor Code'}
js['value']="{field} is required.".format(field=error_str[a])
return HttpResponse(json.dumps(js))
try:
......
import logging
from django.conf import settings
from django.http import HttpResponse
from django.http import HttpResponseServerError
log = logging.getLogger("mitx")
......@@ -12,4 +12,4 @@ class ExceptionLoggingMiddleware(object):
if not settings.TEMPLATE_DEBUG:
def process_exception(self, request, exception):
log.exception(exception)
return HttpResponse("Server Error - Please try again later.")
return HttpResponseServerError("Server Error - Please try again later.")
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