Commit 9e8ec09b by ichuang

pep8 fixes

parent 0ddd8949
......@@ -4,7 +4,7 @@ Models for Student Information
Replication Notes
In our live deployment, we intend to run in a scenario where there is a pool of
Portal servers that hold the canoncial user information and that user
Portal servers that hold the canoncial user information and that user
information is replicated to slave Course server pools. Each Course has a set of
servers that serves only its content and has users that are relevant only to it.
......@@ -61,6 +61,7 @@ from xmodule.modulestore.django import modulestore
log = logging.getLogger(__name__)
class UserProfile(models.Model):
"""This is where we store all the user demographic fields. We have a
separate table for this rather than extending the built-in Django auth_user.
......@@ -175,6 +176,7 @@ class PendingEmailChange(models.Model):
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)
......@@ -185,7 +187,8 @@ class CourseEnrollment(models.Model):
unique_together = (('user', 'course_id'), )
def __unicode__(self):
return "%s: %s (%s)" % (self.user,self.course_id,self.created)
return "%s: %s (%s)" % (self.user, self.course_id, self.created)
@receiver(post_save, sender=CourseEnrollment)
def assign_default_role(sender, instance, **kwargs):
......@@ -276,6 +279,7 @@ def add_user_to_default_group(user, group):
utg.users.add(User.objects.get(username=user))
utg.save()
@receiver(post_save, sender=User)
def update_user_information(sender, instance, created, **kwargs):
try:
......@@ -286,6 +290,7 @@ def update_user_information(sender, instance, created, **kwargs):
log.error(unicode(e))
log.error("update user info to discussion failed for user with id: " + str(instance.id))
########################## REPLICATION SIGNALS #################################
# @receiver(post_save, sender=User)
def replicate_user_save(sender, **kwargs):
......@@ -295,6 +300,7 @@ def replicate_user_save(sender, **kwargs):
for course_db_name in db_names_to_replicate_to(user_obj.id):
replicate_user(user_obj, course_db_name)
# @receiver(post_save, sender=CourseEnrollment)
def replicate_enrollment_save(sender, **kwargs):
"""This is called when a Student enrolls in a course. It has to do the
......@@ -320,12 +326,14 @@ def replicate_enrollment_save(sender, **kwargs):
log.debug("Replicating user profile because of new enrollment")
user_profile = UserProfile.objects.get(user_id=enrollment_obj.user_id)
replicate_model(UserProfile.save, user_profile, enrollment_obj.user_id)
# @receiver(post_delete, sender=CourseEnrollment)
def replicate_enrollment_delete(sender, **kwargs):
enrollment_obj = kwargs['instance']
return replicate_model(CourseEnrollment.delete, enrollment_obj, enrollment_obj.user_id)
# @receiver(post_save, sender=UserProfile)
def replicate_userprofile_save(sender, **kwargs):
"""We just updated the UserProfile (say an update to the name), so push that
......@@ -333,12 +341,13 @@ def replicate_userprofile_save(sender, **kwargs):
user_profile_obj = kwargs['instance']
return replicate_model(UserProfile.save, user_profile_obj, user_profile_obj.user_id)
######### Replication functions #########
USER_FIELDS_TO_COPY = ["id", "username", "first_name", "last_name", "email",
"password", "is_staff", "is_active", "is_superuser",
"last_login", "date_joined"]
def replicate_user(portal_user, course_db_name):
"""Replicate a User to the correct Course DB. This is more complicated than
it should be because Askbot extends the auth_user table and adds its own
......@@ -362,9 +371,10 @@ def replicate_user(portal_user, course_db_name):
course_user.save(using=course_db_name)
unmark(course_user)
def replicate_model(model_method, instance, user_id):
"""
model_method is the model action that we want replicated. For instance,
model_method is the model action that we want replicated. For instance,
UserProfile.save
"""
if not should_replicate(instance):
......@@ -379,8 +389,10 @@ def replicate_model(model_method, instance, user_id):
model_method(instance, using=db_name)
unmark(instance)
######### Replication Helpers #########
def is_valid_course_id(course_id):
"""Right now, the only database that's not a course database is 'default'.
I had nicer checking in here originally -- it would scan the courses that
......@@ -390,26 +402,30 @@ def is_valid_course_id(course_id):
"""
return course_id != 'default'
def is_portal():
"""Are we in the portal pool? Only Portal servers are allowed to replicate
their changes. For now, only Portal servers see multiple DBs, so we use
that to decide."""
return len(settings.DATABASES) > 1
def db_names_to_replicate_to(user_id):
"""Return a list of DB names that this user_id is enrolled in."""
return [c.course_id
for c in CourseEnrollment.objects.filter(user_id=user_id)
if is_valid_course_id(c.course_id)]
def marked_handled(instance):
"""Have we marked this instance as being handled to avoid infinite loops
caused by saving models in post_save hooks for the same models?"""
return hasattr(instance, '_do_not_copy_to_course_db') and instance._do_not_copy_to_course_db
def mark_handled(instance):
"""You have to mark your instance with this function or else we'll go into
an infinite loop since we're putting listeners on Model saves/deletes and
an infinite loop since we're putting listeners on Model saves/deletes and
the act of replication requires us to call the same model method.
We create a _replicated attribute to differentiate the first save of this
......@@ -418,16 +434,18 @@ def mark_handled(instance):
"""
instance._do_not_copy_to_course_db = True
def unmark(instance):
"""If we don't unmark a model after we do replication, then consecutive
"""If we don't unmark a model after we do replication, then consecutive
save() calls won't be properly replicated."""
instance._do_not_copy_to_course_db = False
def should_replicate(instance):
"""Should this instance be replicated? We need to be a Portal server and
the instance has to not have been marked_handled."""
if marked_handled(instance):
# Basically, avoid an infinite loop. You should
# Basically, avoid an infinite loop. You should
log.debug("{0} should not be replicated because it's been marked"
.format(instance))
return False
......
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