def get_or_create_user(wclass_db: WimsClass, wclass: wimsapi.Class, parameters: Dict[str, Any] ) -> Tuple[WimsUser, wimsapi.User]: """Get the WIMS' user database and wimsapi.User instances, create them if they does not exists. If at least one of the roles in the LTI request's parameters is in ROLES_ALLOWED_CREATE_WIMS_CLASS, the user will be connected as supervisor. Raises: - wimsapi.WimsAPIError if the WIMS' server denied a request. - requests.RequestException if the WIMS server could not be joined. Returns a tuple (user_db, user) where user_db is an instance of models.WimsUser and user an instance of wimsapi.User.""" try: role = Role.parse_role_lti(parameters["roles"]) if is_teacher(role): user_db = WimsUser.objects.get(lms_guid=None, wclass=wclass_db) else: user_db = WimsUser.objects.get(lms_guid=parameters['user_id'], wclass=wclass_db) user = wimsapi.User.get(wclass, user_db.quser) except WimsUser.DoesNotExist: user = create_user(parameters) i = 0 while True: try: wclass.additem(user) break except wimsapi.WimsAPIError as e: # Raised if an user with the same quser already exists, # in this case, keep trying by appending integer to quser (jdoe, jdoe1, # jdoe2, ...), stopping after 100 tries. # Can also be raised if an error occured while communicating with the # WIMS server, hence the following test. if "user already exists" not in str(e) or i >= 100: # pragma: no cover raise if i: user.quser = user.quser[:-len(str(i))] i += 1 user.quser += str(i) user_db = WimsUser.objects.create( lms_guid=parameters["user_id"], wclass=wclass_db, quser=user.quser ) logger.info("New user created (wims id: %s - lms id : %s) in class %d" % (user.quser, str(user_db.lms_guid), wclass_db.id)) return user_db, user
def send_back_all(cls, exam: WimsExam) -> int: """Send the score of the exam of every user back to the LMS.""" try: wclass = exam.wclass wims = wclass.wims grades = Class.get(wims.url, wclass.wims.ident, wims.passwd, wclass.qclass, wims.rclass, timeout=settings.WIMSAPI_TIMEOUT).getitem( exam.qexam, Exam).scores() except AdmRawError as e: # pragma: no cover if "There's no user in this class" in str(e): return 0 raise total = 0 for grade in grades: try: user = WimsUser.objects.get(wclass=wclass, quser=grade.user.quser) gl = GradeLinkExam.objects.get(user=user, activity=exam) except (GradeLinkExam.DoesNotExist, WimsUser.DoesNotExist): # pragma: no cover continue score = grade.score / 10 total += gl.send_back(score) return total
def send_back_all(cls, sheet: WimsSheet) -> int: """Send the score of the sheet of every user back to the LMS. The score used it the the one set by the teacher at the sheet creation for WIMS > 4.18, else the cumul score.""" try: wclass = sheet.wclass wims = wclass.wims grades = Class.get(wims.url, wclass.wims.ident, wims.passwd, wclass.qclass, wims.rclass, timeout=settings.WIMSAPI_TIMEOUT).getitem( sheet.qsheet, Sheet).scores() except AdmRawError as e: # pragma: no cover if "There is no user in this class" in str(e): return 0 raise total = 0 for grade in grades: try: user = WimsUser.objects.get(wclass=wclass, quser=grade.user.quser) gl = GradeLinkSheet.objects.get(user=user, activity=sheet) except (GradeLinkSheet.DoesNotExist, WimsUser.DoesNotExist): # pragma: no cover continue score = grade.score / 10 if grade.score != -1 else grade.best / 100 total += gl.send_back(score) return total
def get_exam(wclass_db: WimsClass, wclass: wimsapi.Class, qexam: int, parameters: Dict[str, Any] ) -> Tuple[WimsExam, wimsapi.Exam]: """Get the WIMS' exam database and wimsapi.Exam instances, create them if they does not exists. Raises: - wimsapi.WimsAPIError if the WIMS' server denied a request. - requests.RequestException if the WIMS server could not be joined. Returns a tuple (exam_db, exam) where exam_db is an instance of models.WimsExam and exam an instance of wimsapi.Exam.""" exam = wclass.getitem(qexam, Exam) try: exam_db = WimsExam.objects.get(wclass=wclass_db, qexam=str(qexam)) exam_db.lms_guid = parameters["resource_link_id"] exam_db.save() except WimsExam.DoesNotExist: exam_db = WimsExam.objects.create( lms_guid=parameters["resource_link_id"], wclass=wclass_db, qexam=str(qexam) ) logger.info("New exam created (wims id: %s - lms id : %s) in class %d" % (str(qexam), str(exam_db.lms_guid), wclass_db.id)) return exam_db, exam
def get_sheet(wclass_db: WimsClass, wclass: wimsapi.Class, qsheet: int, parameters: Dict[str, Any] ) -> Tuple[WimsSheet, wimsapi.Sheet]: """Get the WIMS' sheet database and wimsapi.Sheet instances, create them if they does not exists. Raises: - wimsapi.WimsAPIError if the WIMS' server denied a request. - requests.RequestException if the WIMS server could not be joined. Returns a tuple (sheet_db, sheet) where sheet_db is an instance of models.WimsSheet and sheet an instance of wimsapi.Sheet.""" sheet = wclass.getitem(qsheet, Sheet) try: sheet_db = WimsSheet.objects.get(wclass=wclass_db, qsheet=str(qsheet)) sheet_db.lms_guid = parameters["resource_link_id"] sheet_db.save() except WimsSheet.DoesNotExist: sheet_db = WimsSheet.objects.create( lms_guid=parameters["resource_link_id"], wclass=wclass_db, qsheet=str(qsheet) ) logger.info("New sheet created (wims id: %s - lms id : %s) in class %d" % (str(qsheet), str(sheet_db.lms_guid), wclass_db.id)) return sheet_db, sheet
def setUp(self): self.client = Client() self.url_ok = self.live_server_url + reverse("lti:test_xml_ok") self.url_error = self.live_server_url + reverse("lti:test_xml_error") self.url_badly_formatted = self.live_server_url + reverse( "lti:xml_badly_formatted") self.lms1 = LMS.objects.create(guid="elearning.upem.fr", url="https://elearning.u-pem.fr/", name="No WIMS", key="provider1", secret="secret1") self.wims2 = WIMS.objects.create(url=WIMS_URL, name="Two", ident="myself", passwd="toto", rclass="myclass") qclass = untar_archive() c1 = Class.get(WIMS_URL, "myself", "toto", qclass, "myclass") self.class1 = WimsClass.objects.create(lms=self.lms1, wims=self.wims2, lms_guid=1, qclass=c1.qclass, name=c1.name) self.user = WimsUser.objects.create(lms_guid="qcoumes", wclass=self.class1, quser="******") self.sheet1 = c1.getitem(1, Sheet) self.wsheet1 = WimsSheet.objects.create(wclass=self.class1, qsheet=self.sheet1.qsheet, lms_guid=1) self.exam1 = c1.getitem(1, Exam) self.wexam1 = WimsExam.objects.create(wclass=self.class1, qexam=self.sheet1.qsheet, lms_guid=1)
def setUpTestData(cls): cls.client = Client() cls.lms1 = LMS.objects.create(guid="elearning.upem.fr", url="https://elearning.u-pem.fr/", name="No WIMS", key="provider1", secret="secret1") cls.lms2 = LMS.objects.create(guid="elearning.test.fr", url="https://elearning.test.fr/", name="One WIMS", key="provider2", secret="secret1") cls.lms3 = LMS.objects.create(guid="elearning.test.fr", url="https://elearning.test.fr/", name="Two WIMS", key="provider3", secret="secret1") cls.wims1 = WIMS.objects.create(url="www.lti_app.com", name="One", ident="myself", passwd="toto", rclass="myclass") cls.wims2 = WIMS.objects.create(url=WIMS_URL, name="Two", ident="myself", passwd="toto", rclass="myclass") cls.wims1.allowed_lms.add(cls.lms2) cls.wims1.allowed_lms.add(cls.lms3) cls.wims2.allowed_lms.add(cls.lms3) c1 = Class("myclass", "Classe 1", "Institution", "email", PASSWORD, User("supervisor", "First", "Last", PASSWORD)) c2 = Class("myclass", "Classe 2", "Institution", "email", PASSWORD, User("supervisor", "First", "Last", PASSWORD)) c1.save(cls.wims2.url, cls.wims2.ident, cls.wims2.passwd) c2.save(cls.wims2.url, cls.wims2.ident, cls.wims2.passwd) cls.class1 = WimsClass.objects.create(lms=cls.lms3, wims=cls.wims2, lms_guid=1, qclass=c1.qclass, name=c1.name) cls.class2 = WimsClass.objects.create(lms=cls.lms3, wims=cls.wims2, lms_guid=2, qclass=c2.qclass, name=c2.name) cls.sheet1 = Sheet("Sheet1", "Desc1") cls.sheet2 = Sheet("Sheet2", "Desc2") c2.additem(cls.sheet1) c2.additem(cls.sheet2) cls.wsheet1 = WimsSheet.objects.create(wclass=cls.class1, qsheet=cls.sheet1.qsheet, lms_guid=1) cls.exam1 = Exam("Exam1", "Desc1") cls.exam2 = Exam("Exam2", "Desc2") c2.additem(cls.exam1) c2.additem(cls.exam2) cls.wexam1 = WimsExam.objects.create(wclass=cls.class1, qexam=cls.sheet1.qsheet, lms_guid=1)