Commit 2c5bd99f by Bridger Maxwell

Caught up to default branch

--HG--
branch : bridger-dev
parents 216e9969 ccacc90c
......@@ -58,6 +58,11 @@ def get_instance(model, instance_or_pk, timeout=None, using=None):
cache.delete(key)
# Use the default manager so we are never filtered by a .get_query_set()
# import logging
# log = logging.getLogger("tracking")
# log.info( str(pk) )
instance = model._default_manager.using(using).get(pk=pk)
data = {}
......
......@@ -92,6 +92,10 @@ def cache_relation(descriptor, timeout=None):
except AttributeError:
pass
# import logging
# log = logging.getLogger("tracking")
# log.info( "DEBUG: "+str(str(rel.model)+"/"+str(self.pk) ))
instance = get_instance(rel.model, self.pk, timeout)
setattr(self, '_%s_cache' % related_name, instance)
......
......@@ -146,11 +146,11 @@ def propogate_downward_tag(element, attribute_name, parent_attribute = None):
def user_groups(user):
# TODO: Rewrite in Django
key = 'user_group_names_{user.id}'.format(user=user)
cache_expiration = 60 * 60 * 4 # four hours
group_names = cache.get(key)
cache_expiration = 60 * 60 # one hour
group_names = cache.get(fasthash(key))
if group_names is None:
group_names = [u.name for u in UserTestGroup.objects.filter(users=user)]
cache.set(key, group_names, cache_expiration)
cache.set(fasthash(key), group_names, cache_expiration)
return group_names
......@@ -169,19 +169,23 @@ def course_xml_process(tree):
def course_file(user):
''' Given a user, return course.xml'''
filename = user.profile_cache.courseware # UserProfile.objects.get(user=user).courseware
#import logging
#log = logging.getLogger("tracking")
#log.info( "DEBUG: cf:"+str(user) )
filename = UserProfile.objects.get(user=user).courseware # user.profile_cache.courseware
groups = user_groups(user)
options = {'dev_content':settings.DEV_CONTENT,
'groups' : groups}
cache_key = filename + "_processed?dev_content:" + str(options['dev_content']) + "&groups:" + str(sorted(groups))
tree_string = cache.get(cache_key)
tree_string = cache.get(fasthash(cache_key))
if not tree_string:
tree = course_xml_process(etree.XML(render_to_string(filename, options, namespace = 'course')))
tree_string = etree.tostring(tree)
cache.set(cache_key, tree_string, 60)
cache.set(fasthash(cache_key), tree_string, 60)
else:
tree = etree.XML(tree_string)
......
......@@ -14,12 +14,12 @@ ASSUMPTIONS: modules have unique IDs, even across different module_types
"""
from django.db import models
from django.db.models.signals import post_save, post_delete
from django.core.cache import cache
#from django.core.cache import cache
from django.contrib.auth.models import User
from cache_toolbox import cache_model, cache_relation
#from cache_toolbox import cache_model, cache_relation
CACHE_TIMEOUT = 60 * 60 * 4 # Set the cache timeout to be four hours
#CACHE_TIMEOUT = 60 * 60 * 4 # Set the cache timeout to be four hours
class StudentModule(models.Model):
# For a homework problem, contains a JSON
......@@ -58,35 +58,35 @@ class StudentModule(models.Model):
def __unicode__(self):
return self.module_type+'/'+self.student.username+"/"+self.module_id+'/'+str(self.state)[:20]
@classmethod
def get_with_caching(cls, student, module_id):
k = cls.key_for(student, module_id)
student_module = cache.get(k)
if student_module is None:
student_module = StudentModule.objects.filter(student=student,
module_id=module_id)[0]
# It's possible it really doesn't exist...
if student_module is not None:
cache.set(k, student_module, CACHE_TIMEOUT)
return student_module
# @classmethod
# def get_with_caching(cls, student, module_id):
# k = cls.key_for(student, module_id)
# student_module = cache.get(k)
# if student_module is None:
# student_module = StudentModule.objects.filter(student=student,
# module_id=module_id)[0]
# # It's possible it really doesn't exist...
# if student_module is not None:
# cache.set(k, student_module, CACHE_TIMEOUT)
# return student_module
@classmethod
def key_for(cls, student, module_id):
return "StudentModule-student_id:{0};module_id:{1}".format(student.id, module_id)
def clear_cache_by_student_and_module_id(sender, instance, *args, **kwargs):
k = sender.key_for(instance.student, instance.module_id)
cache.delete(k)
# def clear_cache_by_student_and_module_id(sender, instance, *args, **kwargs):
# k = sender.key_for(instance.student, instance.module_id)
# cache.delete(k)
def update_cache_by_student_and_module_id(sender, instance, *args, **kwargs):
k = sender.key_for(instance.student, instance.module_id)
cache.set(k, instance, CACHE_TIMEOUT)
# def update_cache_by_student_and_module_id(sender, instance, *args, **kwargs):
# k = sender.key_for(instance.student, instance.module_id)
# cache.set(k, instance, CACHE_TIMEOUT)
post_save.connect(update_cache_by_student_and_module_id, sender=StudentModule, weak=False)
post_delete.connect(clear_cache_by_student_and_module_id, sender=StudentModule, weak=False)
#post_save.connect(update_cache_by_student_and_module_id, sender=StudentModule, weak=False)
#post_delete.connect(clear_cache_by_student_and_module_id, sender=StudentModule, weak=False)
cache_model(StudentModule)
#cache_model(StudentModule)
......@@ -47,13 +47,17 @@ def make_track_function(request):
def modx_dispatch(request, module=None, dispatch=None, id=None):
''' Generic view for extensions. '''
if not request.user.is_authenticated():
return redirect('/')
# Grab the student information for the module from the database
#s = StudentModule.objects.filter(student=request.user,
# module_id=id)
s = StudentModule.get_with_caching(request.user, id)
if s is None:
s = StudentModule.objects.filter(student=request.user,
module_id=id)
#s = StudentModule.get_with_caching(request.user, id)
if len(s) == 0 or s is None:
log.debug("Couldnt find module for user and id " + str(module) + " " + str(request.user) + " "+ str(id))
raise Http404
s = s[0]
oldgrade = s.grade
oldstate = s.state
......
......@@ -254,7 +254,7 @@ def profile(request):
]
user_info = request.user.profile_cache # UserProfile.objects.get(user=request.user)
user_info = UserProfile.objects.get(user=request.user) # request.user.profile_cache #
context={'name':user_info.name,
'username':request.user.username,
'location':user_info.location,
......@@ -345,6 +345,10 @@ def index(request, course="6.002 Spring 2012", chapter="Using the System", secti
if course!="6.002 Spring 2012":
return redirect('/')
#import logging
#log = logging.getLogger("mitx")
#log.info( "DEBUG: "+str(user) )
dom = content_parser.course_file(user)
dom_module = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]/*[1]",
course=course, chapter=chapter, section=section)
......
......@@ -174,7 +174,7 @@ execfile(os.path.join(BASE_DIR, "settings.py"))
pid = os.getpid()
hostname = platform.node().split(".")[0]
SYSLOG_ADDRESS = ('syslog.m.i4x.org', 514)
LOGGING_FILENAME = 'trackinglog-' + str(pid)
TRACKING_LOG_FILE = LOG_DIR + "/tracking_{0}.log".format(pid)
handlers = ['console']
if not DEBUG:
......@@ -214,10 +214,11 @@ LOGGING = {
'address' : SYSLOG_ADDRESS,
'formatter' : 'syslog_format',
},
'filelogger' : {
'level' : 'INFO',
'class' : 'logging.FileHandler',
'filename' : LOGGING_FILENAME,
'tracking' : {
'level' : 'DEBUG',
'class' : 'logging.handlers.WatchedFileHandler',
'filename' : TRACKING_LOG_FILE,
'formatter' : 'raw',
},
'mail_admins' : {
'level': 'ERROR',
......@@ -231,7 +232,7 @@ LOGGING = {
'level' : 'INFO'
},
'tracking' : {
'handlers' : [] if DEBUG else ['filelogger'], # handlers,
'handlers' : ['tracking'],
'level' : 'DEBUG',
'propagate' : False,
},
......@@ -248,6 +249,8 @@ LOGGING = {
}
}
if PERFSTATS :
MIDDLEWARE_CLASSES = ( 'perfstats.middleware.ProfileMiddleware',) + MIDDLEWARE_CLASSES
......@@ -443,7 +446,7 @@ LIVESETTINGS_OPTIONS = {
'MIN_ANSWER_BODY_LENGTH' : 1,
'WIKI_ON' : True,
'ALLOW_ASK_ANONYMOUSLY' : True,
'ALLOW_POSTING_BEFORE_LOGGING_IN' : True,
'ALLOW_POSTING_BEFORE_LOGGING_IN' : False,
'ALLOW_SWAPPING_QUESTION_WITH_ANSWER' : False,
'MAX_TAG_LENGTH' : 20,
'MIN_TITLE_LENGTH' : 1,
......@@ -628,7 +631,7 @@ LIVESETTINGS_OPTIONS = {
'VOTE_RULES' : {
'MAX_VOTES_PER_USER_PER_DAY' : 30,
'MAX_FLAGS_PER_USER_PER_DAY' : 5,
'MIN_DAYS_FOR_STAFF_TO_ACCEPT_ANSWER' : 7,
'MIN_DAYS_FOR_STAFF_TO_ACCEPT_ANSWER' : 0,
'MIN_DAYS_TO_ANSWER_OWN_QUESTION' : 0,
'MIN_FLAGS_TO_DELETE_POST' : 5,
'MIN_FLAGS_TO_HIDE_POST' : 3,
......@@ -647,7 +650,7 @@ ot = MAKO_TEMPLATES
MAKO_TEMPLATES['course'] = [DATA_DIR]
MAKO_TEMPLATES['sections'] = [DATA_DIR+'/sections']
MAKO_TEMPLATES['custom_tags'] = [DATA_DIR+'/custom_tags']
MAKO_TEMPLATES['main'] = [BASE_DIR+'/templates/']
MAKO_TEMPLATES['main'] = [BASE_DIR+'/templates/', DATA_DIR+'/info']
MAKO_TEMPLATES.update(ot)
......
......@@ -39,7 +39,7 @@ def view(request, wiki_url):
'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),
'wiki_title' : article.title + " - MITX 6.002 Wiki"
'wiki_title' : article.title + " - MITX 6.002x Wiki"
}
d.update(csrf(request))
return render_to_response('simplewiki_view.html', d)
......
import os.path
from lxml import etree
from django.core.management.base import BaseCommand
from django.conf import settings
from django.contrib.auth.models import User
import mitxmako.middleware as middleware
from student.models import UserTestGroup
import random
import sys
import datetime
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:
sum = sum + p
if sum > v:
return g
return g # For round-off errors
class Command(BaseCommand):
help = \
''' Assign users to test groups. Takes a list
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.
Will log what happened to file.txt.
'''
def handle(self, *args, **options):
if len(args) != 3:
print "Invalid number of options"
sys.exit(-1)
# Extract groups from string
group_strs = [x.split(':') for x in args[0].split(',')]
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:
print "Total not 1"
sys.exit(-1)
## Confirm groups don't already exist
for group in dict(groups):
if UserTestGroup.objects.filter(name=group).count() != 0:
print group, "already exists!"
sys.exit(-1)
group_objects = {}
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
group_objects[group].save()
## Assign groups
users = list(User.objects.all())
count = 0
for user in users:
if count % 1000 == 0:
print count
count = count + 1
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,
group=group))
## Save groups
for group in group_objects:
group_objects[group].save()
f.close()
# python manage.py assigngroups summary_test:0.3,skip_summary_test:0.7 log.txt "Do previews of future materials help?"
# python manage.py assigngroups skip_capacitor:0.3,capacitor:0.7 log.txt "Do we show capacitor in linearity tutorial?"
import os.path
from lxml import etree
from django.core.management.base import BaseCommand
from django.conf import settings
from django.contrib.auth.models import User
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()
users = User.objects.all()
for user in users:
if user.is_active:
print user.email
import os.path
from lxml import etree
from django.core.management.base import BaseCommand
from django.conf import settings
from django.contrib.auth.models import User
import mitxmako.middleware as middleware
middleware.MakoMiddleware()
class Command(BaseCommand):
help = \
'''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()
for user in users:
if user.is_active:
user.email_user(subject, text)
import os.path
import time
from lxml import etree
from django.core.management.base import BaseCommand
from django.conf import settings
from django.contrib.auth.models import User
import mitxmako.middleware as middleware
from django.core.mail import send_mass_mail
import sys
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]
class Command(BaseCommand):
help = \
'''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
logfile.txt -- where to log progress
rate -- messages per second
'''
log_file = None
def hard_log(self, text):
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()
rate = int(ratestr)
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 ]
self.hard_log(" ".join(users))
send_mass_mail( emails, fail_silently = False )
time.sleep(1)
print datetime.datetime.utcnow().isoformat(), i
i = i+len(users)
# Emergency interruptor
if os.path.exists("/tmp/stopemails.txt"):
self.log_file.close()
sys.exit(-1)
self.log_file.close()
......@@ -13,7 +13,7 @@ import uuid
from django.db import models
from django.contrib.auth.models import User
from cache_toolbox import cache_model, cache_relation
#from cache_toolbox import cache_model, cache_relation
class UserProfile(models.Model):
class Meta:
......@@ -56,4 +56,4 @@ class Registration(models.Model):
self.user.save()
#self.delete()
cache_relation(User.profile)
#cache_relation(User.profile)
......@@ -86,7 +86,7 @@ def logout_user(request):
def change_setting(request):
if not request.user.is_authenticated():
return redirect('/')
up = request.user.profile_cache # UserProfile.objects.get(user=request.user)
up = UserProfile.objects.get(user=request.user) #request.user.profile_cache
if 'location' in request.POST:
# print "loc"
up.location=request.POST['location']
......
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