Beispiel #1
0
    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')
Beispiel #5
0
    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))
Beispiel #7
0
 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)
Beispiel #8
0
 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)
Beispiel #9
0
    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')
Beispiel #10
0
    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)
Beispiel #11
0
    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')
Beispiel #12
0
  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')
Beispiel #13
0
  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)
Beispiel #14
0
 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
Beispiel #15
0
 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
Beispiel #16
0
    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)
Beispiel #17
0
    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))
Beispiel #18
0
  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)
        })
Beispiel #20
0
    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')
Beispiel #21
0
  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
Beispiel #23
0
 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')
Beispiel #24
0
  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
    }
Beispiel #26
0
    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')
Beispiel #27
0
    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')
Beispiel #28
0
    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')
Beispiel #29
0
    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()
Beispiel #30
0
    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')
Beispiel #31
0
    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
    }
Beispiel #34
0
    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')
Beispiel #35
0
    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)
Beispiel #37
0
    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))
Beispiel #38
0
    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')
Beispiel #39
0
 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())
Beispiel #40
0
 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)})