Cleaning up pep8 violations
This commit is contained in:
@@ -13,6 +13,7 @@ from django.db import DEFAULT_DB_ALIAS
|
||||
|
||||
from . import app_settings
|
||||
|
||||
|
||||
def get_instance(model, instance_or_pk, timeout=None, using=None):
|
||||
"""
|
||||
Returns the ``model`` instance with a primary key of ``instance_or_pk``.
|
||||
@@ -87,6 +88,7 @@ def get_instance(model, instance_or_pk, timeout=None, using=None):
|
||||
|
||||
return instance
|
||||
|
||||
|
||||
def delete_instance(model, *instance_or_pk):
|
||||
"""
|
||||
Purges the cache keys for the instances of this model.
|
||||
@@ -94,6 +96,7 @@ def delete_instance(model, *instance_or_pk):
|
||||
|
||||
cache.delete_many([instance_key(model, x) for x in instance_or_pk])
|
||||
|
||||
|
||||
def instance_key(model, instance_or_pk):
|
||||
"""
|
||||
Returns the cache key for this (model, instance) pair.
|
||||
|
||||
@@ -84,6 +84,7 @@ from django.contrib.auth.middleware import AuthenticationMiddleware
|
||||
|
||||
from .model import cache_model
|
||||
|
||||
|
||||
class CacheBackedAuthenticationMiddleware(AuthenticationMiddleware):
|
||||
def __init__(self):
|
||||
cache_model(User)
|
||||
|
||||
@@ -58,6 +58,7 @@ from django.db.models.signals import post_save, post_delete
|
||||
|
||||
from .core import get_instance, delete_instance
|
||||
|
||||
|
||||
def cache_model(model, timeout=None):
|
||||
if hasattr(model, 'get_cached'):
|
||||
# Already patched
|
||||
|
||||
@@ -74,6 +74,7 @@ from django.db.models.signals import post_save, post_delete
|
||||
|
||||
from .core import get_instance, delete_instance
|
||||
|
||||
|
||||
def cache_relation(descriptor, timeout=None):
|
||||
rel = descriptor.related
|
||||
related_name = '%s_cache' % rel.field.related_query_name()
|
||||
|
||||
@@ -5,6 +5,7 @@ from django.template import resolve_variable
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
class CacheNode(Node):
|
||||
def __init__(self, nodelist, expire_time, key):
|
||||
self.nodelist = nodelist
|
||||
@@ -21,6 +22,7 @@ class CacheNode(Node):
|
||||
cache.set(key, value, expire_time)
|
||||
return value
|
||||
|
||||
|
||||
@register.tag
|
||||
def cachedeterministic(parser, token):
|
||||
"""
|
||||
@@ -42,6 +44,7 @@ def cachedeterministic(parser, token):
|
||||
raise TemplateSyntaxError(u"'%r' tag requires 2 arguments." % tokens[0])
|
||||
return CacheNode(nodelist, tokens[1], tokens[2])
|
||||
|
||||
|
||||
class ShowIfCachedNode(Node):
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
@@ -50,6 +53,7 @@ class ShowIfCachedNode(Node):
|
||||
key = resolve_variable(self.key, context)
|
||||
return cache.get(key) or ''
|
||||
|
||||
|
||||
@register.tag
|
||||
def showifcached(parser, token):
|
||||
"""
|
||||
|
||||
@@ -60,6 +60,7 @@ def csrf_response_exempt(view_func):
|
||||
PendingDeprecationWarning)
|
||||
return view_func
|
||||
|
||||
|
||||
def csrf_view_exempt(view_func):
|
||||
"""
|
||||
Marks a view function as being exempt from CSRF view protection.
|
||||
@@ -68,6 +69,7 @@ def csrf_view_exempt(view_func):
|
||||
PendingDeprecationWarning)
|
||||
return csrf_exempt(view_func)
|
||||
|
||||
|
||||
def csrf_exempt(view_func):
|
||||
"""
|
||||
Marks a view function as being exempt from the CSRF view protection.
|
||||
|
||||
@@ -6,6 +6,7 @@ from pipeline.conf import settings
|
||||
from pipeline.packager import Packager
|
||||
from pipeline.utils import guess_type
|
||||
|
||||
|
||||
def compressed_css(package_name):
|
||||
package = settings.PIPELINE_CSS.get(package_name, {})
|
||||
if package:
|
||||
@@ -20,6 +21,7 @@ def compressed_css(package_name):
|
||||
paths = packager.compile(package.paths)
|
||||
return render_individual_css(package, paths)
|
||||
|
||||
|
||||
def render_css(package, path):
|
||||
template_name = package.template_name or "mako/css.html"
|
||||
context = package.extra_context
|
||||
@@ -29,6 +31,7 @@ def render_css(package, path):
|
||||
})
|
||||
return render_to_string(template_name, context)
|
||||
|
||||
|
||||
def render_individual_css(package, paths):
|
||||
tags = [render_css(package, path) for path in paths]
|
||||
return '\n'.join(tags)
|
||||
@@ -49,6 +52,7 @@ def compressed_js(package_name):
|
||||
templates = packager.pack_templates(package)
|
||||
return render_individual_js(package, paths, templates)
|
||||
|
||||
|
||||
def render_js(package, path):
|
||||
template_name = package.template_name or "mako/js.html"
|
||||
context = package.extra_context
|
||||
@@ -58,6 +62,7 @@ def render_js(package, path):
|
||||
})
|
||||
return render_to_string(template_name, context)
|
||||
|
||||
|
||||
def render_inline_js(package, js):
|
||||
context = package.extra_context
|
||||
context.update({
|
||||
@@ -65,6 +70,7 @@ def render_inline_js(package, js):
|
||||
})
|
||||
return render_to_string("mako/inline_js.html", context)
|
||||
|
||||
|
||||
def render_individual_js(package, paths, templates=None):
|
||||
tags = [render_js(package, js) for js in paths]
|
||||
if templates:
|
||||
|
||||
@@ -15,4 +15,3 @@ admin.site.register(CourseEnrollment)
|
||||
admin.site.register(Registration)
|
||||
|
||||
admin.site.register(PendingNameChange)
|
||||
|
||||
|
||||
@@ -25,27 +25,29 @@ import mitxmako.middleware as middleware
|
||||
|
||||
middleware.MakoMiddleware()
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = \
|
||||
'''Exports all users and user profiles.
|
||||
'''Exports all users and user profiles.
|
||||
Caveat: Should be looked over before any run
|
||||
for schema changes.
|
||||
for schema changes.
|
||||
|
||||
Current version grabs user_keys from
|
||||
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',
|
||||
|
||||
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']
|
||||
|
||||
up_keys = ['language', 'location', 'meta', 'name', 'id', 'user_id']
|
||||
|
||||
def extract_dict(keys, object):
|
||||
d = {}
|
||||
for key in keys:
|
||||
|
||||
@@ -22,6 +22,7 @@ import mitxmako.middleware as middleware
|
||||
|
||||
middleware.MakoMiddleware()
|
||||
|
||||
|
||||
def import_user(u):
|
||||
user_info = u['u']
|
||||
up_info = u['up']
|
||||
@@ -30,11 +31,10 @@ def import_user(u):
|
||||
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',
|
||||
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']
|
||||
|
||||
up_keys = ['language', 'location', 'meta', 'name', 'id', 'user_id']
|
||||
|
||||
u = User()
|
||||
for key in user_keys:
|
||||
@@ -47,20 +47,22 @@ def import_user(u):
|
||||
up.__setattr__(key, up_info[key])
|
||||
up.save()
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = \
|
||||
'''Exports all users and user profiles.
|
||||
'''Exports all users and user profiles.
|
||||
Caveat: Should be looked over before any run
|
||||
for schema changes.
|
||||
for schema changes.
|
||||
|
||||
Current version grabs user_keys from
|
||||
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
|
||||
n = 0
|
||||
for u in extracted:
|
||||
import_user(u)
|
||||
if n%100 == 0:
|
||||
if n % 100 == 0:
|
||||
print n
|
||||
n = n+1
|
||||
n = n + 1
|
||||
|
||||
@@ -17,29 +17,32 @@ import json
|
||||
|
||||
middleware.MakoMiddleware()
|
||||
|
||||
|
||||
def group_from_value(groups, v):
|
||||
''' Given group: (('a',0.3),('b',0.4),('c',0.3)) And random value
|
||||
in [0,1], return the associated group (in the above case, return
|
||||
'a' if v<0.3, 'b' if 0.3<=v<0.7, and 'c' if v>0.7
|
||||
'''
|
||||
sum = 0
|
||||
for (g,p) in groups:
|
||||
for (g, p) in groups:
|
||||
sum = sum + p
|
||||
if sum > v:
|
||||
return g
|
||||
return g # For round-off errors
|
||||
return g # For round-off errors
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = \
|
||||
''' Assign users to test groups. Takes a list
|
||||
of groups:
|
||||
of groups:
|
||||
a:0.3,b:0.4,c:0.3 file.txt "Testing something"
|
||||
Will assign each user to group a, b, or c with
|
||||
probability 0.3, 0.4, 0.3. Probabilities must
|
||||
add up to 1.
|
||||
probability 0.3, 0.4, 0.3. Probabilities must
|
||||
add up to 1.
|
||||
|
||||
Will log what happened to file.txt.
|
||||
'''
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if len(args) != 3:
|
||||
print "Invalid number of options"
|
||||
@@ -47,13 +50,13 @@ Will log what happened to file.txt.
|
||||
|
||||
# Extract groups from string
|
||||
group_strs = [x.split(':') for x in args[0].split(',')]
|
||||
groups = [(group,float(value)) for group,value in group_strs]
|
||||
groups = [(group, float(value)) for group, value in group_strs]
|
||||
print "Groups", groups
|
||||
|
||||
## Confirm group probabilities add up to 1
|
||||
total = sum(zip(*groups)[1])
|
||||
print "Total:", total
|
||||
if abs(total-1)>0.01:
|
||||
if abs(total - 1) > 0.01:
|
||||
print "Total not 1"
|
||||
sys.exit(-1)
|
||||
|
||||
@@ -65,15 +68,15 @@ Will log what happened to file.txt.
|
||||
|
||||
group_objects = {}
|
||||
|
||||
f = open(args[1],"a+")
|
||||
f = open(args[1], "a+")
|
||||
|
||||
## Create groups
|
||||
for group in dict(groups):
|
||||
utg = UserTestGroup()
|
||||
utg.name=group
|
||||
utg.description = json.dumps({"description":args[2]},
|
||||
{"time":datetime.datetime.utcnow().isoformat()})
|
||||
group_objects[group]=utg
|
||||
utg.name = group
|
||||
utg.description = json.dumps({"description": args[2]},
|
||||
{"time": datetime.datetime.utcnow().isoformat()})
|
||||
group_objects[group] = utg
|
||||
group_objects[group].save()
|
||||
|
||||
## Assign groups
|
||||
@@ -83,11 +86,11 @@ Will log what happened to file.txt.
|
||||
if count % 1000 == 0:
|
||||
print count
|
||||
count = count + 1
|
||||
v = random.uniform(0,1)
|
||||
group = group_from_value(groups,v)
|
||||
v = random.uniform(0, 1)
|
||||
group = group_from_value(groups, v)
|
||||
group_objects[group].users.add(user)
|
||||
f.write("Assigned user {name} ({id}) to {group}\n".format(name=user.username,
|
||||
id=user.id,
|
||||
f.write("Assigned user {name} ({id}) to {group}\n".format(name=user.username,
|
||||
id=user.id,
|
||||
group=group))
|
||||
|
||||
## Save groups
|
||||
|
||||
@@ -10,9 +10,11 @@ import mitxmako.middleware as middleware
|
||||
|
||||
middleware.MakoMiddleware()
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = \
|
||||
''' Extract an e-mail list of all active students. '''
|
||||
|
||||
def handle(self, *args, **options):
|
||||
#text = open(args[0]).read()
|
||||
#subject = open(args[1]).read()
|
||||
|
||||
@@ -10,18 +10,20 @@ import mitxmako.middleware as middleware
|
||||
|
||||
middleware.MakoMiddleware()
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = \
|
||||
'''Sends an e-mail to all users. Takes a single
|
||||
'''Sends an e-mail to all users. Takes a single
|
||||
parameter -- name of e-mail template -- located
|
||||
in templates/email. Adds a .txt for the message
|
||||
body, and an _subject.txt for the subject. '''
|
||||
|
||||
def handle(self, *args, **options):
|
||||
#text = open(args[0]).read()
|
||||
#subject = open(args[1]).read()
|
||||
users = User.objects.all()
|
||||
text = middleware.lookup['main'].get_template('email/'+args[0]+".txt").render()
|
||||
subject = middleware.lookup['main'].get_template('email/'+args[0]+"_subject.txt").render().strip()
|
||||
text = middleware.lookup['main'].get_template('email/' + args[0] + ".txt").render()
|
||||
subject = middleware.lookup['main'].get_template('email/' + args[0] + "_subject.txt").render().strip()
|
||||
for user in users:
|
||||
if user.is_active:
|
||||
user.email_user(subject, text)
|
||||
|
||||
@@ -16,16 +16,18 @@ import datetime
|
||||
|
||||
middleware.MakoMiddleware()
|
||||
|
||||
|
||||
def chunks(l, n):
|
||||
""" Yield successive n-sized chunks from l.
|
||||
"""
|
||||
for i in xrange(0, len(l), n):
|
||||
yield l[i:i+n]
|
||||
yield l[i:i + n]
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = \
|
||||
'''Sends an e-mail to all users in a text file.
|
||||
E.g.
|
||||
'''Sends an e-mail to all users in a text file.
|
||||
E.g.
|
||||
manage.py userlist.txt message logfile.txt rate
|
||||
userlist.txt -- list of all users
|
||||
message -- prefix for template with message
|
||||
@@ -35,28 +37,28 @@ rate -- messages per second
|
||||
log_file = None
|
||||
|
||||
def hard_log(self, text):
|
||||
self.log_file.write(datetime.datetime.utcnow().isoformat()+' -- '+text+'\n')
|
||||
self.log_file.write(datetime.datetime.utcnow().isoformat() + ' -- ' + text + '\n')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
global log_file
|
||||
(user_file, message_base, logfilename, ratestr) = args
|
||||
|
||||
|
||||
users = [u.strip() for u in open(user_file).readlines()]
|
||||
|
||||
message = middleware.lookup['main'].get_template('emails/'+message_base+"_body.txt").render()
|
||||
subject = middleware.lookup['main'].get_template('emails/'+message_base+"_subject.txt").render().strip()
|
||||
message = middleware.lookup['main'].get_template('emails/' + message_base + "_body.txt").render()
|
||||
subject = middleware.lookup['main'].get_template('emails/' + message_base + "_subject.txt").render().strip()
|
||||
rate = int(ratestr)
|
||||
|
||||
self.log_file = open(logfilename, "a+", buffering = 0)
|
||||
|
||||
i=0
|
||||
self.log_file = open(logfilename, "a+", buffering=0)
|
||||
|
||||
i = 0
|
||||
for users in chunks(users, rate):
|
||||
emails = [ (subject, message, settings.DEFAULT_FROM_EMAIL, [u]) for u in users ]
|
||||
emails = [(subject, message, settings.DEFAULT_FROM_EMAIL, [u]) for u in users]
|
||||
self.hard_log(" ".join(users))
|
||||
send_mass_mail( emails, fail_silently = False )
|
||||
send_mass_mail(emails, fail_silently=False)
|
||||
time.sleep(1)
|
||||
print datetime.datetime.utcnow().isoformat(), i
|
||||
i = i+len(users)
|
||||
i = i + len(users)
|
||||
# Emergency interruptor
|
||||
if os.path.exists("/tmp/stopemails.txt"):
|
||||
self.log_file.close()
|
||||
|
||||
@@ -13,26 +13,28 @@ from student.models import UserProfile
|
||||
|
||||
middleware.MakoMiddleware()
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = \
|
||||
''' Extract full user information into a JSON file.
|
||||
''' Extract full user information into a JSON file.
|
||||
Pass a single filename.'''
|
||||
|
||||
def handle(self, *args, **options):
|
||||
f = open(args[0],'w')
|
||||
f = open(args[0], 'w')
|
||||
#text = open(args[0]).read()
|
||||
#subject = open(args[1]).read()
|
||||
users = User.objects.all()
|
||||
|
||||
l = []
|
||||
for user in users:
|
||||
up = UserProfile.objects.get(user = user)
|
||||
d = { 'username':user.username,
|
||||
'email':user.email,
|
||||
'is_active':user.is_active,
|
||||
'joined':user.date_joined.isoformat(),
|
||||
'name':up.name,
|
||||
'language':up.language,
|
||||
'location':up.location}
|
||||
up = UserProfile.objects.get(user=user)
|
||||
d = {'username': user.username,
|
||||
'email': user.email,
|
||||
'is_active': user.is_active,
|
||||
'joined': user.date_joined.isoformat(),
|
||||
'name': up.name,
|
||||
'language': up.language,
|
||||
'location': up.location}
|
||||
l.append(d)
|
||||
json.dump(l,f)
|
||||
json.dump(l, f)
|
||||
f.close()
|
||||
|
||||
@@ -4,10 +4,11 @@ from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
|
||||
# Adding model 'UserProfile'
|
||||
db.create_table('auth_userprofile', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
@@ -28,16 +29,14 @@ class Migration(SchemaMigration):
|
||||
))
|
||||
db.send_create_signal('student', ['Registration'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
|
||||
# Deleting model 'UserProfile'
|
||||
db.delete_table('auth_userprofile')
|
||||
|
||||
# Deleting model 'Registration'
|
||||
db.delete_table('auth_registration')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
|
||||
@@ -4,10 +4,11 @@ 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.name'
|
||||
db.alter_column('auth_userprofile', 'name', self.gf('django.db.models.fields.CharField')(max_length=255))
|
||||
|
||||
@@ -32,9 +33,8 @@ class Migration(SchemaMigration):
|
||||
# Adding index on 'UserProfile', fields ['location']
|
||||
db.create_index('auth_userprofile', ['location'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
|
||||
# Removing index on 'UserProfile', fields ['location']
|
||||
db.delete_index('auth_userprofile', ['location'])
|
||||
|
||||
@@ -59,7 +59,6 @@ class Migration(SchemaMigration):
|
||||
# Changing field 'UserProfile.location'
|
||||
db.alter_column('auth_userprofile', 'location', self.gf('django.db.models.fields.TextField')())
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
|
||||
@@ -4,10 +4,11 @@ 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)),
|
||||
@@ -24,16 +25,14 @@ class Migration(SchemaMigration):
|
||||
))
|
||||
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'},
|
||||
|
||||
@@ -4,18 +4,17 @@ from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
db.execute("create unique index email on auth_user (email)")
|
||||
pass
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
db.execute("drop index email on auth_user")
|
||||
pass
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
|
||||
@@ -4,10 +4,11 @@ from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
|
||||
# Adding model 'PendingEmailChange'
|
||||
db.create_table('student_pendingemailchange', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
@@ -29,9 +30,8 @@ class Migration(SchemaMigration):
|
||||
# Changing field 'UserProfile.user'
|
||||
db.alter_column('auth_userprofile', 'user_id', self.gf('django.db.models.fields.related.OneToOneField')(unique=True, to=orm['auth.User']))
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
|
||||
# Deleting model 'PendingEmailChange'
|
||||
db.delete_table('student_pendingemailchange')
|
||||
|
||||
@@ -41,7 +41,6 @@ class Migration(SchemaMigration):
|
||||
# Changing field 'UserProfile.user'
|
||||
db.alter_column('auth_userprofile', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], unique=True))
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
|
||||
@@ -4,20 +4,19 @@ 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'},
|
||||
|
||||
@@ -4,6 +4,7 @@ from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
@@ -16,12 +17,10 @@ class Migration(SchemaMigration):
|
||||
ALTER TABLE student_usertestgroup_users CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
""")
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Although this migration can't be undone, it is okay for it to be run backwards because it doesn't add/remove any fields
|
||||
pass
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
|
||||
@@ -16,12 +16,10 @@ class Migration(SchemaMigration):
|
||||
))
|
||||
db.send_create_signal('student', ['CourseRegistration'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'CourseRegistration'
|
||||
db.delete_table('student_courseregistration')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
@@ -129,4 +127,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -19,7 +19,6 @@ class Migration(SchemaMigration):
|
||||
))
|
||||
db.send_create_signal('student', ['CourseEnrollment'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Adding model 'CourseRegistration'
|
||||
db.create_table('student_courseregistration', (
|
||||
@@ -32,7 +31,6 @@ class Migration(SchemaMigration):
|
||||
# Deleting model 'CourseEnrollment'
|
||||
db.delete_table('student_courseenrollment')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
@@ -140,4 +138,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -124,4 +124,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -13,8 +13,8 @@ class Migration(SchemaMigration):
|
||||
pass
|
||||
# # Removing unique constraint on 'CourseEnrollment', fields ['user']
|
||||
# db.delete_unique('student_courseenrollment', ['user_id'])
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# # Changing field 'CourseEnrollment.user'
|
||||
# db.alter_column('student_courseenrollment', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User']))
|
||||
|
||||
@@ -25,7 +25,6 @@ class Migration(SchemaMigration):
|
||||
# # Adding unique constraint on 'CourseEnrollment', fields ['user']
|
||||
# db.create_unique('student_courseenrollment', ['user_id'])
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
@@ -133,4 +132,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -38,7 +38,6 @@ class Migration(SchemaMigration):
|
||||
self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting field 'UserProfile.gender'
|
||||
db.delete_column('auth_userprofile', 'gender')
|
||||
@@ -58,7 +57,6 @@ class Migration(SchemaMigration):
|
||||
# Deleting field 'UserProfile.occupation'
|
||||
db.delete_column('auth_userprofile', 'occupation')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
@@ -172,4 +170,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -130,4 +130,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -11,7 +11,6 @@ class Migration(SchemaMigration):
|
||||
# Deleting model 'CourseEnrollment'
|
||||
db.delete_table('student_courseenrollment')
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Adding model 'CourseEnrollment'
|
||||
db.create_table('student_courseenrollment', (
|
||||
@@ -21,7 +20,6 @@ class Migration(SchemaMigration):
|
||||
))
|
||||
db.send_create_signal('student', ['CourseEnrollment'])
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
@@ -129,4 +127,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -19,7 +19,6 @@ class Migration(SchemaMigration):
|
||||
# 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'])
|
||||
@@ -27,7 +26,6 @@ class Migration(SchemaMigration):
|
||||
# Deleting model 'CourseEnrollment'
|
||||
db.delete_table('student_courseenrollment')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
@@ -141,4 +139,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -13,7 +13,6 @@ class Migration(SchemaMigration):
|
||||
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))
|
||||
|
||||
@@ -21,7 +20,6 @@ class Migration(SchemaMigration):
|
||||
# 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))
|
||||
|
||||
@@ -139,4 +137,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -15,7 +15,6 @@ class Migration(SchemaMigration):
|
||||
# Rename 'created' field to 'date'
|
||||
db.rename_column('student_courseenrollment', 'created', 'date')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
@@ -130,4 +129,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -11,12 +11,10 @@ class Migration(SchemaMigration):
|
||||
# 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'},
|
||||
@@ -131,4 +129,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -38,7 +38,6 @@ class Migration(SchemaMigration):
|
||||
# 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'])
|
||||
@@ -72,7 +71,6 @@ class Migration(SchemaMigration):
|
||||
# Deleting field 'UserProfile.goals'
|
||||
db.delete_column('auth_userprofile', 'goals')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
@@ -186,4 +184,4 @@ class Migration(SchemaMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
complete_apps = ['student']
|
||||
|
||||
@@ -18,6 +18,7 @@ from django_countries import CountryField
|
||||
|
||||
#from cache_toolbox import cache_model, cache_relation
|
||||
|
||||
|
||||
class UserProfile(models.Model):
|
||||
class Meta:
|
||||
db_table = "auth_userprofile"
|
||||
@@ -28,7 +29,7 @@ class UserProfile(models.Model):
|
||||
user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile')
|
||||
name = models.CharField(blank=True, max_length=255, db_index=True)
|
||||
|
||||
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')
|
||||
|
||||
# Location is no longer used, but is held here for backwards compatibility
|
||||
@@ -59,7 +60,6 @@ class UserProfile(models.Model):
|
||||
mailing_address = models.TextField(blank=True, null=True)
|
||||
goals = models.TextField(blank=True, null=True)
|
||||
|
||||
|
||||
def get_meta(self):
|
||||
js_str = self.meta
|
||||
if not js_str:
|
||||
@@ -69,9 +69,10 @@ class UserProfile(models.Model):
|
||||
|
||||
return js_str
|
||||
|
||||
def set_meta(self,js):
|
||||
def set_meta(self, js):
|
||||
self.meta = json.dumps(js)
|
||||
|
||||
|
||||
## TODO: Should be renamed to generic UserGroup, and possibly
|
||||
# Given an optional field for type of group
|
||||
class UserTestGroup(models.Model):
|
||||
@@ -79,6 +80,7 @@ class UserTestGroup(models.Model):
|
||||
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
|
||||
registration profile is created when the user creates an
|
||||
@@ -92,8 +94,8 @@ class Registration(models.Model):
|
||||
|
||||
def register(self, user):
|
||||
# MINOR TODO: Switch to crypto-secure key
|
||||
self.activation_key=uuid.uuid4().hex
|
||||
self.user=user
|
||||
self.activation_key = uuid.uuid4().hex
|
||||
self.user = user
|
||||
self.save()
|
||||
|
||||
def activate(self):
|
||||
@@ -101,22 +103,25 @@ class Registration(models.Model):
|
||||
self.user.save()
|
||||
#self.delete()
|
||||
|
||||
|
||||
class PendingNameChange(models.Model):
|
||||
user = models.OneToOneField(User, unique=True, db_index=True)
|
||||
new_name = models.CharField(blank=True, max_length=255)
|
||||
rationale = models.CharField(blank=True, max_length=1024)
|
||||
|
||||
|
||||
class PendingEmailChange(models.Model):
|
||||
user = models.OneToOneField(User, unique=True, db_index=True)
|
||||
new_email = models.CharField(blank=True, max_length=255, db_index=True)
|
||||
activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True)
|
||||
|
||||
|
||||
class CourseEnrollment(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
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'), )
|
||||
|
||||
@@ -124,38 +129,45 @@ class CourseEnrollment(models.Model):
|
||||
|
||||
#### Helper methods for use from python manage.py shell.
|
||||
|
||||
|
||||
def get_user(email):
|
||||
u = User.objects.get(email = email)
|
||||
up = UserProfile.objects.get(user = u)
|
||||
return u,up
|
||||
u = User.objects.get(email=email)
|
||||
up = UserProfile.objects.get(user=u)
|
||||
return u, up
|
||||
|
||||
|
||||
def user_info(email):
|
||||
u,up = get_user(email)
|
||||
u, up = get_user(email)
|
||||
print "User id", u.id
|
||||
print "Username", u.username
|
||||
print "E-mail", u.email
|
||||
print "Name", up.name
|
||||
print "Location", up.location
|
||||
print "Language", up.language
|
||||
return u,up
|
||||
return u, up
|
||||
|
||||
|
||||
def change_email(old_email, new_email):
|
||||
u = User.objects.get(email = old_email)
|
||||
u = User.objects.get(email=old_email)
|
||||
u.email = new_email
|
||||
u.save()
|
||||
|
||||
|
||||
def change_name(email, new_name):
|
||||
u,up = get_user(email)
|
||||
u, up = get_user(email)
|
||||
up.name = new_name
|
||||
up.save()
|
||||
|
||||
|
||||
def user_count():
|
||||
print "All users", User.objects.all().count()
|
||||
print "Active users", User.objects.filter(is_active = True).count()
|
||||
print "Active users", User.objects.filter(is_active=True).count()
|
||||
return User.objects.all().count()
|
||||
|
||||
|
||||
def active_user_count():
|
||||
return User.objects.filter(is_active = True).count()
|
||||
return User.objects.filter(is_active=True).count()
|
||||
|
||||
|
||||
def create_group(name, description):
|
||||
utg = UserTestGroup()
|
||||
@@ -163,29 +175,31 @@ def create_group(name, description):
|
||||
utg.description = description
|
||||
utg.save()
|
||||
|
||||
|
||||
def add_user_to_group(user, group):
|
||||
utg = UserTestGroup.objects.get(name = group)
|
||||
utg.users.add(User.objects.get(username = user))
|
||||
utg = UserTestGroup.objects.get(name=group)
|
||||
utg.users.add(User.objects.get(username=user))
|
||||
utg.save()
|
||||
|
||||
|
||||
def remove_user_from_group(user, group):
|
||||
utg = UserTestGroup.objects.get(name = group)
|
||||
utg.users.remove(User.objects.get(username = user))
|
||||
utg = UserTestGroup.objects.get(name=group)
|
||||
utg.users.remove(User.objects.get(username=user))
|
||||
utg.save()
|
||||
|
||||
default_groups = {'email_future_courses' : 'Receive e-mails about future MITx courses',
|
||||
'email_helpers' : 'Receive e-mails about how to help with MITx',
|
||||
'mitx_unenroll' : 'Fully unenrolled -- no further communications',
|
||||
'6002x_unenroll' : 'Took and dropped 6002x'}
|
||||
default_groups = {'email_future_courses': 'Receive e-mails about future MITx courses',
|
||||
'email_helpers': 'Receive e-mails about how to help with MITx',
|
||||
'mitx_unenroll': 'Fully unenrolled -- no further communications',
|
||||
'6002x_unenroll': 'Took and dropped 6002x'}
|
||||
|
||||
|
||||
def add_user_to_default_group(user, group):
|
||||
try:
|
||||
utg = UserTestGroup.objects.get(name = group)
|
||||
utg = UserTestGroup.objects.get(name=group)
|
||||
except UserTestGroup.DoesNotExist:
|
||||
utg = UserTestGroup()
|
||||
utg.name = group
|
||||
utg.description = default_groups[group]
|
||||
utg.save()
|
||||
utg.users.add(User.objects.get(username = user))
|
||||
utg.users.add(User.objects.get(username=user))
|
||||
utg.save()
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ from django.core.cache import cache
|
||||
|
||||
from django_future.csrf import ensure_csrf_cookie
|
||||
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.modulestore.django import modulestore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
@@ -80,10 +80,12 @@ def index(request):
|
||||
|
||||
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
|
||||
@ensure_csrf_cookie
|
||||
def dashboard(request):
|
||||
@@ -100,19 +102,18 @@ def dashboard(request):
|
||||
except ItemNotFoundError:
|
||||
log.error("User {0} enrolled in non-existant course {1}"
|
||||
.format(user.username, enrollment.course_id))
|
||||
|
||||
|
||||
|
||||
message = ""
|
||||
if not user.is_active:
|
||||
message = render_to_string('registration/activate_account_notice.html', {'email': user.email})
|
||||
|
||||
context = {'courses': courses, 'message' : message}
|
||||
context = {'courses': courses, 'message': message}
|
||||
return render_to_response('dashboard.html', context)
|
||||
|
||||
|
||||
def try_change_enrollment(request):
|
||||
"""
|
||||
This method calls change_enrollment if the necessary POST
|
||||
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.
|
||||
@@ -126,22 +127,23 @@ def try_change_enrollment(request):
|
||||
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" , "")
|
||||
|
||||
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
|
||||
@@ -151,22 +153,23 @@ def change_enrollment(request):
|
||||
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 = 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
|
||||
@ensure_csrf_cookie
|
||||
def login_user(request, error=""):
|
||||
@@ -195,7 +198,7 @@ def login_user(request, error=""):
|
||||
try:
|
||||
login(request, user)
|
||||
if request.POST.get('remember') == 'true':
|
||||
request.session.set_expiry(None) # or change to 604800 for 7 days
|
||||
request.session.set_expiry(None) # or change to 604800 for 7 days
|
||||
log.debug("Setting user session to never expire")
|
||||
else:
|
||||
request.session.set_expiry(0)
|
||||
@@ -204,38 +207,41 @@ def login_user(request, error=""):
|
||||
log.exception(e)
|
||||
|
||||
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))
|
||||
return HttpResponse(json.dumps({'success':False,
|
||||
return HttpResponse(json.dumps({'success': False,
|
||||
'value': 'This account has not been activated. Please check your e-mail for the activation instructions.'}))
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def logout_user(request):
|
||||
''' HTTP request to log out the user. Redirects to marketing page'''
|
||||
logout(request)
|
||||
return redirect('/')
|
||||
|
||||
|
||||
@login_required
|
||||
@ensure_csrf_cookie
|
||||
def change_setting(request):
|
||||
''' 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:
|
||||
up.location=request.POST['location']
|
||||
up.location = request.POST['location']
|
||||
up.save()
|
||||
|
||||
return HttpResponse(json.dumps({'success':True,
|
||||
'location':up.location,}))
|
||||
return HttpResponse(json.dumps({'success': True,
|
||||
'location': up.location, }))
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def create_account(request, post_override=None):
|
||||
''' JSON call to enroll in the course. '''
|
||||
js={'success':False}
|
||||
js = {'success': False}
|
||||
|
||||
post_vars = post_override if post_override else request.POST
|
||||
|
||||
@@ -246,12 +252,11 @@ def create_account(request, post_override=None):
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
if post_vars.get('honor_code', 'false') != u'true':
|
||||
js['value']="To enroll, you must follow the honor code.".format(field=a)
|
||||
js['value'] = "To enroll, you must follow the honor code.".format(field=a)
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
|
||||
if post_vars.get('terms_of_service', 'false') != u'true':
|
||||
js['value']="You must accept the terms of service.".format(field=a)
|
||||
js['value'] = "You must accept the terms of service.".format(field=a)
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
# Confirm appropriate fields are there.
|
||||
@@ -261,25 +266,25 @@ def create_account(request, post_override=None):
|
||||
# TODO: Check password is sane
|
||||
for a in ['username', 'email', 'name', 'password', 'terms_of_service', 'honor_code']:
|
||||
if len(post_vars[a]) < 2:
|
||||
error_str = {'username' : 'Username of length 2 or greater',
|
||||
'email' : 'Properly formatted e-mail',
|
||||
'name' : 'Your legal name ',
|
||||
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])
|
||||
js['value'] = "{field} is required.".format(field=error_str[a])
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
try:
|
||||
validate_email(post_vars['email'])
|
||||
except ValidationError:
|
||||
js['value']="Valid e-mail is required.".format(field=a)
|
||||
js['value'] = "Valid e-mail is required.".format(field=a)
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
try:
|
||||
validate_slug(post_vars['username'])
|
||||
except ValidationError:
|
||||
js['value']="Username should only consist of A-Z and 0-9.".format(field=a)
|
||||
js['value'] = "Username should only consist of A-Z and 0-9.".format(field=a)
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
u = User(username=post_vars['username'],
|
||||
@@ -311,17 +316,17 @@ def create_account(request, post_override=None):
|
||||
up.gender = post_vars.get('gender')
|
||||
up.mailing_address = post_vars.get('mailing_address')
|
||||
up.goals = post_vars.get('goals')
|
||||
|
||||
|
||||
try:
|
||||
up.year_of_birth = int(post_vars['year_of_birth'])
|
||||
except (ValueError, KeyError):
|
||||
up.year_of_birth = None # If they give us garbage, just ignore it instead
|
||||
up.year_of_birth = None # If they give us garbage, just ignore it instead
|
||||
# of asking them to put an integer.
|
||||
try:
|
||||
up.save()
|
||||
except Exception:
|
||||
log.exception("UserProfile creation failed for user {0}.".format(u.id))
|
||||
|
||||
|
||||
d = {'name': post_vars['name'],
|
||||
'key': r.activation_key,
|
||||
}
|
||||
@@ -334,7 +339,7 @@ def create_account(request, post_override=None):
|
||||
try:
|
||||
if settings.MITX_FEATURES.get('REROUTE_ACTIVATION_EMAIL'):
|
||||
dest_addr = settings.MITX_FEATURES['REROUTE_ACTIVATION_EMAIL']
|
||||
message = "Activation for %s (%s): %s\n" % (u,u.email,up.name) + '-' * 80 + '\n\n' + message
|
||||
message = "Activation for %s (%s): %s\n" % (u, u.email, up.name) + '-' * 80 + '\n\n' + message
|
||||
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [dest_addr], fail_silently=False)
|
||||
elif not settings.GENERATE_RANDOM_USER_CREDENTIALS:
|
||||
res = u.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
|
||||
@@ -342,57 +347,60 @@ def create_account(request, post_override=None):
|
||||
log.exception(sys.exc_info())
|
||||
js['value'] = 'Could not send activation e-mail.'
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
|
||||
# Immediately after a user creates an account, we log them in. They are only
|
||||
# logged in until they close the browser. They can't log in again until they click
|
||||
# the activation link from the email.
|
||||
login_user = authenticate(username=post_vars['username'], password = post_vars['password'] )
|
||||
login_user = authenticate(username=post_vars['username'], password=post_vars['password'])
|
||||
login(request, login_user)
|
||||
request.session.set_expiry(0)
|
||||
|
||||
request.session.set_expiry(0)
|
||||
|
||||
try_change_enrollment(request)
|
||||
|
||||
js={'success': True}
|
||||
|
||||
js = {'success': True}
|
||||
return HttpResponse(json.dumps(js), mimetype="application/json")
|
||||
|
||||
|
||||
def create_random_account(create_account_function):
|
||||
|
||||
def id_generator(size=6, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits):
|
||||
return ''.join(random.choice(chars) for x in range(size))
|
||||
|
||||
def inner_create_random_account(request):
|
||||
post_override= {'username' : "random_" + id_generator(),
|
||||
'email' : id_generator(size=10, chars=string.ascii_lowercase) + "_dummy_test@mitx.mit.edu",
|
||||
'password' : id_generator(),
|
||||
'location' : id_generator(size=5, chars=string.ascii_uppercase),
|
||||
'name' : id_generator(size=5, chars=string.ascii_lowercase) + " " + id_generator(size=7, chars=string.ascii_lowercase),
|
||||
'honor_code' : u'true',
|
||||
'terms_of_service' : u'true',}
|
||||
post_override = {'username': "random_" + id_generator(),
|
||||
'email': id_generator(size=10, chars=string.ascii_lowercase) + "_dummy_test@mitx.mit.edu",
|
||||
'password': id_generator(),
|
||||
'location': id_generator(size=5, chars=string.ascii_uppercase),
|
||||
'name': id_generator(size=5, chars=string.ascii_lowercase) + " " + id_generator(size=7, chars=string.ascii_lowercase),
|
||||
'honor_code': u'true',
|
||||
'terms_of_service': u'true', }
|
||||
|
||||
return create_account_function(request, post_override = post_override)
|
||||
return create_account_function(request, post_override=post_override)
|
||||
|
||||
return inner_create_random_account
|
||||
|
||||
if settings.GENERATE_RANDOM_USER_CREDENTIALS:
|
||||
create_account = create_random_account(create_account)
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def activate_account(request, key):
|
||||
''' When link in activation e-mail is clicked
|
||||
'''
|
||||
r=Registration.objects.filter(activation_key=key)
|
||||
if len(r)==1:
|
||||
r = Registration.objects.filter(activation_key=key)
|
||||
if len(r) == 1:
|
||||
user_logged_in = request.user.is_authenticated()
|
||||
already_active = True
|
||||
if not r[0].user.is_active:
|
||||
r[0].activate()
|
||||
already_active = False
|
||||
resp = render_to_response("registration/activation_complete.html",{'user_logged_in':user_logged_in, 'already_active' : already_active})
|
||||
resp = render_to_response("registration/activation_complete.html", {'user_logged_in': user_logged_in, 'already_active': already_active})
|
||||
return resp
|
||||
if len(r)==0:
|
||||
return render_to_response("registration/activation_invalid.html",{'csrf':csrf(request)['csrf_token']})
|
||||
if len(r) == 0:
|
||||
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.")
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def password_reset(request):
|
||||
''' Attempts to send a password reset e-mail. '''
|
||||
@@ -400,43 +408,44 @@ def password_reset(request):
|
||||
raise Http404
|
||||
form = PasswordResetForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save( use_https = request.is_secure(),
|
||||
from_email = settings.DEFAULT_FROM_EMAIL,
|
||||
request = request )
|
||||
return HttpResponse(json.dumps({'success':True,
|
||||
form.save(use_https=request.is_secure(),
|
||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||||
request=request)
|
||||
return HttpResponse(json.dumps({'success': True,
|
||||
'value': render_to_string('registration/password_reset_done.html', {})}))
|
||||
else:
|
||||
return HttpResponse(json.dumps({'success':False,
|
||||
return HttpResponse(json.dumps({'success': False,
|
||||
'error': 'Invalid e-mail'}))
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def reactivation_email(request):
|
||||
''' Send an e-mail to reactivate a deactivated account, or to
|
||||
resend an activation e-mail. Untested. '''
|
||||
email = request.POST['email']
|
||||
try:
|
||||
user = User.objects.get(email = 'email')
|
||||
user = User.objects.get(email='email')
|
||||
except User.DoesNotExist:
|
||||
return HttpResponse(json.dumps({'success':False,
|
||||
return HttpResponse(json.dumps({'success': False,
|
||||
'error': 'No inactive user with this e-mail exists'}))
|
||||
|
||||
if user.is_active:
|
||||
return HttpResponse(json.dumps({'success':False,
|
||||
return HttpResponse(json.dumps({'success': False,
|
||||
'error': 'User is already active'}))
|
||||
|
||||
reg = Registration.objects.get(user = user)
|
||||
reg = Registration.objects.get(user=user)
|
||||
reg.register(user)
|
||||
|
||||
d={'name':UserProfile.get(user = user).name,
|
||||
'key':r.activation_key}
|
||||
d = {'name': UserProfile.get(user=user).name,
|
||||
'key': r.activation_key}
|
||||
|
||||
subject = render_to_string('reactivation_email_subject.txt',d)
|
||||
subject = render_to_string('reactivation_email_subject.txt', d)
|
||||
subject = ''.join(subject.splitlines())
|
||||
message = render_to_string('reactivation_email.txt',d)
|
||||
message = render_to_string('reactivation_email.txt', d)
|
||||
|
||||
res=u.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
|
||||
res = u.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
|
||||
|
||||
return HttpResponse(json.dumps({'success':True}))
|
||||
return HttpResponse(json.dumps({'success': True}))
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
@@ -450,26 +459,26 @@ def change_email_request(request):
|
||||
user = request.user
|
||||
|
||||
if not user.check_password(request.POST['password']):
|
||||
return HttpResponse(json.dumps({'success':False,
|
||||
'error':'Invalid password'}))
|
||||
return HttpResponse(json.dumps({'success': False,
|
||||
'error': 'Invalid password'}))
|
||||
|
||||
new_email = request.POST['new_email']
|
||||
try:
|
||||
validate_email(new_email)
|
||||
except ValidationError:
|
||||
return HttpResponse(json.dumps({'success':False,
|
||||
'error':'Valid e-mail address required.'}))
|
||||
return HttpResponse(json.dumps({'success': False,
|
||||
'error': 'Valid e-mail address required.'}))
|
||||
|
||||
if len(User.objects.filter(email = new_email)) != 0:
|
||||
if len(User.objects.filter(email=new_email)) != 0:
|
||||
## CRITICAL TODO: Handle case sensitivity for e-mails
|
||||
return HttpResponse(json.dumps({'success':False,
|
||||
'error':'An account with this e-mail already exists.'}))
|
||||
return HttpResponse(json.dumps({'success': False,
|
||||
'error': 'An account with this e-mail already exists.'}))
|
||||
|
||||
pec_list = PendingEmailChange.objects.filter(user = request.user)
|
||||
pec_list = PendingEmailChange.objects.filter(user=request.user)
|
||||
if len(pec_list) == 0:
|
||||
pec = PendingEmailChange()
|
||||
pec.user = user
|
||||
else :
|
||||
else:
|
||||
pec = pec_list[0]
|
||||
|
||||
pec.new_email = request.POST['new_email']
|
||||
@@ -478,20 +487,21 @@ def change_email_request(request):
|
||||
|
||||
if pec.new_email == user.email:
|
||||
pec.delete()
|
||||
return HttpResponse(json.dumps({'success':False,
|
||||
'error':'Old email is the same as the new email.'}))
|
||||
return HttpResponse(json.dumps({'success': False,
|
||||
'error': 'Old email is the same as the new email.'}))
|
||||
|
||||
d = {'key':pec.activation_key,
|
||||
'old_email' : user.email,
|
||||
'new_email' : pec.new_email}
|
||||
d = {'key': pec.activation_key,
|
||||
'old_email': user.email,
|
||||
'new_email': pec.new_email}
|
||||
|
||||
subject = render_to_string('emails/email_change_subject.txt',d)
|
||||
subject = render_to_string('emails/email_change_subject.txt', d)
|
||||
subject = ''.join(subject.splitlines())
|
||||
message = render_to_string('emails/email_change.txt',d)
|
||||
message = render_to_string('emails/email_change.txt', d)
|
||||
|
||||
res=send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [pec.new_email])
|
||||
res = send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [pec.new_email])
|
||||
|
||||
return HttpResponse(json.dumps({'success': True}))
|
||||
|
||||
return HttpResponse(json.dumps({'success':True}))
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def confirm_email_change(request, key):
|
||||
@@ -499,22 +509,21 @@ def confirm_email_change(request, key):
|
||||
link is clicked. We confirm with the old e-mail, and update
|
||||
'''
|
||||
try:
|
||||
pec=PendingEmailChange.objects.get(activation_key=key)
|
||||
pec = PendingEmailChange.objects.get(activation_key=key)
|
||||
except PendingEmailChange.DoesNotExist:
|
||||
return render_to_response("invalid_email_key.html", {})
|
||||
|
||||
user = pec.user
|
||||
d = {'old_email' : user.email,
|
||||
'new_email' : pec.new_email}
|
||||
d = {'old_email': user.email,
|
||||
'new_email': pec.new_email}
|
||||
|
||||
if len(User.objects.filter(email = pec.new_email)) != 0:
|
||||
if len(User.objects.filter(email=pec.new_email)) != 0:
|
||||
return render_to_response("email_exists.html", d)
|
||||
|
||||
|
||||
subject = render_to_string('emails/email_change_subject.txt',d)
|
||||
subject = render_to_string('emails/email_change_subject.txt', d)
|
||||
subject = ''.join(subject.splitlines())
|
||||
message = render_to_string('emails/confirm_email_change.txt',d)
|
||||
up = UserProfile.objects.get( user = user )
|
||||
message = render_to_string('emails/confirm_email_change.txt', d)
|
||||
up = UserProfile.objects.get(user=user)
|
||||
meta = up.get_meta()
|
||||
if 'old_emails' not in meta:
|
||||
meta['old_emails'] = []
|
||||
@@ -528,6 +537,7 @@ def confirm_email_change(request, key):
|
||||
|
||||
return render_to_response("email_change_successful.html", d)
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def change_name_request(request):
|
||||
''' Log a request for a new name. '''
|
||||
@@ -535,18 +545,18 @@ def change_name_request(request):
|
||||
raise Http404
|
||||
|
||||
try:
|
||||
pnc = PendingNameChange.objects.get(user = request.user)
|
||||
pnc = PendingNameChange.objects.get(user=request.user)
|
||||
except PendingNameChange.DoesNotExist:
|
||||
pnc = PendingNameChange()
|
||||
pnc.user = request.user
|
||||
pnc.new_name = request.POST['new_name']
|
||||
pnc.rationale = request.POST['rationale']
|
||||
if len(pnc.new_name)<2:
|
||||
return HttpResponse(json.dumps({'success':False,'error':'Name required'}))
|
||||
if len(pnc.rationale)<2:
|
||||
return HttpResponse(json.dumps({'success':False,'error':'Rationale required'}))
|
||||
if len(pnc.new_name) < 2:
|
||||
return HttpResponse(json.dumps({'success': False, 'error': 'Name required'}))
|
||||
if len(pnc.rationale) < 2:
|
||||
return HttpResponse(json.dumps({'success': False, 'error': 'Rationale required'}))
|
||||
pnc.save()
|
||||
return HttpResponse(json.dumps({'success':True}))
|
||||
return HttpResponse(json.dumps({'success': True}))
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
|
||||
@@ -4,6 +4,7 @@ from django.conf import settings
|
||||
|
||||
import views
|
||||
|
||||
|
||||
class TrackMiddleware:
|
||||
def process_request(self, request):
|
||||
try:
|
||||
@@ -11,34 +12,34 @@ class TrackMiddleware:
|
||||
# names/passwords.
|
||||
if request.META['PATH_INFO'] in ['/event', '/login']:
|
||||
return
|
||||
|
||||
|
||||
# Removes passwords from the tracking logs
|
||||
# WARNING: This list needs to be changed whenever we change
|
||||
# password handling functionality.
|
||||
# password handling functionality.
|
||||
#
|
||||
# As of the time of this comment, only 'password' is used
|
||||
# The rest are there for future extension.
|
||||
# The rest are there for future extension.
|
||||
#
|
||||
# Passwords should never be sent as GET requests, but
|
||||
# Passwords should never be sent as GET requests, but
|
||||
# this can happen due to older browser bugs. We censor
|
||||
# this too.
|
||||
#
|
||||
# this too.
|
||||
#
|
||||
# We should manually confirm no passwords make it into log
|
||||
# files when we change this.
|
||||
# files when we change this.
|
||||
|
||||
censored_strings = ['password', 'newpassword', 'new_password',
|
||||
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
|
||||
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)}
|
||||
|
||||
event = { 'GET' : dict(get_dict),
|
||||
'POST' : dict(post_dict)}
|
||||
|
||||
# TODO: Confirm no large file uploads
|
||||
event = json.dumps(event)
|
||||
event = event[:512]
|
||||
|
||||
@@ -10,61 +10,64 @@ from django.conf import settings
|
||||
|
||||
log = logging.getLogger("tracking")
|
||||
|
||||
|
||||
def log_event(event):
|
||||
event_str = json.dumps(event)
|
||||
log.info(event_str[:settings.TRACK_MAX_EVENT])
|
||||
|
||||
|
||||
def user_track(request):
|
||||
try: # TODO: Do the same for many of the optional META parameters
|
||||
try: # TODO: Do the same for many of the optional META parameters
|
||||
username = request.user.username
|
||||
except:
|
||||
except:
|
||||
username = "anonymous"
|
||||
|
||||
try:
|
||||
scookie = request.META['HTTP_COOKIE'] # Get cookies
|
||||
scookie = ";".join([c.split('=')[1] for c in scookie.split(";") if "sessionid" in c]).strip() # Extract session ID
|
||||
except:
|
||||
try:
|
||||
scookie = request.META['HTTP_COOKIE'] # Get cookies
|
||||
scookie = ";".join([c.split('=')[1] for c in scookie.split(";") if "sessionid" in c]).strip() # Extract session ID
|
||||
except:
|
||||
scookie = ""
|
||||
|
||||
try:
|
||||
try:
|
||||
agent = request.META['HTTP_USER_AGENT']
|
||||
except:
|
||||
except:
|
||||
agent = ''
|
||||
|
||||
# TODO: Move a bunch of this into log_event
|
||||
event = {
|
||||
"username" : username,
|
||||
"session" : scookie,
|
||||
"ip" : request.META['REMOTE_ADDR'],
|
||||
"event_source" : "browser",
|
||||
"event_type" : request.GET['event_type'],
|
||||
"event" : request.GET['event'],
|
||||
"agent" : agent,
|
||||
"page" : request.GET['page'],
|
||||
"username": username,
|
||||
"session": scookie,
|
||||
"ip": request.META['REMOTE_ADDR'],
|
||||
"event_source": "browser",
|
||||
"event_type": request.GET['event_type'],
|
||||
"event": request.GET['event'],
|
||||
"agent": agent,
|
||||
"page": request.GET['page'],
|
||||
"time": datetime.datetime.utcnow().isoformat(),
|
||||
}
|
||||
log_event(event)
|
||||
return HttpResponse('success')
|
||||
|
||||
|
||||
def server_track(request, event_type, event, page=None):
|
||||
try:
|
||||
try:
|
||||
username = request.user.username
|
||||
except:
|
||||
except:
|
||||
username = "anonymous"
|
||||
|
||||
try:
|
||||
try:
|
||||
agent = request.META['HTTP_USER_AGENT']
|
||||
except:
|
||||
except:
|
||||
agent = ''
|
||||
|
||||
event = {
|
||||
"username" : username,
|
||||
"ip" : request.META['REMOTE_ADDR'],
|
||||
"event_source" : "server",
|
||||
"event_type" : event_type,
|
||||
"event" : event,
|
||||
"agent" : agent,
|
||||
"page" : page,
|
||||
"username": username,
|
||||
"ip": request.META['REMOTE_ADDR'],
|
||||
"event_source": "server",
|
||||
"event_type": event_type,
|
||||
"event": event,
|
||||
"agent": agent,
|
||||
"page": page,
|
||||
"time": datetime.datetime.utcnow().isoformat(),
|
||||
}
|
||||
log_event(event)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
This module aims to give a little more fine-tuned control of caching and cache
|
||||
invalidation. Import these instead of django.core.cache.
|
||||
|
||||
Note that 'default' is being preserved for user session caching, which we're
|
||||
Note that 'default' is being preserved for user session caching, which we're
|
||||
not migrating so as not to inconvenience users by logging them all out.
|
||||
"""
|
||||
from functools import wraps
|
||||
@@ -16,26 +16,27 @@ try:
|
||||
except Exception:
|
||||
cache = cache.cache
|
||||
|
||||
|
||||
def cache_if_anonymous(view_func):
|
||||
"""
|
||||
Many of the pages in edX are identical when the user is not logged
|
||||
in, but should not be cached when the user is logged in (because
|
||||
of the navigation bar at the top with the username).
|
||||
|
||||
in, but should not be cached when the user is logged in (because
|
||||
of the navigation bar at the top with the username).
|
||||
|
||||
The django middleware cache does not handle this correctly, because
|
||||
we access the session to put the csrf token in the header. This adds
|
||||
the cookie to the vary header, and so every page is cached seperately
|
||||
for each user (because each user has a different csrf token).
|
||||
|
||||
|
||||
Note that this decorator should only be used on views that do not
|
||||
contain the csrftoken within the html. The csrf token can be included
|
||||
in the header by ordering the decorators as such:
|
||||
|
||||
|
||||
@ensure_csrftoken
|
||||
@cache_if_anonymous
|
||||
def myView(request):
|
||||
"""
|
||||
|
||||
|
||||
@wraps(view_func)
|
||||
def _decorated(request, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
@@ -45,12 +46,12 @@ def cache_if_anonymous(view_func):
|
||||
if not response:
|
||||
response = view_func(request, *args, **kwargs)
|
||||
cache.set(cache_key, response, 60 * 3)
|
||||
|
||||
|
||||
return response
|
||||
|
||||
|
||||
else:
|
||||
#Don't use the cache
|
||||
return view_func(request, *args, **kwargs)
|
||||
|
||||
|
||||
return _decorated
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ from functools import wraps
|
||||
import copy
|
||||
import json
|
||||
|
||||
|
||||
def expect_json(view_function):
|
||||
@wraps(view_function)
|
||||
def expect_json_with_cloned_request(request, *args, **kwargs):
|
||||
|
||||
@@ -6,11 +6,13 @@ from django.utils.encoding import smart_str
|
||||
import hashlib
|
||||
import urllib
|
||||
|
||||
|
||||
def fasthash(string):
|
||||
m = hashlib.new("md4")
|
||||
m.update(string)
|
||||
return m.hexdigest()
|
||||
|
||||
|
||||
def safe_key(key, key_prefix, version):
|
||||
safe_key = urllib.quote_plus(smart_str(key))
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ from django.http import HttpResponseServerError
|
||||
|
||||
log = logging.getLogger("mitx")
|
||||
|
||||
|
||||
class ExceptionLoggingMiddleware(object):
|
||||
"""Just here to log unchecked exceptions that go all the way up the Django
|
||||
"""Just here to log unchecked exceptions that go all the way up the Django
|
||||
stack"""
|
||||
|
||||
if not settings.TEMPLATE_DEBUG:
|
||||
def process_exception(self, request, exception):
|
||||
log.exception(exception)
|
||||
return HttpResponseServerError("Server Error - Please try again later.")
|
||||
|
||||
|
||||
@@ -14,53 +14,57 @@ from mitxmako.shortcuts import render_to_response, render_to_string
|
||||
import capa.calc
|
||||
import track.views
|
||||
|
||||
|
||||
def calculate(request):
|
||||
''' Calculator in footer of every page. '''
|
||||
equation = request.GET['equation']
|
||||
try:
|
||||
try:
|
||||
result = capa.calc.evaluator({}, {}, equation)
|
||||
except:
|
||||
event = {'error':map(str,sys.exc_info()),
|
||||
'equation':equation}
|
||||
event = {'error': map(str, sys.exc_info()),
|
||||
'equation': equation}
|
||||
track.views.server_track(request, 'error:calc', event, page='calc')
|
||||
return HttpResponse(json.dumps({'result':'Invalid syntax'}))
|
||||
return HttpResponse(json.dumps({'result':str(result)}))
|
||||
return HttpResponse(json.dumps({'result': 'Invalid syntax'}))
|
||||
return HttpResponse(json.dumps({'result': str(result)}))
|
||||
|
||||
|
||||
def send_feedback(request):
|
||||
''' Feeback mechanism in footer of every page. '''
|
||||
try:
|
||||
try:
|
||||
username = request.user.username
|
||||
email = request.user.email
|
||||
except:
|
||||
except:
|
||||
username = "anonymous"
|
||||
email = "anonymous"
|
||||
|
||||
try:
|
||||
browser = request.META['HTTP_USER_AGENT']
|
||||
except:
|
||||
browser = "Unknown"
|
||||
|
||||
feedback = render_to_string("feedback_email.txt",
|
||||
{"subject":request.POST['subject'],
|
||||
"url": request.POST['url'],
|
||||
"time": datetime.datetime.now().isoformat(),
|
||||
"feedback": request.POST['message'],
|
||||
"email":email,
|
||||
"browser":browser,
|
||||
"user":username})
|
||||
|
||||
send_mail("MITx Feedback / " +request.POST['subject'],
|
||||
feedback,
|
||||
try:
|
||||
browser = request.META['HTTP_USER_AGENT']
|
||||
except:
|
||||
browser = "Unknown"
|
||||
|
||||
feedback = render_to_string("feedback_email.txt",
|
||||
{"subject": request.POST['subject'],
|
||||
"url": request.POST['url'],
|
||||
"time": datetime.datetime.now().isoformat(),
|
||||
"feedback": request.POST['message'],
|
||||
"email": email,
|
||||
"browser": browser,
|
||||
"user": username})
|
||||
|
||||
send_mail("MITx Feedback / " + request.POST['subject'],
|
||||
feedback,
|
||||
settings.DEFAULT_FROM_EMAIL,
|
||||
[ settings.DEFAULT_FEEDBACK_EMAIL ],
|
||||
fail_silently = False
|
||||
[settings.DEFAULT_FEEDBACK_EMAIL],
|
||||
fail_silently=False
|
||||
)
|
||||
return HttpResponse(json.dumps({'success':True}))
|
||||
return HttpResponse(json.dumps({'success': True}))
|
||||
|
||||
|
||||
def info(request):
|
||||
''' Info page (link from main header) '''
|
||||
return render_to_response("info.html", {})
|
||||
|
||||
|
||||
# From http://djangosnippets.org/snippets/1042/
|
||||
def parse_accept_header(accept):
|
||||
"""Parse the Accept header *accept*, returning a list with pairs of
|
||||
@@ -82,6 +86,7 @@ def parse_accept_header(accept):
|
||||
result.sort(lambda x, y: -cmp(x[2], y[2]))
|
||||
return result
|
||||
|
||||
|
||||
def accepts(request, media_type):
|
||||
"""Return whether this request has an Accept header that matches type"""
|
||||
accept = parse_accept_header(request.META.get("HTTP_ACCEPT", ""))
|
||||
|
||||
Reference in New Issue
Block a user