Commit c6d2ea6a by Bridger Maxwell

Merge with default branch

--HG--
branch : profiledev
parents c3a6ad2f 3a6a43c0
import uuid
from django.db import models
from django.contrib.auth.models import User
import uuid
class UserProfile(models.Model):
## CRITICAL TODO/SECURITY
......
from djangomako.shortcuts import render_to_response, render_to_string
from django.contrib.auth.models import User
from django.shortcuts import redirect
from django.contrib.auth import logout, authenticate, login
from django.contrib.auth.models import User
from django.http import HttpResponse
import json
from models import Registration, UserProfile
import logging
import random
import string
from django.conf import settings
from django.contrib.auth import logout, authenticate, login
from django.contrib.auth.models import User
from django.contrib.auth.models import User
from django.core.context_processors import csrf
from django.core.validators import validate_email, validate_slug
import random, string
from django.db import connection
from django.http import HttpResponse
from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string
from models import Registration, UserProfile
log = logging.getLogger("mitx.auth")
def csrf_token(context):
csrf_token = context.get('csrf_token', '')
......@@ -37,37 +42,43 @@ def index(request):
# return render_to_response('courseinfo.html', {'error' : '',
# 'csrf': csrf_token })
# Need different levels of logging
def login_user(request, error=""):
# print request.POST
if 'email' not in request.POST or 'password' not in request.POST:
# print "X"
return render_to_response('login.html', {'error':error.replace('+',' ')})
email = request.POST['email']
password = request.POST['password']
try:
user=User.objects.get(email=email)
user = User.objects.get(email=email)
except User.DoesNotExist:
log.warning("Login failed - Unknown user email: {0}".format(email))
return HttpResponse(json.dumps({'success':False,
'error': 'Invalid login'})) # TODO: User error message
username=user.username
user=authenticate(username=username, password=password)
username = user.username
user = authenticate(username=username, password=password)
if user is None:
log.warning("Login failed - password for {0} is invalid".format(email))
return HttpResponse(json.dumps({'success':False,
'error': 'Invalid login'}))
if user is not None and user.is_active:
try:
login(request, user)
if request.POST['remember'] == 'true':
request.session.set_expiry(None) # or change to 604800 for 7 days
# print "recall"
log.debug("Setting user session to never expire")
else:
request.session.set_expiry(0)
#print "close"
# print len(connection.queries), connection.queries
return HttpResponse(json.dumps({'success':True}))
except Exception as e:
log.critical("Login failed - Could not create session. Is memcached running?")
log.exception(e)
# print len(connection.queries), connection.queries
log.info("Login success - {0} ({1})".format(username, email))
return HttpResponse(json.dumps({'success':True}))
log.warning("Login failed - Account not active for user {0}".format(username))
return HttpResponse(json.dumps({'success':False,
'error': 'Account not active. Check your e-mail.'}))
......
import uuid
from django.db import models
from django.contrib.auth.models import User
import uuid
class ServerCircuit(models.Model):
# Later, add owner, who can edit, part of what app, etc.
......
from djangomako.shortcuts import render_to_response, render_to_string
from django.shortcuts import redirect
import json
import os
import xml.etree.ElementTree
from django.conf import settings
from django.http import Http404
from models import ServerCircuit
import json
import xml.etree.ElementTree
from django.http import HttpResponse
from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string
from models import ServerCircuit
def circuit_line(circuit):
''' Returns string for an appropriate input element for a circuit.
TODO: Rename. '''
if not circuit.isalnum():
raise Http404()
try:
sc = ServerCircuit.objects.get(name=circuit)
schematic = sc.schematic
print "Got"
except:
schematic = ''
print "not got"
print "X", schematic
circuit_line = xml.etree.ElementTree.Element('input')
circuit_line.set('type', 'hidden')
......
import math
import operator
from pyparsing import Word, alphas, nums, oneOf, Literal
from pyparsing import ZeroOrMore, OneOrMore, StringStart
from pyparsing import StringEnd, Optional, Forward
......
import random, numpy, math, scipy
import struct, os
import copy
import math
import numpy
import os
import random
import re
import scipy
import struct
from lxml import etree
from lxml.etree import Element
import copy
from mako.template import Template
from courseware.content_parser import xpath_remove
import calc, eia
from util import contextualize_text
from inputtypes import textline, schematic
from responsetypes import numericalresponse, formularesponse, customresponse, schematicresponse
import calc
import eia
response_types = {'numericalresponse':numericalresponse,
'formularesponse':formularesponse,
'customresponse':customresponse,
......@@ -52,12 +58,14 @@ class LoncapaProblem(object):
self.done = False
self.filename = filename
if id!=None:
if id:
self.problem_id = id
else:
self.problem_id = filename
print "NO ID"
raise Exception("This should never happen (183)")
#self.problem_id = filename
if state!=None:
if state:
if 'seed' in state:
self.seed = state['seed']
if 'student_answers' in state:
......@@ -68,7 +76,7 @@ class LoncapaProblem(object):
self.done = state['done']
# TODO: Does this deplete the Linux entropy pool? Is this fast enough?
if self.seed == None:
if not self.seed:
self.seed=struct.unpack('i', os.urandom(4))[0]
## Parse XML file
......@@ -102,7 +110,7 @@ class LoncapaProblem(object):
for key in self.correct_map:
if self.correct_map[key] == u'correct':
correct += 1
if self.student_answers == None or len(self.student_answers)==0:
if (not self.student_answers) or len(self.student_answers)==0:
return {'score':0,
'total':self.get_max_score()}
else:
......@@ -132,8 +140,8 @@ class LoncapaProblem(object):
for entry in problems_simple.xpath("//"+"|//".join(response_properties+entry_types)):
answer = entry.get('correct_answer')
if answer != None:
answer_map[entry.get('id')] = contextualize_text(answer, self.context())
if answer:
answer_map[entry.get('id')] = contextualize_text(answer, self.context)
return answer_map
......@@ -162,7 +170,7 @@ class LoncapaProblem(object):
status = self.correct_map[problemtree.get('id')]
value = ""
if self.student_answers != None and problemtree.get('id') in self.student_answers:
if self.student_answers and problemtree.get('id') in self.student_answers:
value = self.student_answers[problemtree.get('id')]
return html_special_response[problemtree.tag](problemtree, value, status) #TODO
......@@ -170,7 +178,7 @@ class LoncapaProblem(object):
tree=Element(problemtree.tag)
for item in problemtree:
subitems = self.extract_html(item)
if subitems != None:
if subitems:
for subitem in subitems:
tree.append(subitem)
for (key,value) in problemtree.items():
......
from djangomako.shortcuts import render_to_response, render_to_string
from lxml.etree import Element
from lxml import etree
from mitxmako.shortcuts import render_to_response, render_to_string
class textline(object):
@staticmethod
def render(element, value, state):
......
import random, numpy, math, scipy, json
from util import contextualize_text
import json
import math
import numpy
import random
import scipy
from calc import evaluator
import random, math
from django.conf import settings
from util import contextualize_text
import calc
import eia
# TODO: Should be the same object as in capa_problem
global_context={'random':random,
'numpy':numpy,
'math':math,
'scipy':scipy}
'scipy':scipy,
'calc':calc,
'eia':eia}
class numericalresponse(object):
def __init__(self, xml, context):
......
import math
import operator
from numpy import eye, array
from pyparsing import Word, alphas, nums, oneOf, Literal
from pyparsing import ZeroOrMore, OneOrMore, StringStart
from pyparsing import StringEnd, Optional, Forward
from pyparsing import CaselessLiteral, Group, StringEnd
from pyparsing import NoMatch, stringEnd
base_units = ['meter', 'gram', 'second', 'ampere', 'kelvin', 'mole', 'cd']
unit_vectors = dict([(base_units[i], eye(len(base_units))[:,i]) for i in range(len(base_units))])
def unit_evaluator(unit_string, units=unit_map):
''' Evaluate an expression. Variables are passed as a dictionary
from string to value. Unary functions are passed as a dictionary
from string to function '''
if string.strip() == "":
return float('nan')
ops = { "^" : operator.pow,
"*" : operator.mul,
"/" : operator.truediv,
}
prefixes={'%':0.01,'k':1e3,'M':1e6,'G':1e9,
'T':1e12,#'P':1e15,'E':1e18,'Z':1e21,'Y':1e24,
'c':1e-2,'m':1e-3,'u':1e-6,
'n':1e-9,'p':1e-12}#,'f':1e-15,'a':1e-18,'z':1e-21,'y':1e-24}
def super_float(text):
''' Like float, but with si extensions. 1k goes to 1000'''
if text[-1] in suffixes:
return float(text[:-1])*suffixes[text[-1]]
else:
return float(text)
def number_parse_action(x): # [ '7' ] -> [ 7 ]
return [super_float("".join(x))]
def exp_parse_action(x): # [ 2 ^ 3 ^ 2 ] -> 512
x = [e for e in x if type(e) == float] # Ignore ^
x.reverse()
x=reduce(lambda a,b:b**a, x)
return x
def parallel(x): # Parallel resistors [ 1 2 ] => 2/3
if len(x) == 1:
return x[0]
if 0 in x:
return float('nan')
x = [1./e for e in x if type(e) == float] # Ignore ^
return 1./sum(x)
def sum_parse_action(x): # [ 1 + 2 - 3 ] -> 0
total = 0.0
op = ops['+']
for e in x:
if e in set('+-'):
op = ops[e]
else:
total=op(total, e)
return total
def prod_parse_action(x): # [ 1 * 2 / 3 ] => 0.66
prod = 1.0
op = ops['*']
for e in x:
if e in set('*/'):
op = ops[e]
else:
prod=op(prod, e)
return prod
def func_parse_action(x):
return [functions[x[0]](x[1])]
number_suffix=reduce(lambda a,b:a|b, map(Literal,suffixes.keys()), NoMatch()) # SI suffixes and percent
(dot,minus,plus,times,div,lpar,rpar,exp)=map(Literal,".-+*/()^")
number_part=Word(nums)
inner_number = ( number_part+Optional("."+number_part) ) | ("."+number_part) # 0.33 or 7 or .34
number=Optional(minus | plus)+ inner_number + \
Optional(CaselessLiteral("E")+Optional("-")+number_part)+ \
Optional(number_suffix) # 0.33k or -17
number=number.setParseAction( number_parse_action ) # Convert to number
# Predefine recursive variables
expr = Forward()
factor = Forward()
def sreduce(f, l):
''' Same as reduce, but handle len 1 and len 0 lists sensibly '''
if len(l)==0:
return NoMatch()
if len(l)==1:
return l[0]
return reduce(f, l)
# 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(variables)>0:
varnames = sreduce(lambda x,y:x|y, map(lambda x: CaselessLiteral(x), variables.keys()))
varnames.setParseAction(lambda x:map(lambda y:variables[y], x))
else:
varnames=NoMatch()
# Same thing for functions.
if len(functions)>0:
funcnames = sreduce(lambda x,y:x|y, map(lambda x: CaselessLiteral(x), functions.keys()))
function = funcnames+lpar.suppress()+expr+rpar.suppress()
function.setParseAction(func_parse_action)
else:
function = NoMatch()
atom = number | varnames | lpar+expr+rpar | function
factor << (atom + ZeroOrMore(exp+atom)).setParseAction(exp_parse_action) # 7^6
paritem = factor + ZeroOrMore(Literal('||')+factor) # 5k || 4k
paritem=paritem.setParseAction(parallel)
term = paritem + ZeroOrMore((times|div)+paritem) # 7 * 5 / 4 - 3
term = term.setParseAction(prod_parse_action)
expr << Optional((plus|minus)) + term + ZeroOrMore((plus|minus)+term) # -5 + 4 - 3
expr=expr.setParseAction(sum_parse_action)
return (expr+stringEnd).parseString(string)[0]
if __name__=='__main__':
variables={'R1':2.0, 'R3':4.0}
functions={'sin':math.sin, 'cos':math.cos}
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({'a': 2.2997471478310274, 'k': 9, 'm': 8, 'x': 0.66009498411213041}, {}, "5")
print evaluator({},{}, "-1")
print evaluator({},{}, "-(7+5)")
print evaluator({},{}, "-0.33")
print evaluator({},{}, "-.33")
print evaluator({},{}, "5+7 QWSEKO")
try:
import json
import hashlib
import logging
from lxml import etree
try: # This lets us do __name__ == ='__main__'
from django.conf import settings
from auth.models import UserProfile
except:
settings = None
from lxml import etree
import json
import hashlib
import logging
''' This file will eventually form an abstraction layer between the
course XML file and the rest of the system.
......
from django.db import models
from django.contrib.auth.models import User
# class Organization(models.Model):
# # Tree structure implemented such that child node has left ID
# # greater than all parents, and right ID less than all parents
# left_tree_id = models.IntegerField(unique=True, db_index=True)
# right_tree_id = models.IntegerField(unique=True, db_index=True)
# # This is a duplicate, but we keep this to enforce unique name
# # constraint
# parent = models.ForeignKey('self', null=True, blank=True)
# name = models.CharField(max_length=200)
# ORG_TYPES= (('course','course'),
# ('chapter','chapter'),
# ('section','section'),)
# org_type = models.CharField(max_length=32, choices=ORG_TYPES)
# available = models.DateField(null=True, blank=True)
# due = models.DateField(null=True, blank=True)
# # JSON dictionary of metadata:
# # Time for a video, format of a section, etc.
# metadata = models.TextField(null=True, blank=True)
# class Modules(models.Model):
# MOD_TYPES = (('hw','homework'),
# ('vid','video_clip'),
# ('lay','layout'),
# (),)
# module_type = models.CharField(max_length=100)
# left_tree_id = models.IntegerField(unique=True, db_index=True)
# right_tree_id = models.IntegerField(unique=True, db_index=True)
# LAYOUT_TYPES = (('leaf','leaf'),
# ('tab','tab'),
# ('seq','sequential'),
# ('sim','simultaneous'),)
# layout_type = models.CharField(max_length=32, choices=LAYOUT_TYPES)
# data = models.TextField(null=True, blank=True)
#class HomeworkProblems(models.Model):
class StudentModule(models.Model):
# For a homework problem, contains a JSON
# object consisting of state
......
from django.http import HttpResponse
from django.template import Context, loader
from djangomako.shortcuts import render_to_response, render_to_string
import json, os, sys
from django.core.context_processors import csrf
import StringIO
import json
import os
import sys
import sys
import urllib
import uuid
from django.db import connection
from django.template import Context
from lxml import etree
from django.conf import settings
from django.contrib.auth.models import User
from auth.models import UserProfile
from django.core.context_processors import csrf
from django.db import connection
from django.http import Http404
from django.http import HttpResponse
from django.shortcuts import redirect
from django.template import Context
from django.template import Context, loader
from mitxmako.shortcuts import render_to_response, render_to_string
import StringIO
from auth.models import UserProfile
from models import StudentModule
import track.views
from django.http import Http404
import urllib
import courseware.content_parser as content_parser
import courseware.modules.capa_module
import courseware.modules.video_module
import courseware.modules.vertical_module
import courseware.modules.html_module
import courseware.modules.schematic_module
import courseware.modules.seq_module
from models import StudentModule
import urllib
from django.conf import settings
import courseware.content_parser as content_parser
import sys
import logging
from lxml import etree
import uuid
import courseware.modules.vertical_module
import courseware.modules.video_module
log = logging.getLogger("mitx.courseware")
......@@ -96,7 +89,7 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
ajax_return=instance.handle_ajax(dispatch, request.POST)
# Save the state back to the database
s.state=instance.get_state()
if instance.get_score() != None:
if not instance.get_score():
s.grade=instance.get_score()['score']
s.save()
# Return whatever the module wanted to return to the client/caller
......@@ -110,22 +103,14 @@ def render_x_module(user, request, xml_module, module_object_preload):
module_id=xml_module.get('id') #module_class.id_attribute) or ""
# Grab state from database
s = object_cache(module_object_preload,
smod = object_cache(module_object_preload,
user,
module_type,
module_id)
# s = StudentModule.objects.filter(student=request.user,
# module_id=module_id,
# module_type = module_type)
# if len(s) == 0:
# s=None
# else:
# s=s[0]
if s == None: # If nothing in the database...
if not smod: # If nothing in the database...
state=None
else:
smod = s
state = smod.state
# Create a new instance
......@@ -138,7 +123,7 @@ def render_x_module(user, request, xml_module, module_object_preload):
render_function = lambda x: render_module(user, request, x, module_object_preload))
# If instance wasn't already in the database, create it
if s == None:
if not smod:
smod=StudentModule(student=user,
module_type = module_type,
module_id=module_id,
......
import random, numpy, math, scipy, sys, StringIO, os, struct, json
from x_module import XModule
import sys
from courseware.capa.capa_problem import LoncapaProblem
from django.http import Http404
import StringIO
import datetime
import dateutil
import dateutil.parser
import datetime
import courseware.content_parser as content_parser
import json
import math
import numpy
import os
import random
import scipy
import struct
import sys
import traceback
from lxml import etree
## TODO: Abstract out from Django
from django.conf import settings
from djangomako.shortcuts import render_to_response, render_to_string
from mitxmako.shortcuts import render_to_response, render_to_string
from django.http import Http404
from x_module import XModule
from courseware.capa.capa_problem import LoncapaProblem
import courseware.content_parser as content_parser
class LoncapaModule(XModule):
''' Interface between capa_problem and x_module. Originally a hack
......@@ -231,6 +237,8 @@ class LoncapaModule(XModule):
for key in get:
answers['_'.join(key.split('_')[1:])]=get[key]
print "XXX", answers, get
event_info['answers']=answers
# Too late. Cannot submit
......@@ -255,6 +263,7 @@ class LoncapaModule(XModule):
correct_map = self.lcp.grade_answers(answers)
except:
self.lcp = LoncapaProblem(filename, id=lcp_id, state=old_state)
traceback.print_exc()
print {'error':sys.exc_info(),
'answers':answers,
'seed':self.lcp.seed,
......
from x_module import XModule
from lxml import etree
import json
## TODO: Abstract out from Django
from django.conf import settings
from djangomako.shortcuts import render_to_response, render_to_string
from mitxmako.shortcuts import render_to_response, render_to_string
from x_module import XModule
from lxml import etree
class HtmlModule(XModule):
id_attribute = 'filename'
......
from x_module import XModule
import json
## TODO: Abstract out from Django
from django.conf import settings
from djangomako.shortcuts import render_to_response, render_to_string
from mitxmako.shortcuts import render_to_response, render_to_string
from x_module import XModule
class SchematicModule(XModule):
id_attribute = 'id'
......
from x_module import XModule
from lxml import etree
from django.http import Http404
import json
from lxml import etree
## TODO: Abstract out from Django
from django.http import Http404
from django.conf import settings
from djangomako.shortcuts import render_to_response, render_to_string
from mitxmako.shortcuts import render_to_response, render_to_string
from x_module import XModule
class SequentialModule(XModule):
''' Layout module which lays out content in a temporal sequence
......
from x_module import XModule
from lxml import etree
import json
## TODO: Abstract out from Django
from django.conf import settings
from djangomako.shortcuts import render_to_response, render_to_string
from mitxmako.shortcuts import render_to_response, render_to_string
from x_module import XModule
from lxml import etree
class VerticalModule(XModule):
id_attribute = 'id'
......
from x_module import XModule
from lxml import etree
import json
import logging
from lxml import etree
## TODO: Abstract out from Django
from django.conf import settings
from djangomako.shortcuts import render_to_response, render_to_string
from mitxmako.shortcuts import render_to_response, render_to_string
from x_module import XModule
log = logging.getLogger("mitx.courseware.modules")
class VideoModule(XModule):
#id_attribute = 'youtube'
video_time = 0
def handle_ajax(self, dispatch, get):
print "GET", get
print "DISPATCH", dispatch
if dispatch=='goto_position':
log.debug(u"GET {0}".format(get))
log.debug(u"DISPATCH {0}".format(dispatch))
if dispatch == 'goto_position':
self.position = int(float(get['position']))
print "NEW POSITION", self.position
log.debug(u"NEW POSITION {0}".format(self.position))
return json.dumps({'success':True})
raise Http404()
def get_state(self):
print "STATE POSITION", self.position
log.debug(u"STATE POSITION {0}".format(self.position))
return json.dumps({ 'position':self.position })
def get_xml_tags():
''' Tags in the courseware file guaranteed to correspond to the module '''
'''Tags in the courseware file guaranteed to correspond to the module'''
return "video"
def video_list(self):
l=self.youtube.split(',')
l=[i.split(":") for i in l]
l = self.youtube.split(',')
l = [i.split(":") for i in l]
return json.dumps(dict(l))
def get_html(self):
......@@ -39,24 +43,25 @@ class VideoModule(XModule):
'position':self.position})
def get_init_js(self):
''' JavaScript code to be run when problem is shown. Be aware
'''JavaScript code to be run when problem is shown. Be aware
that this may happen several times on the same page
(e.g. student switching tabs). Common functions should be put
in the main course .js files for now. '''
print "INIT POSITION", self.position
log.debug(u"INIT POSITION {0}".format(self.position))
return render_to_string('video_init.js',{'streams':self.video_list(),
'id':self.item_id,
'position':self.position})
def get_destroy_js(self):
return "videoDestroy(\""+self.item_id+"\");"
return "videoDestroy(\"{0}\");".format(self.item_id)
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None, track_function=None, render_function = None):
XModule.__init__(self, xml, item_id, ajax_url, track_url, state, track_function, render_function)
self.youtube = etree.XML(xml).get('youtube')
self.position = 0
if state!=None:
if state != None:
state = json.loads(state)
if 'position' in state: self.position = int(float(state['position']))
print "POOSITION IN STATE"
print "LOAD POSITION", self.position
if 'position' in state:
self.position = int(float(state['position']))
log.debug("POSITION IN STATE")
log.debug(u"LOAD POSITION {0}".format(self.position))
import courseware.progress
def dummy_track(event_type, event):
pass
......@@ -12,6 +14,9 @@ class XModule(object):
''' Tags in the courseware file guaranteed to correspond to the module '''
return []
def get_completion(self):
return courseware.progress.completion()
def get_state(self):
return ""
......
class completion(object):
def __init__(self, d=None):
self.dict = dict()
def __init__(self, **d):
self.dict = dict({'duration_total':0,
'duration_watched':0,
'done':True,
'questions_correct':0,
'questions_incorrect':0,
'questions_total':0})
if d:
self.dict.update(d)
......@@ -11,9 +16,23 @@ class completion(object):
self.dict[key] = value
def __add__(self, other):
result = dict()
dict.update(self.dict)
dict.update(other.dict)
result = dict(self.dict)
for item in ['duration_total',
'duration_watched',
'done',
'questions_correct',
'questions_incorrect',
'questions_total']:
result[item] = result[item]+other.dict[item]
return completion(**result)
def __contains__(self, key):
pass
return key in dict
def __repr__(self):
return repr(self.dict)
if __name__ == '__main__':
dict1=completion(duration_total=5)
dict2=completion(duration_total=7)
print dict1+dict2
......@@ -12,16 +12,16 @@ from django.contrib.auth.models import User
from django.http import HttpResponse, Http404
from django.shortcuts import redirect
from django.template import Context, loader
from djangomako.shortcuts import render_to_response, render_to_string
from mitxmako.shortcuts import render_to_response, render_to_string
from django.db import connection
from lxml import etree
from auth.models import UserProfile
from models import StudentModule
from module_render import * # TODO: Clean up
from module_render import modx_dispatch
from module_render import render_module, modx_dispatch
import courseware.content_parser as content_parser
import courseware.modules.capa_module
log = logging.getLogger("mitx.courseware")
......@@ -36,10 +36,6 @@ def profile(request):
if not request.user.is_authenticated():
return redirect('/')
log.info("Profile called")
logging.info("Now the root")
logging.getLogger("tracking").info("this should be unformatted")
dom=content_parser.course_file(request.user)
hw=[]
course = dom.xpath('//course/@name')[0]
......@@ -146,6 +142,7 @@ def index(request, course="6.002 Spring 2012", chapter="Using the System", secti
module_object_preload = list(StudentModule.objects.filter(student=user,
module_id__in=module_ids))
module=render_module(user, request, module, module_object_preload)
if 'init_js' not in module:
......
================================================================================
django-mako
================================================================================
This module provides a drop in replacement of Django templates for Mako
Templates.
Django: http://www.djangoproject.com/
Mako: http://www.makotemplates.org/
================================================================================
How to install?
================================================================================
$ sudo python setup.py install
# Copyright (c) 2008 Mikeal Rogers
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
lookup = None
# Copyright (c) 2008 Mikeal Rogers
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from mako.lookup import TemplateLookup
import tempfile
from django.template import RequestContext
requestcontext = None
lookup = None
class MakoMiddleware(object):
def __init__(self):
"""Setup mako variables and lookup object"""
from django.conf import settings
# Set all mako variables based on django settings
global template_dirs, output_encoding, module_directory, encoding_errors
directories = getattr(settings, 'MAKO_TEMPLATE_DIRS', settings.TEMPLATE_DIRS)
module_directory = getattr(settings, 'MAKO_MODULE_DIR', None)
if module_directory is None:
module_directory = tempfile.mkdtemp()
output_encoding = getattr(settings, 'MAKO_OUTPUT_ENCODING', 'utf-8')
encoding_errors = getattr(settings, 'MAKO_ENCODING_ERRORS', 'replace')
global lookup
lookup = TemplateLookup(directories=directories,
module_directory=module_directory,
output_encoding=output_encoding,
encoding_errors=encoding_errors,
)
import mitxmako
mitxmako.lookup = lookup
def process_request (self, request):
global requestcontext
requestcontext = RequestContext(request)
# print requestcontext
# Copyright (c) 2008 Mikeal Rogers
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from django.template import Context
from django.http import HttpResponse
import mitxmako.middleware as middleware
from django.conf import settings
from mitxmako.middleware import requestcontext
def render_to_string(template_name, dictionary, context_instance=None):
context_instance = context_instance or Context(dictionary)
# add dictionary to context_instance
context_instance.update(dictionary or {})
# collapse context_instance to a single dictionary for mako
context_dictionary = {}
context_instance['settings'] = settings
context_instance['request_context'] = requestcontext
for d in context_instance:
context_dictionary.update(d)
# fetch and render template
template = middleware.lookup.get_template(template_name)
return template.render(**context_dictionary)
def render_to_response(template_name, dictionary, context_instance=None, **kwargs):
"""
Returns a HttpResponse whose content is filled with the result of calling
lookup.get_template(args[0]).render with the passed arguments.
"""
return HttpResponse(render_to_string(template_name, dictionary, context_instance), **kwargs)
# Copyright (c) 2008 Mikeal Rogers
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from mako.template import Template as MakoTemplate
import middleware
django_variables = ['lookup', 'template_dirs', 'output_encoding',
'module_directory', 'encoding_errors',]
class Template(MakoTemplate):
def __init__(self, *args, **kwargs):
"""Overrides base __init__ to provide django variable overrides"""
if not kwargs.get('no_django', False):
overrides = dict([(k, getattr(middleware, k, None),) for k in django_variables])
kwargs.update(overrides)
super(Template, self).__init__(*args, **kwargs)
import views, json, tempfile, time
import json
import tempfile
import time
from django.conf import settings
from django.db import connection
import views
class ProfileMiddleware:
def process_request (self, request):
......
# Create your views here.
import middleware
from django.http import HttpResponse
def end_profile(request):
......
......@@ -3,12 +3,16 @@ import sys
import djcelery
LIB_URL = '/static/lib/'
LIB_URL = 'http://mitxstatic.s3-website-us-east-1.amazonaws.com/js/'
BOOK_URL = '/static/book/'
BOOK_URL = 'http://mitxstatic.s3-website-us-east-1.amazonaws.com/book_images/'
# Our parent dir (mitx_all) is the BASE_DIR
BASE_DIR = os.path.abspath(os.path.join(__file__, "..", ".."))
COURSEWARE_ENABLED = True
ASKBOT_ENABLED = True
CSRF_COOKIE_DOMAIN = '127.0.0.1'
# Defaults to be overridden
......@@ -34,7 +38,7 @@ DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
('Piotr Mitros', 'pmitros@csail.mit.edu'),
('Piotr Mitros', 'staff@csail.mit.edu'),
)
MANAGERS = ADMINS
......@@ -56,87 +60,6 @@ USE_I18N = True
# calendars according to the current locale
USE_L10N = True
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters' : {
'standard' : {
'format' : '%(levelname)s %(asctime)s PID:%(process)d %(name)s %(filename)s:%(lineno)d %(message)s',
},
'raw' : {
'format' : '%(message)s',
}
},
'handlers' : {
'console' : {
'level' : 'DEBUG' if DEBUG else 'INFO',
'class' : 'logging.StreamHandler',
'formatter' : 'standard',
'stream' : sys.stdout,
},
'console_err' : {
'level' : 'ERROR',
'class' : 'logging.StreamHandler',
'formatter' : 'standard',
'stream' : sys.stderr,
},
# 'app' : {
# 'level' : 'INFO',
# 'class' : 'logging.handlers.TimedRotatingFileHandler',
# 'formatter' : 'standard',
# 'filename' : '/tmp/mitx.log', # temporary location for proof of concept
# 'when' : 'midnight',
# 'utc' : True,
# 'encoding' : 'utf-8',
# },
# We should actually use this for tracking:
# http://pypi.python.org/pypi/ConcurrentLogHandler/0.8.2
'tracking' : {
'level' : 'INFO',
'class' : 'logging.handlers.TimedRotatingFileHandler',
'formatter' : 'raw',
'filename' : BASE_DIR + '/track_dir/tracking.log',
'when' : 'midnight',
'utc' : True,
'encoding' : 'utf-8',
},
'mail_admins' : {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
},
},
'loggers' : {
'django.request': {
'handlers': ['mail_admins', 'console', 'console_err'],
'level': 'INFO',
'propagate': True,
},
'tracking' : {
'handlers' : ['tracking'],
'level' : 'DEBUG',
'propagate' : False,
},
'root' : {
'handlers' : ['console', 'console_err'],
'level' : 'DEBUG',
'propagate' : False
},
'mitx' : {
'handlers' : ['console', 'console_err'],
'level' : 'DEBUG',
'propagate' : False
},
}
}
STATIC_URL = '/static/'
# URL prefix for admin static files -- CSS, JavaScript and images.
......@@ -166,7 +89,7 @@ MIDDLEWARE_CLASSES = (
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'track.middleware.TrackMiddleware',
'djangomako.middleware.MakoMiddleware',
'mitxmako.middleware.MakoMiddleware',
#'debug_toolbar.middleware.DebugToolbarMiddleware',
)
......@@ -188,6 +111,7 @@ INSTALLED_APPS = (
'track',
'circuit',
'perfstats',
'util',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
......@@ -201,9 +125,94 @@ TRACK_MAX_EVENT = 1000
# Maximum length of log file before starting a new one.
MAXLOG = 500
LOG_DIR = "/tmp/"
# Make sure we execute correctly regardless of where we're called from
execfile(os.path.join(BASE_DIR, "settings.py"))
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters' : {
'standard' : {
'format' : '%(asctime)s %(levelname)s %(process)d [%(name)s] %(filename)s:%(lineno)d - %(message)s',
},
'raw' : {
'format' : '%(message)s',
}
},
'handlers' : {
'console' : {
'level' : 'DEBUG' if DEBUG else 'INFO',
'class' : 'logging.StreamHandler',
'formatter' : 'standard',
'stream' : sys.stdout,
},
'console_err' : {
'level' : 'ERROR',
'class' : 'logging.StreamHandler',
'formatter' : 'standard',
'stream' : sys.stderr,
},
'app' : {
'level' : 'DEBUG' if DEBUG else 'INFO',
'class' : 'logging.handlers.WatchedFileHandler',
'formatter' : 'standard',
'filename' : LOG_DIR + '/mitx.log', # temporary location for proof of concept
'encoding' : 'utf-8',
},
'app_err' : {
'level' : 'WARNING',
'class' : 'logging.handlers.WatchedFileHandler',
'formatter' : 'standard',
'filename' : LOG_DIR + '/mitx.err.log', # temporary location for proof of concept
'encoding' : 'utf-8',
},
# We should actually use this for tracking:
# http://pypi.python.org/pypi/ConcurrentLogHandler/0.8.2
'tracking' : {
'level' : 'INFO',
'class' : 'logging.handlers.WatchedFileHandler',
'formatter' : 'raw',
'filename' : LOG_DIR + '/tracking.log',
'encoding' : 'utf-8',
},
'mail_admins' : {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
},
},
'loggers' : {
'django' : {
'handlers' : ['console', 'mail_admins', 'app_err'],
'propagate' : True,
'level' : 'INFO'
},
'tracking' : {
'handlers' : ['console', 'tracking'],
'level' : 'DEBUG',
'propagate' : False,
},
'root' : {
'handlers' : ['console', 'app', 'app_err'],
'level' : 'DEBUG',
'propagate' : False
},
'mitx' : {
'handlers' : ['console', 'app', 'app_err'],
'level' : 'DEBUG',
'propagate' : False
},
}
}
if PERFSTATS :
MIDDLEWARE_CLASSES = ( 'perfstats.middleware.ProfileMiddleware',) + MIDDLEWARE_CLASSES
......@@ -252,6 +261,7 @@ site.addsitedir(os.path.join(os.path.dirname(askbot.__file__), 'deps'))
TEMPLATE_LOADERS = TEMPLATE_LOADERS + ('askbot.skins.loaders.filesystem_load_template_source',)
MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES + (
'util.middleware.ExceptionLoggingMiddleware',
'askbot.middleware.anon_user.ConnectToSessionMessagesMiddleware',
'askbot.middleware.forum_mode.ForumModeMiddleware',
'askbot.middleware.cancel.CancelActionMiddleware',
......@@ -312,3 +322,4 @@ BROKER_TRANSPORT = "djkombu.transport.DatabaseTransport"
CELERY_ALWAYS_EAGER = True
djcelery.setup_loader()
......@@ -26,7 +26,7 @@ DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
('Piotr Mitros', 'pmitros@csail.mit.edu'),
('Piotr Mitros', 'staff@csail.mit.edu'),
)
MANAGERS = ADMINS
......@@ -81,7 +81,7 @@ MIDDLEWARE_CLASSES = (
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'track.middleware.TrackMiddleware',
'djangomako.middleware.MakoMiddleware',
'mitxmako.middleware.MakoMiddleware',
#'debug_toolbar.middleware.DebugToolbarMiddleware',
)
......
# Source: django-simplewiki. GPL license.
import sys, os
import os
import sys
# allow mdx_* parsers to be just dropped in the simplewiki folder
module_path = os.path.abspath(os.path.dirname(__file__))
......
# Source: django-simplewiki. GPL license.
from django.contrib import admin
from django import forms
from django.contrib import admin
from django.utils.translation import ugettext as _
from models import Article, Revision, Permission, ArticleAttachment
class RevisionInline(admin.TabularInline):
......
......@@ -8,7 +8,7 @@ circuit:name becomes the circuit.
import simplewiki.settings as settings
from djangomako.shortcuts import render_to_response, render_to_string
from mitxmako.shortcuts import render_to_response, render_to_string
import markdown
try:
......
from django.utils.translation import ugettext_lazy as _
import difflib
import os
from django import forms
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import signals
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from markdown import markdown
from django import forms
from django.core.urlresolvers import reverse
import difflib
import os
from settings import *
class ShouldHaveExactlyOneRootSlug(Exception):
......
from django import template
from django.template.defaultfilters import stringfilter
from simplewiki.settings import *
from django.conf import settings
from django.template.defaultfilters import stringfilter
from django.utils.http import urlquote as django_urlquote
from simplewiki.settings import *
register = template.Library()
@register.filter()
......
......@@ -3,6 +3,7 @@ from django.conf.urls.defaults import *
urlpatterns = patterns('',
url(r'^$', 'simplewiki.views.root_redirect', name='wiki_root'),
url(r'^view(/[a-zA-Z\d/_-]*)/?$', 'simplewiki.views.view', name='wiki_view'),
url(r'^view_revision/([0-9]*)(/[a-zA-Z\d/_-]*)/?$', 'simplewiki.views.view_revision', name='wiki_view_revision'),
url(r'^edit(/[a-zA-Z\d/_-]*)/?$', 'simplewiki.views.edit', name='wiki_edit'),
url(r'^create(/[a-zA-Z\d/_-]*)/?$', 'simplewiki.views.create', name='wiki_create'),
url(r'^history(/[a-zA-Z\d/_-]*)/([0-9]*)/?$', 'simplewiki.views.history', name='wiki_history'),
......
# -*- coding: utf-8 -*-
import types
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.context_processors import csrf
from django.core.urlresolvers import get_callable
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseServerError, HttpResponseForbidden, HttpResponseNotAllowed
from django.utils import simplejson
from djangomako.shortcuts import render_to_response, render_to_string
from django.shortcuts import get_object_or_404
from django.template import RequestContext, Context, loader
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.conf import settings
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseServerError, HttpResponseForbidden, HttpResponseNotAllowed
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.shortcuts import redirect
from django.core.context_processors import csrf
from django.template import Context
from django.http import HttpResponse
import djangomako.middleware
from mako.template import Template
from django.template import RequestContext, Context, loader
from django.utils import simplejson
from django.utils.translation import ugettext_lazy as _
from mitxmako.shortcuts import render_to_response, render_to_string
from mako.lookup import TemplateLookup
from mako.template import Template
import mitxmako.middleware
from models import *
from models import * # TODO: Clean up
from settings import *
def view(request, wiki_url):
......@@ -36,6 +35,7 @@ def view(request, wiki_url):
if perm_err:
return perm_err
d = {'wiki_article': article,
'wiki_article_revision':article.current_revision,
'wiki_write': article.can_write_l(request.user),
'wiki_attachments_write': article.can_attach(request.user),
'wiki_current_revision_deleted' : not (article.current_revision.deleted == 0),
......@@ -43,6 +43,37 @@ def view(request, wiki_url):
d.update(csrf(request))
return render_to_response('simplewiki_view.html', d)
def view_revision(request, revision_number, wiki_url, revision=None):
if not request.user.is_authenticated():
return redirect('/')
(article, path, err) = fetch_from_url(request, wiki_url)
if err:
return err
try:
revision = Revision.objects.get(counter=int(revision_number), article=article)
except:
d = {'wiki_article': article,
'wiki_err_norevision': revision_number,}
d.update(csrf(request))
return render_to_response('simplewiki_error.html', d)
perm_err = check_permissions(request, article, check_read=True, check_deleted=True, revision=revision)
if perm_err:
return perm_err
d = {'wiki_article': article,
'wiki_article_revision':revision,
'wiki_write': article.can_write_l(request.user),
'wiki_attachments_write': article.can_attach(request.user),
'wiki_current_revision_deleted' : not (revision.deleted == 0),
}
d.update(csrf(request))
return render_to_response('simplewiki_view.html', d)
def root_redirect(request):
if not request.user.is_authenticated():
return redirect('/')
......@@ -206,12 +237,18 @@ def history(request, wiki_url, page=1):
perm_err = check_permissions(request, article, check_write=True, check_locked=True)
if perm_err:
return perm_err
redirectURL = reverse('wiki_view', args=(article.get_url(),))
try:
r = int(request.POST['revision'])
revision = Revision.objects.get(id=r)
if request.POST.__contains__('change'):
article.current_revision = revision
article.save()
elif request.POST.__contains__('view'):
redirectURL = reverse('wiki_view_revision', args=(revision.counter, article.get_url(),))
#The rese of these are admin functions
elif request.POST.__contains__('delete') and request.user.is_superuser:
if (revision.deleted == 0):
revision.adminSetDeleted(2)
......@@ -228,7 +265,7 @@ def history(request, wiki_url, page=1):
except:
pass
finally:
return HttpResponseRedirect(reverse('wiki_view', args=(article.get_url(),)))
return HttpResponseRedirect(redirectURL)
#
#
# <input type="submit" name="delete" value="Delete revision"/>
......@@ -433,14 +470,16 @@ def fetch_from_url(request, url):
return (article, path, err)
def check_permissions(request, article, check_read=False, check_write=False, check_locked=False, check_deleted=False):
def check_permissions(request, article, check_read=False, check_write=False, check_locked=False, check_deleted=False, revision = None):
read_err = check_read and not article.can_read(request.user)
write_err = check_write and not article.can_write(request.user)
locked_err = check_locked and article.locked
deleted_err = check_deleted and not (article.current_revision.deleted == 0)
if revision == None:
revision = article.current_revision
deleted_err = check_deleted and not (revision.deleted == 0)
if (request.user.is_superuser):
deleted_err = False
locked_err = False
......
import os
from django.contrib.auth.decorators import login_required
from django.core.servers.basehttp import FileWrapper
from django.db.models.fields.files import FieldFile
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
from django.template import loader, Context
from django.db.models.fields.files import FieldFile
from django.core.servers.basehttp import FileWrapper
from django.contrib.auth.decorators import login_required
from settings import *
from settings import * # TODO: Clean up
from models import Article, ArticleAttachment, get_attachment_filepath
from views import not_found, check_permissions, get_url_path, fetch_from_url
import os
from simplewiki.settings import WIKI_ALLOW_ANON_ATTACHMENTS
......
......@@ -3,7 +3,7 @@
# List of valid templates is explicitly managed for (short-term)
# security reasons.
from djangomako.shortcuts import render_to_response, render_to_string
from mitxmako.shortcuts import render_to_response, render_to_string
from django.shortcuts import redirect
from django.core.context_processors import csrf
......
# Create your views here.
from djangomako.shortcuts import render_to_response, render_to_string
from django.shortcuts import redirect
import os
from django.conf import settings
from django.http import Http404
from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string
def index(request, page=1):
def index(request, page=0):
if not request.user.is_authenticated():
return redirect('/')
return render_to_response('staticbook.html',{'page':int(page)})
def index_shifted(request, page):
return index(request, int(page)+24)
import views, json
import json
from django.conf import settings
import views
class TrackMiddleware:
def process_request (self, request):
def process_request(self, request):
try:
# We're already logging events
if request.META['PATH_INFO'] == '/event':
# We're already logging events, and we don't want to capture user
# names/passwords.
if request.META['PATH_INFO'] in ['/event', '/login']:
return
event = { 'GET' : dict(request.GET),
......
import json
import logging
import os
# Create your views here.
from django.http import HttpResponse
from django.http import Http404
from django.conf import settings
import json, os, stat
import tempfile
if settings.TRACK_DIR != None:
directory = tempfile.mkdtemp(prefix = settings.TRACK_DIR)
else:
directory = None
logfile = None
file_index = 0
log_index = 0
filename = None
def make_file():
global logfile, log_index, file_index, filename
if logfile != None:
logfile.close()
os.chmod(filename, stat.S_IRUSR | stat.S_IWUSR | \
stat.S_IRGRP | stat.S_IWGRP | \
stat.S_IROTH )
filename = directory+"/%05i"%(file_index)+".trklog"
logfile = open(filename, "w")
file_index = file_index + 1
log_index = 0
log = logging.getLogger("tracking")
def log_event(event):
global logfile, log_index
event_str = json.dumps(event)
if settings.TRACK_DIR == None:
# print event
return
if logfile == None or log_index >= settings.MAXLOG:
make_file()
logfile.write(event_str[:settings.TRACK_MAX_EVENT]+'\n')
if settings.DEBUG_TRACK_LOG:
print event_str
log_index = log_index + 1
log.info(event_str[:settings.TRACK_MAX_EVENT])
def user_track(request):
try: # TODO: Do the same for many of the optional META parameters
......@@ -49,15 +19,25 @@ def user_track(request):
except:
username = "anonymous"
try:
scookie = request.META['HTTP_COOKIE']
except:
scookie = ""
try:
agent = request.META['HTTP_USER_AGENT']
except:
agent = ''
# TODO: Move a bunch of this into log_event
event = {
"username" : username,
"session" : request.META['HTTP_COOKIE'],
"session" : scookie,
"ip" : request.META['REMOTE_ADDR'],
"event_source" : "browser",
"event_type" : request.GET['event_type'],
"event" : request.GET['event'],
"agent" : request.META['HTTP_USER_AGENT'],
"agent" : agent,
"page" : request.GET['page'],
}
log_event(event)
......@@ -69,13 +49,18 @@ def server_track(request, event_type, event, page=None):
except:
username = "anonymous"
try:
agent = request.META['HTTP_USER_AGENT']
except:
agent = ''
event = {
"username" : username,
"ip" : request.META['REMOTE_ADDR'],
"event_source" : "server",
"event_type" : event_type,
"event" : event,
"agent" : request.META['HTTP_USER_AGENT'],
"agent" : agent,
"page" : page,
}
log_event(event)
from django.conf.urls.defaults import patterns, include, url
import django.contrib.auth.views
from django.conf import settings
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
import perfstats
import django.contrib.auth.views
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
......@@ -19,7 +18,7 @@ urlpatterns = ('',
url(r'^activate/(?P<key>[^/]*)$', 'auth.views.activate_account'),
url(r'^$', 'auth.views.index'),
url(r'^password_reset/$', 'django.contrib.auth.views.password_reset',
dict(from_email='6002-admin@mit.edu'),name='auth_password_reset'),
dict(from_email='registration@mitx.mit.edu'),name='auth_password_reset'),
url(r'^password_change/$',django.contrib.auth.views.password_change,name='auth_password_change'),
url(r'^password_change_done/$',django.contrib.auth.views.password_change_done,name='auth_password_change_done'),
url(r'^password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',django.contrib.auth.views.password_reset_confirm,
......@@ -29,14 +28,14 @@ urlpatterns = ('',
url(r'^password_reset_done/$',django.contrib.auth.views.password_reset_done,
name='auth_password_reset_done'),
url(r'^send_feedback$', 'util.views.send_feedback'),
url(r'^courseware/$', 'courseware.views.index'),
)
if settings.PERFSTATS:
urlpatterns=urlpatterns + (url(r'^reprofile$','perfstats.views.end_profile'),)
if settings.COURSEWARE_ENABLED:
urlpatterns=urlpatterns + (url(r'^wiki/', include('simplewiki.urls')),
urlpatterns=urlpatterns + ( url(r'^courseware/$', 'courseware.views.index'),
url(r'^wiki/', include('simplewiki.urls')),
url(r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$', 'courseware.views.index'),
url(r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/$', 'courseware.views.index'),
url(r'^courseware/(?P<course>[^/]*)/$', 'courseware.views.index'),
......@@ -45,6 +44,7 @@ if settings.COURSEWARE_ENABLED:
url(r'^change_setting$', 'auth.views.change_setting'),
url(r'^s/(?P<template>[^/]*)$', 'static_template_view.views.auth_index'),
url(r'^book/(?P<page>[^/]*)$', 'staticbook.views.index'),
url(r'^book-shifted/(?P<page>[^/]*)$', 'staticbook.views.index_shifted'),
url(r'^book*$', 'staticbook.views.index'),
# url(r'^course_info/$', 'auth.views.courseinfo'),
# url(r'^show_circuit/(?P<circuit>[^/]*)$', 'circuit.views.show_circuit'),
......
import logging
from django.http import HttpResponse
log = logging.getLogger("mitx")
class ExceptionLoggingMiddleware(object):
"""Just here to log unchecked exceptions that go all the way up the Django
stack"""
def process_exception(self, request, exception):
log.exception(exception)
return HttpResponse("Server Error - Please try again later.")
from djangomako.shortcuts import render_to_response, render_to_string
from django.shortcuts import redirect
from django.contrib.auth.models import User
from django.http import HttpResponse
import datetime
import json
import sys
from django.conf import settings
from django.conf import settings
from django.contrib.auth.models import User
from django.core.context_processors import csrf
from django.core.mail import send_mail
from django.http import Http404
from django.http import HttpResponse
from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string
import courseware.capa.calc
from django.core.mail import send_mail
from django.conf import settings
import datetime
import sys
import track.views
def calculate(request):
# if not request.user.is_authenticated():
# raise Http404
''' Calculator in footer of every page. '''
equation = request.GET['equation']
try:
result = courseware.capa.calc.evaluator({}, {}, equation)
......@@ -27,8 +28,7 @@ def calculate(request):
return HttpResponse(json.dumps({'result':result}))
def send_feedback(request):
# if not request.user.is_authenticated():
# raise Http404
''' Feeback mechanism in footer of every page. '''
try:
username = request.user.username
except:
......@@ -50,4 +50,5 @@ def send_feedback(request):
return HttpResponse(json.dumps({'success':True}))
def info(request):
''' Info page (link from main header) '''
return render_to_response("info.html", {})
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