def update_assessment_transaction( self, email, assessment_type, new_answers, score): """Stores answer and updates user scores.""" student = Student.get_by_email(email) # It may be that old Student entities don't have user_id set; fix it. if not student.user_id: student.user_id = self.get_user().user_id() answers = StudentAnswersEntity.get_by_key_name(student.user_id) if not answers: answers = StudentAnswersEntity(key_name=student.user_id) answers.updated_on = datetime.datetime.now() utils.set_answer(answers, assessment_type, new_answers) assessment_type = store_score(student, assessment_type, score) student.put() answers.put() # Also record the event, which is useful for tracking multiple # submissions and history. models.EventEntity.record( 'submit-assessment', self.get_user(), json.dumps({ 'type': 'assessment-%s' % assessment_type, 'values': new_answers, 'location': 'AnswerHandler'})) return (student, assessment_type)
def post(self): """Handles POST requests.""" user = self.personalize_page_and_get_user() if not user: self.redirect(users.create_login_url(self.request.uri)) return if not self.assert_xsrf_token_or_fail(self.request, "register-post"): return can_register = self.app_context.get_environ()["reg_form"]["can_register"] if not can_register: self.template_value["course_status"] = "full" else: name = self.request.get("form01") # create new or re-enroll old student student = Student.get_by_email(user.email()) if not student: student = Student(key_name=user.email()) student.user_id = user.user_id() student.is_enrolled = True student.name = name student.put() # Render registration confirmation page self.template_value["navbar"] = {"registration": True} self.render("confirmation.html")
def get(self): """Get a students progress.""" #teachers aren't course admins, so we probably shouldn't check for that # if not roles.Roles.is_course_admin(self.app_context): # transforms.send_json_response(self, 401, 'Access denied.', {}) # return key = self.request.get('student') errors = [] student = Student.get_by_email(key.strip()) course = self.get_course() if student: units = teacher_parsers.StudentProgressTracker.get_detailed_progress(student, course) else: errors.append('An error occurred retrieving student data. Contact your course administrator.') self.validation_error('\n'.join(errors)) return payload_dict = { 'units': units, 'student_name': student.name, 'student_email': student.email } transforms.send_json_response( self, 200, '', payload_dict=payload_dict, xsrf_token=crypto.XsrfTokenManager.create_xsrf_token( self.XSRF_TOKEN))
def post(self): user = self.personalizePageAndGetUser() if not user: self.redirect(users.create_login_url(self.request.uri)) return # Read in answers answer = json.dumps(self.request.POST.items()) original_type = self.request.get('assessment_type') # Check for enrollment status student = Student.get_by_email(user.email()) if student and student.is_enrolled: # Log answer submission logging.info(student.key().name() + ':' + answer) (student, assessment_type) = self.storeAssessmentTransaction(student.key().name(), original_type, answer) # Serve the confirmation page self.templateValue['navbar'] = {'course': True} self.templateValue['assessment'] = assessment_type self.templateValue['student_score'] = getScore(student, 'overall_score') self.render('test_confirmation.html') else: self.redirect('/register')
def get(self): """Handles GET requests.""" user = self.personalize_page_and_get_user() student = Student.get_by_email(user.email()) if not user: self.template_value['loginUrl'] = users.create_login_url('/') else: self.template_value['playlist'] = student.playlist self.template_value['playlist_urls'] = student.playlist_urls self.template_value['email'] = user.email() self.template_value['logoutUrl'] = users.create_logout_url('/') if len(student.playlist) > 0: #unit_id = str(student.playlist[0][0]) #lesson_id = str(student.playlist[0][2]) self.template_value['start_plist_url'] = str(student.playlist[0]) #('unit?unit=%s&lesson=%s' % (unit_id, lesson_id)) self.template_value['hasList'] = True else: self.template_value['hasList'] = False self.template_value['navbar'] = {'course': True} self.template_value['units'] = self.get_units() if user and Student.get_enrolled_student_by_email(user.email()): self.render('playlist.html') else: self.redirect('/preview')
def get(self): """Get activity scores.""" request = transforms.loads(self.request.get('request')) payload = transforms.loads(request.get('payload')) errors = [] students = payload['students'] force_refresh = payload['forceRefresh'] course = self.get_course() temp_students = [] for student in students: if '@' in student: temp_students.append(Student.get_by_email(student).user_id) if len(temp_students) > 0: students = temp_students if len(students) > 0: scores = teacher_parsers.ActivityScoreParser.get_activity_scores(students, course, force_refresh) else: errors.append('An error occurred retrieving activity scores. Contact your course administrator.') self.validation_error('\n'.join(errors)) return payload_dict = { 'scores': scores['scores'], 'dateCached': scores['date'].strftime("%B %d, %Y %H:%M:%S") } transforms.send_json_response( self, 200, '', payload_dict=payload_dict, xsrf_token=crypto.XsrfTokenManager.create_xsrf_token( self.XSRF_TOKEN))
def get(self): student = Student.get_by_email(self.request.get("img_id")) if student.avatar: self.response.headers["Content-Type"] = "image/png" self.response.out.write(student.avatar) else: self.error(404)
def get(self): student = Student.get_by_email(self.request.get('img_id')) if student.avatar: self.response.headers['Content-Type'] = 'image/png' self.response.out.write(student.avatar) else: self.error(404)
def post(self): """Handles POST requests.""" user = self.personalize_page_and_get_user() if not user: self.redirect(users.create_login_url(self.request.uri)) return if not self.assert_xsrf_token_or_fail(self.request, 'register-post'): return can_register = self.app_context.get_environ( )['reg_form']['can_register'] if not can_register: self.template_value['course_status'] = 'full' else: name = self.request.get('form01') surname = self.request.get('form02') age = self.request.get('form03') # create new or re-enroll old student student = Student.get_by_email(user.email()) if not student: student = Student(key_name=user.email()) student.user_id = user.user_id() student.is_enrolled = False student.name = name student.surname = surname student.age = age student.put() # Render registration confirmation page self.template_value['navbar'] = {'registration': True} self.render('confirmation.html')
def update_assessment_transaction(self, email, assessment_type, new_answers, score): """Stores answer and updates user scores.""" student = Student.get_by_email(email) # It may be that old Student entities don't have user_id set; fix it. if not student.user_id: student.user_id = self.get_user().user_id() answers = StudentAnswersEntity.get_by_key_name(student.user_id) if not answers: answers = StudentAnswersEntity(key_name=student.user_id) answers.updated_on = datetime.datetime.now() utils.set_answer(answers, assessment_type, new_answers) assessment_type = store_score(student, assessment_type, score) student.put() answers.put() # Also record the event, which is useful for tracking multiple # submissions and history. models.EventEntity.record( 'submit-assessment', self.get_user(), json.dumps({ 'type': 'assessment-%s' % assessment_type, 'values': new_answers, 'location': 'AnswerHandler' })) return (student, assessment_type)
def post(self): """Handles POST requests.""" user = self.personalize_page_and_get_user() if not user: self.redirect(users.create_login_url(self.request.uri)) return if not self.assert_xsrf_token_or_fail(self.request, 'register-post'): return can_register = self.app_context.get_environ( )['reg_form']['can_register'] if not can_register: self.template_value['course_status'] = 'full' else: name = self.request.get('form01') # create new or re-enroll old student student = Student.get_by_email(user.email()) if not student: student = Student(key_name=user.email()) student.user_id = user.user_id() student.is_enrolled = True student.name = name student.put() # Render registration confirmation page self.template_value['navbar'] = {'registration': True} self.render('confirmation.html')
def post(self): user = self.personalizePageAndGetUser() if not user: self.redirect(users.create_login_url(self.request.uri)) return if (MAX_CLASS_SIZE and Student.all(keys_only=True).count() >= MAX_CLASS_SIZE): self.templateValue['course_status'] = 'full' else: # Create student record name = self.request.get('form01') # create new or re-enroll old student student = Student.get_by_email(user.email()) if student: if not student.is_enrolled: student.is_enrolled = True student.name = name else: student = Student(key_name=user.email(), name=name, is_enrolled=True) student.put() # Render registration confirmation page self.templateValue['navbar'] = {'registration': True} self.render('confirmation.html')
def storeAssessmentTransaction(self, email, original_type, answer): student = Student.get_by_email(email) # TODO: considering storing as float for better precision score = int(round(float(self.request.get('score')))) assessment_type = storeAssessmentData(student, original_type, score, answer) student.put() return (student, assessment_type)
def name(self, email): name = self._names.get(email, None) if name: return name else: stud = Student.get_by_email(email) self._names[email] = stud.name return stud.name
def get(self): """Handles GET requests.""" if not self.personalize_page_and_get_enrolled(): return user = self.personalize_page_and_get_user() student = Student.get_by_email(user.email()) playlist = student.playlist # Extract incoming args unit_id, lesson_id = extract_unit_and_lesson_id(self) self.template_value['unit_id'] = unit_id self.template_value['lesson_id'] = lesson_id # Set template values for a unit and its lesson entities for unit in self.get_units(): if unit.unit_id == str(unit_id): self.template_value['units'] = unit lessons = self.get_lessons(unit_id) self.template_value['lessons'] = lessons # Set template values for nav bar self.template_value['navbar'] = {'course': True} # Set template values for back and next nav buttons if lesson_id == 1: self.template_value['back_button_url'] = '' elif lessons[lesson_id - 2].activity: self.template_value['back_button_url'] = ( 'activity?unit=%s&lesson=%s' % (unit_id, lesson_id - 1)) else: self.template_value['back_button_url'] = ( 'unit?unit=%s&lesson=%s' % (unit_id, lesson_id - 1)) if lessons[lesson_id - 1].activity: self.template_value['playlist_button_url'] = ( 'activity?unit=%s&lessons=%s' % (unit_id, lesson_id)) elif playlist[0] != (str(unit_id) + '.' + str(lesson_id)): self.template_value['playlist_button_url'] = '' else: self.template_value['playlist_button_url'] = ( 'unit?unit=%s&lesson=%s' % (unit_id, lesson_id + 1)) if lessons[lesson_id - 1].activity: self.template_value['next_button_url'] = ( 'activity?unit=%s&lesson=%s' % (unit_id, lesson_id)) elif lesson_id == len(lessons): self.template_value['next_button_url'] = '' else: self.template_value['next_button_url'] = ( 'unit?unit=%s&lesson=%s' % (unit_id, lesson_id + 1)) self.response.out.write(unit_id) self.response.out.write(lesson_id)
def post_save(self): if not Roles.is_course_admin(self.app_context): self.abort(403, 'You are not an admin :(') user = self.personalize_page_and_get_enrolled() student_email = self.request.GET.get('email', None) if not student_email: self.abort(404, 'email= parameter required') student = Student.get_enrolled_student_by_email(student_email) if not student: self.abort(404, Markup('Could not find a student with email "%s"') % student_email) badge_slug = custom_badge_name(student) badge = Badge.get_or_insert(badge_slug) badge_form = BadgeForm(self.request.POST, badge) comments_form = CommentsForm(self.request.POST) if not (badge_form.validate() and comments_form.validate()): self.render_edit(badge_form, comments_form) return comments_form.validate() reviewer = Student.get_by_email(comments_form.review_source.data) if not reviewer: comments_form.review_source.errors.append("Could not find a user with that e-mail address") self.render_edit(badge_form, comments_form) return page = WikiPage.get_page(student, unit=UNIT_NUMBER) if not page: self.abort(404, Markup('Could not find unit %d wikifolio for student "%s"') % (UNIT_NUMBER, student_email)) old_reviews = Annotation.reviews(whose=student, unit=UNIT_NUMBER).run() db.delete(old_reviews) Annotation.review(page, who=reviewer, text=comments_form.public_comments.data) if not Annotation.endorsements(what=page, who=user).count(limit=1): Annotation.endorse(page, who=user, optional_done=True) badge_form.populate_obj(badge) badge.put() report = PartReport.on(student, self.get_course(), 4, force_re_run=True, put=False) for rep in report.unit_reports: rep._run() rep.put() report.slug = badge_slug report.put() assertion = Badge.issue(badge, student, put=False) assertion.evidence = urljoin(self.request.host_url, '/badges/evidence?id=%d' % report.key().id()) assertion.put() self.response.write( Markup("Issued badge %s to %s, evidence %s") % ( badge.key().name(), student_email, assertion.evidence))
def post(self): user = self.personalizePageAndGetUser() if not user: self.redirect(users.create_login_url(self.request.uri)) return # Update student record student = Student.get_by_email(user.email()) if student and student.is_enrolled: student.is_enrolled = False student.put() self.templateValue['navbar'] = {'registration': True} self.render('unenroll_confirmation.html')
def get_student_dashboard(cls, dashboardHandler): """Renders Student Dashboard view. Also gets ALL students in ALL course sections for the registered user to build a jQuery autocomplete dropdown on the view. """ student_email = dashboardHandler.request.get('student') or None #email will be in the request if opened from student list # view, otherwise it will be None #need to go through every course section for the current user and get all unique students students = [] course_sections = teacher_entity.CourseSectionEntity.get_course_sections_for_user() if course_sections and len(course_sections) > 0: for course_section in course_sections.values(): if course_section.students and len(course_section.students) > 0: for student_in_section in course_section.students.values(): if not any(x['user_id'] == student_in_section['user_id'] for x in students): students.append(student_in_section) #check to see if we have a student and if we need to get detailed progress student = None if student_email: student = Student.get_by_email(student_email) if (student): course = dashboardHandler.get_course() units = teacher_parsers.StudentProgressTracker.get_detailed_progress(student, course) scores = teacher_parsers.ActivityScoreParser.get_activity_scores([student.user_id], course) else: units = None scores = None #render the template for the student dashboard view main_content = dashboardHandler.get_template( 'student_detailed_progress.html', [TEMPLATES_DIR]).render( { 'units': units, #unit completion 'student': student, #course defined student object, need email and name 'students': students, #list of students, names and emails, from a course section student list 'scores': scores }) #call DashboardHandler function to render the page dashboardHandler.render_page({ 'page_title': dashboardHandler.format_title('Student Dashboard'), 'main_content': jinja2.utils.Markup(main_content) })
def get(self): """Handles GET requests.""" if not self.personalize_page_and_get_enrolled(): return user = self.personalize_page_and_get_user() student = Student.get_by_email(user.email()) playlist = filter(lambda x: x != "", student.playlist) # Extract incoming args unit_id, lesson_id = extract_unit_and_lesson_id(self) self.template_value['unit_id'] = unit_id self.template_value['lesson_id'] = lesson_id # Set template values for a unit and its lesson entities for unit in self.get_units(): if unit.unit_id == str(unit_id): self.template_value['units'] = unit lessons = self.get_lessons(unit_id) self.template_value['lessons'] = lessons # Set template values for nav bar self.template_value['navbar'] = {'course': True} # Set template values for back and next nav buttons self.template_value['back_button_url'] = ( 'unit?unit=%s&lesson=%s' % (unit_id, lesson_id)) if str(unit_id) + '.' + str(lesson_id) in playlist: for i in range (len(playlist)): if playlist[i] == str(unit_id) + '.' + str(lesson_id) and i != len(playlist) - 1: next_playlist = playlist[i + 1] #will go out of bounds if at last item in playlist self.template_value['playlist_button_url'] = ( 'unit?unit=%s&lesson=%s' % (next_playlist[0], next_playlist[2])) break if lesson_id == len(lessons): self.template_value['next_button_url'] = '' else: self.template_value['next_button_url'] = ( 'unit?unit=%s&lesson=%s' % (unit_id, lesson_id + 1)) self.template_value['record_events'] = CAN_PERSIST_ACTIVITY_EVENTS.value self.template_value['event_xsrf_token'] = ( XsrfTokenManager.create_xsrf_token('event-post')) self.render('activity.html')
def post(self): user = self.personalizePageAndGetUser() if not user: self.redirect(users.create_login_url(self.request.uri)) return # Update student record e = self.request.get('email') n = self.request.get('name') student = Student.get_by_email(e) if student: if (n != ''): student.name = n student.put() self.redirect('/student/editstudent?email='+e)
def add_new_teacher_for_user(cls, email, school, additional_fields, alerts): student_by_email = Student.get_by_email(email) if not student_by_email: alerts.append("This email is not registered as a student for this course") return None # assume a new teacher is active by default teacher = cls._add_new_teacher_for_user( student_by_email.user_id, email, student_by_email.name, school, True, additional_fields ) if teacher: alerts.append("Teacher was successfully registered") return teacher
def post(self): """Handles POST requests""" user = self.personalize_page_and_get_user() student = Student.get_by_email(user.email()) playlist = self.request.get_all('plist') playlist_urls = list(xrange(len(playlist))) for i in range (0, len(playlist)): playlist_urls[i] = ('unit?unit=%s&lesson=%s' % (playlist[i][0], playlist[i][2])) # for i in range (0, 22): # plist = 'plist' + str(i) # plist = self.request.get(plist) # if (plist != ""): # playlist.append(plist) student.playlist_urls = playlist_urls student.playlist = playlist student.put() self.redirect('/playlist')
def get(self): user = self.personalizePageAndGetUser() if not user: self.redirect(users.create_login_url(self.request.uri)) return self.templateValue['navbar'] = {} e = self.request.get('email') # Check for existing registration -> redirect to course page student = Student.get_by_email(e) if student == None: self.templateValue['student'] = None self.templateValue['errormsg'] = 'Error: Student with email ' + e + ' can not be found on the roster.' else: self.templateValue['student'] = student self.templateValue['scores'] = getAllScores(student) self.render('student_profile.html')
def get_progress_for_course(user, course_prefix): """ DEPRECATED: Use get_total_progress_for_course instead! Returns a progess dict for the overall percentage of the course complete and an array of track percentages (in the order they appear in app.yaml) for the given course-prefix. """ track_progress = [] course_tasks_completed = 0 total_course_tasks = 0 all_course_app_contexts = controllers.sites.get_all_courses() for course_app_context in all_course_app_contexts: url_path = course_app_context.slug if not url_path.startswith("/" + course_prefix + "-"): continue namespace_manager.set_namespace(course_app_context.namespace) student = Student.get_by_email(user.email()) course = CourseModel12.load(course_app_context) tracker = progress.UnitLessonCompletionTracker(course) if student: lesson_breakdown = tracker.get_task_progress(student) track_tasks_completed = 0 total_track_tasks = 0 for unit_tasks_completed, total_unit_tasks in lesson_breakdown.values( ): track_tasks_completed += unit_tasks_completed total_track_tasks += total_unit_tasks track_progress.append(track_tasks_completed / float(total_track_tasks)) course_tasks_completed += track_tasks_completed total_course_tasks += total_track_tasks logging.info( "Lesson progress in %s: %d of %d tasks completed" % (url_path, track_tasks_completed / 2, total_track_tasks / 2)) else: track_progress.append(0) total_track_tasks = tracker.get_task_total() total_course_tasks += total_track_tasks logging.info("Student not enrolled in %s, which has %d tasks" % (url_path, total_track_tasks / 2)) namespace_manager.set_namespace("") return { "course": course_tasks_completed / float(total_course_tasks), "tracks": track_progress }
def post(self): """Handles POST requests.""" user = self.personalize_page_and_get_user() if not user: self.redirect(users.create_login_url(self.request.uri), normalize=False) return if not self.assert_xsrf_token_or_fail(self.request, 'register-post'): return can_register = self.app_context.get_environ( )['reg_form']['can_register'] if not can_register: self.template_value['course_status'] = 'full' else: name = self.request.get('form01') additional_fields = transforms.dumps(self.request.POST.items()) # create new or re-enroll old student student = Student.get_by_email(user.email()) if not student: student = Student(key_name=user.email()) student.user_id = user.user_id() student_by_uid = Student.get_student_by_user_id(user.user_id()) is_valid_student = (student_by_uid is None or student_by_uid.user_id == student.user_id) assert is_valid_student, ( 'Student\'s email and user id do not match.') student.user_id = user.user_id() student.is_enrolled = True student.name = name student.age = self.request.get('form02') student.additional_fields = additional_fields student.put() # Render registration confirmation page self.template_value['navbar'] = {'registration': True} self.render('confirmation.html')
def get(self): """Handles GET requests.""" user = self.personalize_page_and_get_user() if not user: self.redirect('/preview') return None student = Student.get_by_email(user.email()) playlist = student.playlist playlist_urls = student.playlist_urls if not self.personalize_page_and_get_enrolled(): return self.template_value['units'] = self.get_units() self.template_value['playlist'] = playlist self.template_value['playlist_urls'] = playlist_urls self.template_value['navbar'] = {'course': True} self.render('course.html')
def get(self): logging.error("c**k has occured") """Handles GET request.""" user = self.personalize_page_and_get_user() if not user: self.redirect(users.create_login_url(self.request.uri)) return student = Student.get_by_email(user.email()) if student and student.is_enrolled: self.redirect('/course') return self.template_value['navbar'] = {'registration': True} self.template_value['register_xsrf_token'] = ( XsrfTokenManager.create_xsrf_token('register-post')) if student and not student.is_enrolled: self.render('application_pending.html') else: self.render('register.html')
def create_or_enroll_student(self, user, name): # create new or re-enroll old student student = Student.get_by_email(user.email()) if not student: student = Student(key_name=user.email()) student.user_id = user.user_id() # Add to global student namespace = namespace_manager.get_namespace() try: namespace_manager.set_namespace("") global_student = Student(key_name=user.email()) global_student.user_id = user.user_id() global_student.name = name global_student.put() finally: namespace_manager.set_namespace(namespace) student.is_enrolled = True student.name = name student.put()
def post(self): """Handles POST requests.""" user = self.personalize_page_and_get_user() if not user: self.redirect( users.create_login_url(self.request.uri), normalize=False) return if not self.assert_xsrf_token_or_fail(self.request, 'register-post'): return can_register = self.app_context.get_environ( )['reg_form']['can_register'] if not can_register: self.template_value['course_status'] = 'full' else: name = self.request.get('form01') additional_fields = transforms.dumps(self.request.POST.items()) # create new or re-enroll old student student = Student.get_by_email(user.email()) if not student: student = Student(key_name=user.email()) student.user_id = user.user_id() student_by_uid = Student.get_student_by_user_id(user.user_id()) is_valid_student = (student_by_uid is None or student_by_uid.user_id == student.user_id) assert is_valid_student, ( 'Student\'s email and user id do not match.') student.user_id = user.user_id() student.is_enrolled = True student.name = name student.additional_fields = additional_fields student.put() # Render registration confirmation page self.template_value['navbar'] = {'registration': True} self.render('confirmation.html')
def post(self): """Handles POST requests.""" user = self.personalize_page_and_get_user() if not user: self.redirect(users.create_login_url(self.request.uri), normalize=False) return if not self.assert_xsrf_token_or_fail(self.request, "register-post"): return can_register = self.app_context.get_environ()["reg_form"]["can_register"] if not can_register: self.template_value["course_status"] = "full" else: name = self.request.get("form01") additional_fields = transforms.dumps(self.request.POST.items()) # create new or re-enroll old student student = Student.get_by_email(user.email()) if not student: student = Student(key_name=user.email()) student.user_id = user.user_id() student_by_uid = Student.get_student_by_user_id(user.user_id()) is_valid_student = student_by_uid is None or student_by_uid.user_id == student.user_id assert is_valid_student, "Student's email and user id do not match." student.user_id = user.user_id() student.is_enrolled = True student.name = name student.age = self.request.get("formAge") student.additional_fields = additional_fields student.put() # Render registration confirmation page self.template_value["navbar"] = {"registration": True} self.render("confirmation.html")
def get_progress_for_course(user, course_prefix): """ DEPRECATED: Use get_total_progress_for_course instead! Returns a progess dict for the overall percentage of the course complete and an array of track percentages (in the order they appear in app.yaml) for the given course-prefix. """ track_progress = [] course_tasks_completed = 0 total_course_tasks = 0 all_course_app_contexts = controllers.sites.get_all_courses() for course_app_context in all_course_app_contexts: url_path = course_app_context.slug if not url_path.startswith("/" + course_prefix + "-"): continue namespace_manager.set_namespace(course_app_context.namespace) student = Student.get_by_email(user.email()) course = CourseModel12.load(course_app_context) tracker = progress.UnitLessonCompletionTracker(course) if student: lesson_breakdown = tracker.get_task_progress(student) track_tasks_completed = 0 total_track_tasks = 0 for unit_tasks_completed, total_unit_tasks in lesson_breakdown.values(): track_tasks_completed += unit_tasks_completed total_track_tasks += total_unit_tasks track_progress.append(track_tasks_completed / float(total_track_tasks)) course_tasks_completed += track_tasks_completed total_course_tasks += total_track_tasks logging.info( "Lesson progress in %s: %d of %d tasks completed" % (url_path, track_tasks_completed / 2, total_track_tasks / 2) ) else: track_progress.append(0) total_track_tasks = tracker.get_task_total() total_course_tasks += total_track_tasks logging.info("Student not enrolled in %s, which has %d tasks" % (url_path, total_track_tasks / 2)) namespace_manager.set_namespace("") return {"course": course_tasks_completed / float(total_course_tasks), "tracks": track_progress}
def get_total_progress_for_course(email, course_prefix, as_percent=True, get_total_tasks=False): """ Returns a progess dict for the overall percentage of the course complete and an array of track percentages, which is a dictionary of the total progress in the course and the progress of each unit, (in the order they appear in app.yaml) for the given course-prefix. as_percent is used to specify if the unit's are expressed in percentage or as number of completed tasks with the 'get_total_tasks' flag each unit will have another entry called unitid-total that will be the number of total tasks in the unit """ track_progress = [] course_tasks_completed = 0 total_course_tasks = 0 all_course_app_contexts = controllers.sites.get_all_courses() for course_app_context in all_course_app_contexts: url_path = course_app_context.slug if not url_path.startswith("/" + course_prefix + "-"): continue namespace_manager.set_namespace(course_app_context.namespace) student = Student.get_by_email(email) course = CourseModel12.load(course_app_context) tracker = progress.UnitLessonCompletionTracker(course) if student: lesson_breakdown = tracker.get_task_progress_with_title(student) track_tasks_completed = 0 total_track_tasks = 0 units = {} for unit_title, unit in lesson_breakdown.items(): track_tasks_completed += unit[0] total_track_tasks += unit[1] if as_percent: units[unit_title] = unit[0] / float(unit[1]) else: units[unit_title] = unit[0] / 2 if get_total_tasks: units[unit_title + "-total"] = unit[1] / 2 track_progress.append({ 'name': course_app_context.get_title(), 'url': url_path, 'track': track_tasks_completed / float(total_track_tasks), 'units': units, 'blurb': course_app_context.get_environ()['course']['blurb'].strip() }) course_tasks_completed += track_tasks_completed total_course_tasks += total_track_tasks logging.info( "Lesson progress in %s: %d of %d tasks completed" % (url_path, track_tasks_completed / 2, total_track_tasks / 2)) else: track = { 'name': course_app_context.get_title(), 'track': 0, 'url': url_path, 'units': {}, 'blurb': course_app_context.get_environ()['course']['blurb'].strip() } total_track_tasks = tracker.get_task_total() for unit in tracker.get_course_units(): track['units'][unit.unit_id + ":" + unit.title] = 0 if get_total_tasks: unit_tasks = tracker.get_num_tasks_for_unit(unit) track['units'][unit.unit_id + ":" + unit.title + "-total"] = unit_tasks total_course_tasks += total_track_tasks track_progress.append(track) logging.info("Student not enrolled in %s, which has %d tasks" % (url_path, total_track_tasks / 2)) namespace_manager.set_namespace("") if total_course_tasks == 0: logging.warn('WARNING: track %s has 0 total tasks' % url_path) total_course_tasks = 1 return { "course": course_tasks_completed / float(total_course_tasks), "tracks": track_progress }
def post(self): """Handles POST requests.""" user = self.personalize_page_and_get_user() if not user: self.redirect( users.create_login_url(self.request.uri), normalize=False) return if not self.assert_xsrf_token_or_fail(self.request, 'register-post'): return can_register = self.app_context.get_environ( )['reg_form']['can_register'] if not can_register: self.template_value['course_status'] = 'full' else: missing = self.find_missing_fields(self.request.POST) if missing: self.template_value['navbar'] = {'registration': True} self.template_value['content'] = ''' <div class="gcb-col-11 gcb-aside"> <h2>Something is missing...</h2> <p>You didn't fill out all the required fields in the registration form. Please use your browser's BACK button, and complete the form before submitting.</p> <p>Missing: {0}</p> <p>Thanks!</p> </div> '''.format(", ".join(missing)) self.render('bare.html') return # We accept the form. Now populate the student model: # create new or re-enroll old student student = Student.get_by_email(user.email()) if not student: student = Student(key_name=user.email()) student.user_id = user.user_id() student_by_uid = Student.get_student_by_user_id(user.user_id()) is_valid_student = (student_by_uid is None or student_by_uid.user_id == student.user_id) assert is_valid_student, ( 'Student\'s email and user id do not match.') student.user_id = user.user_id() student.is_enrolled = True string_fields = ('name', 'location_city', 'location_state', 'location_country', 'education_level', 'role', 'other_role') for field in string_fields: setattr(student, field, self.request.POST.get(field, None)) string_list_fields = ('grade_levels', 'title_and_setting', 'research_area', 'faculty_area', 'student_subject') for field in string_list_fields: raw = self.request.POST.get(field, '') if len(raw) > 0: values = [s.strip() for s in raw.split(',')] setattr(student, field, values) student.put() # now that we're in full registration, don't subscribe to pre-reg any more #mailchimp.subscribe('pre-reg', user.email(), student.name) self.redirect('confirm') return # Render registration confirmation page self.template_value['navbar'] = {'registration': True} self.render('confirmation.html')
def add_mentors(cls, handler): template_values = {} template_values['page_title'] = handler.format_title('Added Mentors') mentor_email_lc_list = cls.parse_mentor_csv( handler.request.get('mentor_email_list')) added_mentors = [] not_found_mentors = [] for m in mentor_email_lc_list: if len(m) < 1: continue email = m[0].strip() if len(m) >= 2: college_id = m[1].strip() else: college_id = '' if not email: continue p = Student.get_by_email(email) if (p is None or (college_id and local_chapter_model.LocalChapterDAO. get_local_chapter_by_key(college_id) is None)): not_found_mentors.append(email) else: mentor = Mentor.get_or_create(user_id=p.user_id) if college_id: mentor.local_chapter = True mentor.college_id = college_id else: mentor.local_chapter = False mentor.put() added_mentors.append(email) content = safe_dom.NodeList() if len(added_mentors) > 0: content.append( safe_dom.Element('h3').add_text('Successfully added Mentors')) l = safe_dom.Element('ol') for m in added_mentors: l.add_child(safe_dom.Element('li').add_text(m)) content.append(l) if len(not_found_mentors) > 0: content.append( safe_dom.Element('h3').add_text('Mentor Addition Failed')) l = safe_dom.Element('ol') for m in not_found_mentors: l.add_child(safe_dom.Element('li').add_text(m)) content.append(l) if len(not_found_mentors) == 0 and len(added_mentors) == 0: content.append( safe_dom.Element('h3').add_text( 'No Emails specified for adding to mentor list')) handler.render_page( { 'page_title': handler.format_title(cls.NAME), 'main_content': content }, in_action=cls.DASHBOARD_NAV, in_tab=cls.DASHBOARD_SHOW_LIST_TAB)
def put(self): """Inserts or updates a course section.""" request = transforms.loads(self.request.get('request')) key = request.get('key') if not self.assert_xsrf_token_or_fail( request, self.XSRF_TOKEN, {}): return payload = request.get('payload') json_dict = transforms.loads(payload) python_dict = transforms.json_to_dict( json_dict, self.get_schema().get_json_schema_dict(), permit_none_values=True) version = python_dict.get('version') if version not in self.SCHEMA_VERSIONS: self.validation_error('Version %s not supported.' % version) return errors = [] teacher = teacher_entity.Teacher.get_by_email(users.get_current_user().email()) if not teacher: errors.append('Unable to save changes. Teacher is not registered. Please contact a course admin.') self.validation_error('\n'.join(errors)) return if not teacher.is_active: errors.append('Unable to save changes. Teacher account is inactive.') self.validation_error('\n'.join(errors)) return if key: key_after_save = key new_course_section = teacher_entity.CourseSectionEntity.get_course_for_user(key) students = new_course_section.students or {} emails = "" if 'students' in python_dict and python_dict['students'] is not None: emails = python_dict['students']['emails'].split(',') for email in emails: clean_email = email.strip().replace('\n', '').replace('\r', '') student = Student.get_by_email(clean_email) if student: if python_dict['students']['action'] == 'insert': student_info = {} student_info['email'] = clean_email student_info['name'] = student.name student_info['user_id'] = student.user_id students[student.user_id] = student_info else: students.pop(student.user_id, None) else: errors.append('Unable to find student with email: ' + clean_email) sorted_students = sorted(students.values(), key=lambda k: (k['name'])) if python_dict.get('name') != None: new_course_section.section_name = python_dict.get('name') if python_dict.get('active') != None: new_course_section.is_active = python_dict.get('active') if python_dict.get('description') != None: new_course_section.section_description = python_dict.get('description') if python_dict.get('year') != None: new_course_section.section_year = python_dict.get('year') course_section = teacher_entity.CourseSectionDTO.build( new_course_section.section_name, new_course_section.section_description, new_course_section.is_active, students, new_course_section.section_year) teacher_entity.CourseSectionEntity.update_course_section(key, course_section, errors) else: course_section = teacher_entity.CourseSectionDTO.build( python_dict.get('name'), python_dict.get('description'), python_dict.get('active'), {}, python_dict.get('year')) key_after_save = teacher_entity.CourseSectionEntity.add_new_course_section(key, course_section, errors) if errors: self.validation_error('\n'.join(errors), key=key_after_save) return section = teacher_entity.CourseSectionEntity.get_course_for_user(key_after_save) if section: section.students = sorted_students if section.students and len(section.students) > 0: for student in section.students: student['unit_completion'] = teacher_parsers.StudentProgressTracker.get_unit_completion( Student.get_by_email( student[ 'email']), self.get_course()) student['course_completion'] = teacher_parsers.StudentProgressTracker.get_overall_progress( Student.get_by_email( student[ 'email']), self.get_course()) student['detailed_course_completion'] = \ teacher_parsers.StudentProgressTracker.get_detailed_progress( Student.get_by_email(student['email']), self.get_course()) course_sections = teacher_entity.CourseSectionEntity.get_course_sections_for_user() if course_sections is not None: sorted_course_sections = sorted(course_sections.values(), key=lambda k: (k.section_year, k.section_name.lower())) else: sorted_course_sections = {} payload_dict = { 'key': key_after_save, 'section': section, 'section_list': sorted_course_sections } transforms.send_json_response( self, 200, 'Saved.', payload_dict)
def post_save(self): if not Roles.is_course_admin(self.app_context): self.abort(403, 'You are not an admin :(') user = self.personalize_page_and_get_enrolled() student_email = self.request.GET.get('email', None) if not student_email: self.abort(404, 'email= parameter required') student = Student.get_enrolled_student_by_email(student_email) if not student: self.abort( 404, Markup('Could not find a student with email "%s"') % student_email) badge_slug = custom_badge_name(student) badge = Badge.get_or_insert(badge_slug) badge_form = BadgeForm(self.request.POST, badge) comments_form = CommentsForm(self.request.POST) if not (badge_form.validate() and comments_form.validate()): self.render_edit(badge_form, comments_form) return comments_form.validate() reviewer = Student.get_by_email(comments_form.review_source.data) if not reviewer: comments_form.review_source.errors.append( "Could not find a user with that e-mail address") self.render_edit(badge_form, comments_form) return page = WikiPage.get_page(student, unit=UNIT_NUMBER) if not page: self.abort( 404, Markup('Could not find unit %d wikifolio for student "%s"') % (UNIT_NUMBER, student_email)) old_reviews = Annotation.reviews(whose=student, unit=UNIT_NUMBER).run() db.delete(old_reviews) Annotation.review(page, who=reviewer, text=comments_form.public_comments.data) if not Annotation.endorsements(what=page, who=user).count(limit=1): Annotation.endorse(page, who=user, optional_done=True) badge_form.populate_obj(badge) badge.put() report = PartReport.on(student, self.get_course(), 4, force_re_run=True, put=False) for rep in report.unit_reports: rep._run() rep.put() report.slug = badge_slug report.put() assertion = Badge.issue(badge, student, put=False) assertion.evidence = urljoin( self.request.host_url, '/badges/evidence?id=%d' % report.key().id()) assertion.put() self.response.write( Markup("Issued badge %s to %s, evidence %s") % (badge.key().name(), student_email, assertion.evidence))
def get(self): """Handles GET requests.""" if not self.personalize_page_and_get_enrolled(): return user = self.personalize_page_and_get_user() student = Student.get_by_email(user.email()) playlist = filter(lambda x: x != "", student.playlist) # Extract incoming args unit_id, lesson_id = extract_unit_and_lesson_id(self) self.template_value['unit_id'] = unit_id self.template_value['lesson_id'] = lesson_id # Set template values for a unit and its lesson entities for unit in self.get_units(): if unit.unit_id == str(unit_id): self.template_value['units'] = unit lessons = self.get_lessons(unit_id) self.template_value['lessons'] = lessons # Set template values for nav bar self.template_value['navbar'] = {'course': True} # Set template values for back and next nav buttons if lesson_id == 1: self.template_value['back_button_url'] = '' elif lessons[lesson_id - 2].activity: self.template_value['back_button_url'] = ( 'activity?unit=%s&lesson=%s' % (unit_id, lesson_id - 1)) else: self.template_value['back_button_url'] = ( 'unit?unit=%s&lesson=%s' % (unit_id, lesson_id - 1)) if lessons[lesson_id - 1].activity: self.template_value['playlist_button_url'] = ( 'activity?unit=%s&lesson=%s' % (unit_id, lesson_id)) elif str(unit_id) + '.' + str(lesson_id) in playlist: for i in range (len(playlist)): if playlist[i] == str(unit_id) + '.' + str(lesson_id): if i != len(playlist) - 1: next_playlist = playlist[i + 1] #will go out of bounds if at last item in playlist self.template_value['playlist_button_url'] = ( 'unit?unit=%s&lesson=%s' % (next_playlist[0], next_playlist[2])) break # if lessons[lesson_id - 1].activity: # self.template_value['playlist_button_url'] = ( # 'activity?unit=%s&lessons=%s' % (unit_id, lesson_id)) # else: # self.template_value['playlist_button_url'] = ( # 'unit?unit=%s&lesson=%s' % (unit_id, lesson_id + # 1)) if lessons[lesson_id - 1].activity: self.template_value['next_button_url'] = ( 'activity?unit=%s&lesson=%s' % (unit_id, lesson_id)) elif lesson_id == len(lessons): self.template_value['next_button_url'] = '' else: self.template_value['next_button_url'] = ( 'unit?unit=%s&lesson=%s' % (unit_id, lesson_id + 1)) self.render('unit.html')
def get_student(self): """Get the current student.""" user = self.get_user() if user is None: return None return Student.get_by_email(user.email())
def get_roster(cls, dashboardHandler): """Renders the Roster view. Displays all students in a single course section Also allows user to add students to a course section """ template_values = {} template_values['add_student_xsrf_token'] = crypto.XsrfTokenManager.create_xsrf_token( teacher_rest_handlers.CourseSectionRestHandler.XSRF_TOKEN) #need list of units and lessons for select elements that determine which progress value to display #need a list of units, need the titles, unit ids, types units = dashboardHandler.get_course().get_units() units_filtered = filter(lambda x: x.type == 'U', units) #filter out assessments template_values['units'] = units_filtered #need to get lessons, but only for units that aren't assessments lessons = {} for unit in units_filtered: unit_lessons = dashboardHandler.get_course().get_lessons(unit.unit_id) unit_lessons_filtered = [] for lesson in unit_lessons: unit_lessons_filtered.append({ 'title': lesson.title, 'unit_id': lesson.unit_id, 'lesson_id': lesson.lesson_id }) lessons[unit.unit_id] = unit_lessons_filtered template_values['lessons'] = transforms.dumps(lessons, {}) #passing in JSON to template so it can be used # in JavaScript course_section_id = dashboardHandler.request.get('section') course_section = teacher_entity.CourseSectionEntity.get_course_for_user(course_section_id) students = {} #need to get progress values for ALL students since we show completion for every student if course_section.students and len(course_section.students) > 0: #course_section.students = sorted(course_section.students.values(), key=lambda k: (k['name'])) for student in course_section.students.values(): temp_student = {} temp_student['unit_completion'] = teacher_parsers.StudentProgressTracker.get_unit_completion( Student.get_by_email( student[ 'email']), dashboardHandler.get_course()) temp_student['course_completion'] = teacher_parsers.StudentProgressTracker.get_overall_progress(Student.get_by_email(student[ 'email']), dashboardHandler.get_course()) temp_student['detailed_course_completion'] = teacher_parsers.StudentProgressTracker.get_detailed_progress( Student.get_by_email(student['email']), dashboardHandler.get_course()) temp_student['email'] = student['email'] temp_student['name'] = student['name'] students[student['email']] = temp_student course_section.students = students #passing in students as JSON so JavaScript can handle updating completion values easier template_values['students_json'] = transforms.dumps(course_section.students, {}) template_values['namespace'] = dashboardHandler.get_course()._namespace.replace('ns_', '') if course_section: template_values['section'] = course_section #render student_list.html for Roster view main_content = dashboardHandler.get_template( 'student_list.html', [TEMPLATES_DIR]).render(template_values) #DashboardHandler renders the page dashboardHandler.render_page({ 'page_title': dashboardHandler.format_title('Student List'), 'main_content': jinja2.utils.Markup(main_content)})