diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 799c71eafc8359427737b436a46a6c1e0edcd9cc..de1e737455dcd4f841407159ecb105ba35024d1a 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -70,6 +70,7 @@ from util.json_request import JsonResponse from util.sandboxing import can_execute_unsafe_code, get_python_lib_zip from util import milestones_helpers from util.module_utils import yield_dynamic_descriptor_descendents +from verify_student.services import ReverificationService log = logging.getLogger(__name__) @@ -618,6 +619,7 @@ def get_module_system_for_user(user, field_data_cache, 'fs': xblock.reference.plugins.FSService(), 'field-data': field_data, 'user': DjangoXBlockUserService(user, user_is_staff=user_is_staff), + "reverification": ReverificationService() }, get_user_role=lambda: get_user_role(user, course_id), descriptor_runtime=descriptor._runtime, # pylint: disable=protected-access diff --git a/lms/djangoapps/verify_student/models.py b/lms/djangoapps/verify_student/models.py index 561c59d585780dd27863835860d567929f3eccac..5849755de091417377a535d0d2112ddc0a418e3d 100644 --- a/lms/djangoapps/verify_student/models.py +++ b/lms/djangoapps/verify_student/models.py @@ -17,6 +17,7 @@ import uuid from boto.s3.connection import S3Connection from boto.s3.key import Key +from django.core.exceptions import ObjectDoesNotExist import pytz import requests @@ -945,6 +946,20 @@ class VerificationCheckpoint(models.Model): """ self.photo_verification.add(verification_attempt) # pylint: disable=no-member + def get_user_latest_status(self, user_id): + """ Return the latest status of the given checkpoint attempt by user + + Args: + user_id(str): Id of user + + Returns: + VerificationStatus object if found any else None + """ + try: + return self.checkpoint_status.filter(user_id=user_id).latest() # pylint: disable=E1101 + except ObjectDoesNotExist: + return None + @classmethod def get_verification_checkpoint(cls, course_id, checkpoint_name): """Get the verification checkpoint for given course_id and checkpoint name @@ -976,13 +991,16 @@ class VerificationStatus(models.Model): ("error", "error") ) - checkpoint = models.ForeignKey(VerificationCheckpoint) + checkpoint = models.ForeignKey(VerificationCheckpoint, related_name="checkpoint_status") user = models.ForeignKey(User) status = models.CharField(choices=VERIFICATION_STATUS_CHOICES, db_index=True, max_length=32) timestamp = models.DateTimeField(auto_now_add=True) response = models.TextField(null=True, blank=True) error = models.TextField(null=True, blank=True) + class Meta(object): # pylint: disable=missing-docstring + get_latest_by = "timestamp" + @classmethod def add_verification_status(cls, checkpoint, user, status): """ Create new verification status object diff --git a/lms/djangoapps/verify_student/services.py b/lms/djangoapps/verify_student/services.py new file mode 100644 index 0000000000000000000000000000000000000000..cc43f38504e1c920c8899db3ec186185393bd00f --- /dev/null +++ b/lms/djangoapps/verify_student/services.py @@ -0,0 +1,50 @@ +""" +Implement the Reverification XBlock "reverification" server +""" +from opaque_keys.edx.keys import CourseKey +from django.core.exceptions import ObjectDoesNotExist +from django.core.urlresolvers import reverse +from verify_student.models import VerificationCheckpoint, VerificationStatus + + +class ReverificationService(object): + """ Service to implement the Reverification XBlock "reverification" service + + """ + + def get_status(self, user_id, course_id, checkpoint_name): + """ Check if the user has any verification attempt for this checkpoint and course_id + + Args: + user_id(str): User Id string + course_id(str): A string of course_id + checkpoint_name(str): Verification checkpoint name + + Returns: + Verification Status string if any attempt submitted by user else None + """ + course_key = CourseKey.from_string(course_id) + try: + checkpoint_status = VerificationStatus.objects.filter( + user_id=user_id, + checkpoint__course_id=course_key, + checkpoint__checkpoint_name=checkpoint_name + ).latest() + return checkpoint_status.status + except ObjectDoesNotExist: + return None + + def start_verification(self, course_id, checkpoint_name, item_id): # pylint: disable=W0613 + """ Get or create the verification checkpoint and return the re-verification link + + Args: + course_id(str): A string of course_id + checkpoint_name(str): Verification checkpoint name + + Returns: + Re-verification link + """ + course_key = CourseKey.from_string(course_id) + VerificationCheckpoint.objects.get_or_create(course_id=course_key, checkpoint_name=checkpoint_name) + re_verification_link = reverse("verify_student_incourse_reverify", args=(course_id, checkpoint_name)) + return re_verification_link