def get_video_progress_for_students(students, granular=True, days=31):
    def get_key_and_progress(user_video):
        vid_id = UserVideo.video.get_value_for_datastore(user_video).id()
        points = video_progress_from_points(VideoPointCalculator(user_video))
        if points > 0.9:
            progress = "completed"
        elif points > 0.66:
            progress = "watched-most"
        elif points > 0.33:
            progress = "watched-some"
        else:
            progress = "started"
        return vid_id, progress

    dt_start = datetime.datetime.now() - datetime.timedelta(days=days)
    keys = [s.user for s in students]
    key_to_student = dict(zip(keys, students))
    items = []
    for key_chunk in (keys[i:i+30] for i in xrange(0,len(keys),30)):
        query = UserVideo.all().filter("last_watched >=", dt_start)
        items.extend(query.filter("user in", key_chunk))

    students_progress = {student:{} for student in students}
    for user_video in items:
        user_key = UserVideo.user.get_value_for_datastore(user_video)
        student = key_to_student[user_key]
        vid_id, progress = get_key_and_progress(user_video)
        students_progress[student][vid_id] = progress

    return students_progress
示例#2
0
    def __init__(self, video, user_data):
        self.video_key = video.key()
        self.video_readable_id = video.readable_id
        self.description = video.title

        user_video = UserVideo.get_for_video_and_user_data(video, user_data)
        if user_video:
            self.progress = user_video.progress
        else:
            self.progress = 0.0
示例#3
0
    def __init__(self, video, user_data):
        self.video_key = video.key()
        self.video_readable_id = video.readable_id
        self.description = video.title

        user_video = UserVideo.get_for_video_and_user_data(video, user_data)
        if user_video:
            self.progress = user_video.progress
        else:
            self.progress = 0.0
示例#4
0
文件: api.py 项目: adamwulf/old-khan
    def get(self):  
        user = util.get_current_user()
        student = user
        student_email = self.request.get('student_email')
        if user:
        	pass
        else:
            student = users.User(email=student_email)

        user = student
        if student_email and student_email != user.email():
            #logging.info("user is a coach trying to look at data for student")
            student = users.User(email=student_email)
            user_data = UserData.get_or_insert_for(student)
        else:
            #logging.info("user is a student looking at their own data")
            user_data = UserData.get_or_insert_for(user)  
                                            
        user_data_dict = {
                   'email': user_data.user.email(),
                   'moderator': user_data.moderator,
                   'joined': self.datetime_to_str(user_data.joined),     
                   'last_login': self.datetime_to_str(user_data.last_login),
                   'proficient_exercises': user_data.proficient_exercises,
                   'all_proficient_exercises': user_data.all_proficient_exercises,
                   'suggested_exercises': user_data.suggested_exercises,
                   'assigned_exercises': user_data.assigned_exercises,
                   'need_to_reassess': user_data.need_to_reassess,
                   'points': user_data.points,
                   'coaches': user_data.coaches,
                   }
        
        user_exercises = []
        for ue in UserExercise.all().filter('user ='******'exercise': ue.exercise,
                       'streak': ue.streak,
                       'longest_streak': ue.longest_streak,
                       'first_done': self.datetime_to_str(ue.first_done),
                       'last_done': self.datetime_to_str(ue.last_done),
                       'total_done': ue.total_done,
                       'last_review': self.datetime_to_str(ue.last_review),
                       'review_interval_secs': ue.review_interval_secs,                       
                       'proficient_date': self.datetime_to_str(ue.proficient_date),                       
            }
            user_exercises.append(ue_dict)            

        user_videos = []
        for uv in UserVideo.all().filter('user ='******'video': uv.video.youtube_id,
                       'seconds_watched': uv.seconds_watched,
                       'last_second_watched': uv.last_second_watched,
                       'last_watched': self.datetime_to_str(uv.last_watched),        
            }
            user_videos.append(uv_dict)  
            
        problems = []
        for problem in ProblemLog.all().filter('user ='******'exercise': problem.exercise,
                            'correct': problem.correct,
                            'time_done': self.datetime_to_str(problem.time_done),
                            'time_taken': problem.time_taken,
                            'problem_number': problem.problem_number,
                            'hint_used': problem.hint_used
            }        
            problems.append(problem_dict)    
        
        export_dict = {'UserData': user_data_dict,
                       'UserExercise': user_exercises,
                       'ProblemLog': problems,
                       'UserVideo': user_videos}
        self.response.out.write(json.dumps(export_dict, indent=4))
示例#5
0
文件: api.py 项目: adamwulf/old-khan
    def post(self):  
        user = util.get_current_user()
        student = user        
        if not user:
            self.response.out.write("please login first")        
        elif App.is_dev_server:
            student_email = self.request.get('student_email')
            if student_email and student_email != user.email():
                #logging.info("user is a coach trying to look at data for student")
                student = users.User(email=student_email)
                user_data = UserData.get_or_insert_for(student)
                if users.is_current_user_admin():
                    pass # allow admin to import to anyone's account                
                elif user.email() not in user_data.coaches and user.email().lower() not in user_data.coaches:
                    raise Exception('Student '+ student_email + ' does not have you as their coach')
            else:
                #logging.info("user is a student looking at their own data")
                user_data = UserData.get_or_insert_for(user)  
                                
            file_contents = self.request.POST.get('userdata').file.read()
            import_dict = json.loads(file_contents)
            user_data_dict = import_dict['UserData']
            user_exercises = import_dict['UserExercise']
            problems_unsorted = import_dict['ProblemLog']
            user_videos = import_dict['UserVideo']
            
            user_data.moderator = user_data_dict['moderator']
            user_data.joined = self.datetime_from_str(user_data_dict['joined'])
            user_data.last_login = self.datetime_from_str(user_data_dict['last_login'])
            user_data.proficient_exercises = user_data_dict['proficient_exercises']
            user_data.all_proficient_exercises = user_data_dict['all_proficient_exercises']
            user_data.suggested_exercises = user_data_dict['suggested_exercises']
            user_data.assigned_exercises = user_data_dict['assigned_exercises']
            user_data.need_to_reassess = user_data_dict['need_to_reassess']
            user_data.points = user_data_dict['points']          
            user_data.coaches = user_data_dict['coaches']
            user_data.put()

            proficient_dates = {}    
            correct_in_a_row = {}
            for problem in ProblemLog.all().filter('user ='******'time_done']))
            
            for problem in problems:
                problem_log = ProblemLog()
                problem_log.user = student
                problem_log.exercise = problem['exercise']
                problem_log.time_done = self.datetime_from_str(problem['time_done'])
                problem_log.correct = problem['correct']
                if problem_log.correct:
                    if problem_log.exercise not in correct_in_a_row:
                        correct_in_a_row[problem_log.exercise] = 1                    
                    else:
                        correct_in_a_row[problem_log.exercise] += 1                    
                    if not problem_log.exercise in proficient_dates and correct_in_a_row[problem_log.exercise] == 10:
                        proficient_dates[problem_log.exercise] = problem_log.time_done
                        #for coach in user_data.coaches:                            
                        #    class_data = coaches.Class.get_or_insert(coach, coach=coach)     
                        #    class_data.compute_stats(user_data, problem_log.time_done.date())                                                  
                problem_log.time_taken = problem['time_taken']
                if problem.has_key('problem_number'):
                    problem_log.problem_number = problem['problem_number']
                if problem.has_key('hint_used'):                    
                    problem_log.hint_used = problem['hint_used']               
                problem_log.put()  
                
            for user_exercise in UserExercise.all().filter('user ='******'exercise']
                user_exercise.parent = user_data
                user_exercise.user = student
                user_exercise.exercise = ue['exercise']
                user_exercise.streak = ue['streak']
                user_exercise.longest_streak = ue['longest_streak']
                user_exercise.first_done = self.datetime_from_str(ue['first_done'])
                user_exercise.last_done = self.datetime_from_str(ue['last_done'])
                user_exercise.total_done = ue['total_done']
                last_review = self.datetime_from_str(ue['last_review'])
                if last_review:
                    user_exercise.last_review = last_review
                user_exercise.review_interval_secs = ue['review_interval_secs']
                if user_exercise.exercise in proficient_dates:
                    user_exercise.proficient_date = proficient_dates[user_exercise.exercise]   
                else:
                    user_exercise.proficient_date = self.datetime_from_str(ue['proficient_date'])
                user_exercise.put()

            for user_video in UserVideo.all().filter('user ='******'/individualreport?student_email='+student.email())
        else:
            self.response.out.write("import is not supported on the live site")
示例#6
0
    def get(self, readable_id=""):

        # This method displays a video in the context of a particular playlist.
        # To do that we first need to find the appropriate playlist.  If we aren't
        # given the playlist title in a query param, we need to find a playlist that
        # the video is a part of.  That requires finding the video, given it readable_id
        # or, to support old URLs, it's youtube_id.
        video = None
        playlist = None
        video_id = self.request.get('v')
        playlist_title = self.request_string('playlist', default="") or self.request_string('p', default="")

        readable_id = urllib.unquote(readable_id)
        readable_id = re.sub('-+$', '', readable_id)  # remove any trailing dashes (see issue 1140)

        # If either the readable_id or playlist title is missing,
        # redirect to the canonical URL that contains them
        redirect_to_canonical_url = False
        if video_id: # Support for old links
            query = Video.all()
            query.filter('youtube_id =', video_id)
            video = query.get()

            if not video:
                raise MissingVideoException("Missing video w/ youtube id '%s'" % video_id)

            readable_id = video.readable_id
            playlist = video.first_playlist()

            if not playlist:
                raise MissingVideoException("Missing video w/ youtube id '%s'" % video_id)

            redirect_to_canonical_url = True

        if playlist_title is not None and len(playlist_title) > 0:
            query = Playlist.all().filter('title =', playlist_title)
            key_id = 0
            for p in query:
                if p.key().id() > key_id and not p.youtube_id.endswith('_player'):
                    playlist = p
                    key_id = p.key().id()

        # If a playlist_title wasn't specified or the specified playlist wasn't found
        # use the first playlist for the requested video.
        if playlist is None:
            # Get video by readable_id just to get the first playlist for the video
            video = Video.get_for_readable_id(readable_id)
            if video is None:
                raise MissingVideoException("Missing video '%s'" % readable_id)

            playlist = video.first_playlist()
            if not playlist:
                raise MissingVideoException("Missing video '%s'" % readable_id)

            redirect_to_canonical_url = True

        exid = self.request_string('exid', default=None)

        if redirect_to_canonical_url:
            qs = {'playlist': playlist.title}
            if exid:
                qs['exid'] = exid

            urlpath = "/video/%s" % urllib.quote(readable_id)
            url = urlparse.urlunparse(('', '', urlpath, '', urllib.urlencode(qs), ''))
            self.redirect(url, True)
            return

        # If we got here, we have a readable_id and a playlist_title, so we can display
        # the playlist and the video in it that has the readable_id.  Note that we don't
        # query the Video entities for one with the requested readable_id because in some
        # cases there are multiple Video objects in the datastore with the same readable_id
        # (e.g. there are 2 "Order of Operations" videos).

        videos = VideoPlaylist.get_cached_videos_for_playlist(playlist)
        previous_video = None
        next_video = None
        for v in videos:
            if v.readable_id == readable_id:
                v.selected = 'selected'
                video = v
            elif video is None:
                previous_video = v
            elif next_video is None:
                next_video = v

        if video is None:
            raise MissingVideoException("Missing video '%s'" % readable_id)

        if App.offline_mode:
            video_path = "/videos/" + get_mangled_playlist_name(playlist_title) + "/" + video.readable_id + ".flv"
        else:
            video_path = video.download_video_url()

        if video.description == video.title:
            video.description = None

        related_exercises = video.related_exercises()
        button_top_exercise = None
        if related_exercises:
            def ex_to_dict(exercise):
                return {
                    'name': exercise.display_name,
                    'url': exercise.relative_url,
                }
            button_top_exercise = ex_to_dict(related_exercises[0])

        user_video = UserVideo.get_for_video_and_user_data(video, UserData.current(), insert_if_missing=True)

        awarded_points = 0
        if user_video:
            awarded_points = user_video.points

        template_values = {
                            'playlist': playlist,
                            'video': video,
                            'videos': videos,
                            'video_path': video_path,
                            'video_points_base': consts.VIDEO_POINTS_BASE,
                            'button_top_exercise': button_top_exercise,
                            'related_exercises': [], # disabled for now
                            'previous_video': previous_video,
                            'next_video': next_video,
                            'selected_nav_link': 'watch',
                            'awarded_points': awarded_points,
                            'issue_labels': ('Component-Videos,Video-%s' % readable_id),
                            'author_profile': 'https://plus.google.com/103970106103092409324'
                        }
        template_values = qa.add_template_values(template_values, self.request)

        bingo(['struggling_videos_landing',
               'homepage_restructure_videos_landing'])
        self.render_jinja2_template('viewvideo.html', template_values)
示例#7
0
    def get(self):
        user = util.get_current_user()
        student = user
        if user:
            student_email = self.request.get('student_email')
            if student_email and student_email != user.email():
                #logging.info("user is a coach trying to look at data for student")
                student = users.User(email=student_email)
                user_data = UserData.get_or_insert_for(student)
                if users.is_current_user_admin():
                    pass  # allow admin to export anyone's data
                elif user.email() not in user_data.coaches and user.email(
                ).lower() not in user_data.coaches:
                    raise Exception('Student ' + student_email +
                                    ' does not have you as their coach')
            else:
                #logging.info("user is a student looking at their own data")
                user_data = UserData.get_or_insert_for(user)

            user_data_dict = {
                'email': user_data.user.email(),
                'moderator': user_data.moderator,
                'joined': self.datetime_to_str(user_data.joined),
                'last_login': self.datetime_to_str(user_data.last_login),
                'proficient_exercises': user_data.proficient_exercises,
                'all_proficient_exercises': user_data.all_proficient_exercises,
                'suggested_exercises': user_data.suggested_exercises,
                'assigned_exercises': user_data.assigned_exercises,
                'need_to_reassess': user_data.need_to_reassess,
                'points': user_data.points,
                'coaches': user_data.coaches,
            }

            user_exercises = []
            for ue in UserExercise.all().filter('user ='******'exercise': ue.exercise,
                    'streak': ue.streak,
                    'longest_streak': ue.longest_streak,
                    'first_done': self.datetime_to_str(ue.first_done),
                    'last_done': self.datetime_to_str(ue.last_done),
                    'total_done': ue.total_done,
                    'last_review': self.datetime_to_str(ue.last_review),
                    'review_interval_secs': ue.review_interval_secs,
                    'proficient_date':
                    self.datetime_to_str(ue.proficient_date),
                }
                user_exercises.append(ue_dict)

            user_videos = []
            for uv in UserVideo.all().filter('user ='******'video': uv.video.youtube_id,
                    'seconds_watched': uv.seconds_watched,
                    'last_second_watched': uv.last_second_watched,
                    'last_watched': self.datetime_to_str(uv.last_watched),
                }
                user_videos.append(uv_dict)

            problems = []
            for problem in ProblemLog.all().filter('user ='******'exercise': problem.exercise,
                    'correct': problem.correct,
                    'time_done': self.datetime_to_str(problem.time_done),
                    'time_taken': problem.time_taken,
                    'problem_number': problem.problem_number,
                    'hint_used': problem.hint_used
                }
                problems.append(problem_dict)

            export_dict = {
                'UserData': user_data_dict,
                'UserExercise': user_exercises,
                'ProblemLog': problems,
                'UserVideo': user_videos
            }
            self.response.out.write(json.dumps(export_dict, indent=4))
        else:
            self.redirect(util.create_login_url(self.request.uri))
示例#8
0
    def post(self):
        user = util.get_current_user()
        student = user
        if not user:
            self.response.out.write("please login first")
        elif App.is_dev_server:
            student_email = self.request.get('student_email')
            if student_email and student_email != user.email():
                #logging.info("user is a coach trying to look at data for student")
                student = users.User(email=student_email)
                user_data = UserData.get_or_insert_for(student)
                if users.is_current_user_admin():
                    pass  # allow admin to import to anyone's account
                elif user.email() not in user_data.coaches and user.email(
                ).lower() not in user_data.coaches:
                    raise Exception('Student ' + student_email +
                                    ' does not have you as their coach')
            else:
                #logging.info("user is a student looking at their own data")
                user_data = UserData.get_or_insert_for(user)

            file_contents = self.request.POST.get('userdata').file.read()
            import_dict = json.loads(file_contents)
            user_data_dict = import_dict['UserData']
            user_exercises = import_dict['UserExercise']
            problems_unsorted = import_dict['ProblemLog']
            user_videos = import_dict['UserVideo']

            user_data.moderator = user_data_dict['moderator']
            user_data.joined = self.datetime_from_str(user_data_dict['joined'])
            user_data.last_login = self.datetime_from_str(
                user_data_dict['last_login'])
            user_data.proficient_exercises = user_data_dict[
                'proficient_exercises']
            user_data.all_proficient_exercises = user_data_dict[
                'all_proficient_exercises']
            user_data.suggested_exercises = user_data_dict[
                'suggested_exercises']
            user_data.assigned_exercises = user_data_dict['assigned_exercises']
            user_data.need_to_reassess = user_data_dict['need_to_reassess']
            user_data.points = user_data_dict['points']
            user_data.coaches = user_data_dict['coaches']
            user_data.put()

            proficient_dates = {}
            correct_in_a_row = {}
            for problem in ProblemLog.all().filter('user ='******'time_done']))

            for problem in problems:
                problem_log = ProblemLog()
                problem_log.user = student
                problem_log.exercise = problem['exercise']
                problem_log.time_done = self.datetime_from_str(
                    problem['time_done'])
                problem_log.correct = problem['correct']
                if problem_log.correct:
                    if problem_log.exercise not in correct_in_a_row:
                        correct_in_a_row[problem_log.exercise] = 1
                    else:
                        correct_in_a_row[problem_log.exercise] += 1
                    if not problem_log.exercise in proficient_dates and correct_in_a_row[
                            problem_log.exercise] == 10:
                        proficient_dates[
                            problem_log.exercise] = problem_log.time_done
                        #for coach in user_data.coaches:
                        #    class_data = coaches.Class.get_or_insert(coach, coach=coach)
                        #    class_data.compute_stats(user_data, problem_log.time_done.date())
                problem_log.time_taken = problem['time_taken']
                if problem.has_key('problem_number'):
                    problem_log.problem_number = problem['problem_number']
                if problem.has_key('hint_used'):
                    problem_log.hint_used = problem['hint_used']
                problem_log.put()

            for user_exercise in UserExercise.all().filter('user ='******'exercise']
                user_exercise.parent = user_data
                user_exercise.user = student
                user_exercise.exercise = ue['exercise']
                user_exercise.streak = ue['streak']
                user_exercise.longest_streak = ue['longest_streak']
                user_exercise.first_done = self.datetime_from_str(
                    ue['first_done'])
                user_exercise.last_done = self.datetime_from_str(
                    ue['last_done'])
                user_exercise.total_done = ue['total_done']
                last_review = self.datetime_from_str(ue['last_review'])
                if last_review:
                    user_exercise.last_review = last_review
                user_exercise.review_interval_secs = ue['review_interval_secs']
                if user_exercise.exercise in proficient_dates:
                    user_exercise.proficient_date = proficient_dates[
                        user_exercise.exercise]
                else:
                    user_exercise.proficient_date = self.datetime_from_str(
                        ue['proficient_date'])
                user_exercise.put()

            for user_video in UserVideo.all().filter('user ='******'/individualreport?student_email=' + student.email())
        else:
            self.response.out.write("import is not supported on the live site")
示例#9
0
文件: main.py 项目: di445/server
    def get(self, readable_id=""):

        # This method displays a video in the context of a particular topic.
        # To do that we first need to find the appropriate topic.  If we aren't
        # given the topic title in a query param, we need to find a topic that
        # the video is a part of.  That requires finding the video, given it readable_id
        # or, to support old URLs, it's youtube_id.
        video = None
        topic = None
        video_id = self.request.get('v')
        topic_id = self.request_string('topic', default="")
        readable_id = urllib.unquote(readable_id).decode("utf-8")
        readable_id = re.sub('-+$', '', readable_id)  # remove any trailing dashes (see issue 1140)

        # If either the readable_id or topic title is missing,
        # redirect to the canonical URL that contains them
        redirect_to_canonical_url = False
        if video_id: # Support for old links
            query = Video.all()
            query.filter('youtube_id =', video_id)
            video = query.get()

            if not video:
                raise MissingVideoException("Missing video w/ youtube id '%s'" % video_id)

            readable_id = video.readable_id
            topic = video.first_topic()

            if not topic:
                raise MissingVideoException("No topic has video w/ youtube id '%s'" % video_id)

            redirect_to_canonical_url = True

        if topic_id is not None and len(topic_id) > 0:
            topic = Topic.get_by_id(topic_id)
            key_id = 0 if not topic else topic.key().id()

        # If a topic_id wasn't specified or the specified topic wasn't found
        # use the first topic for the requested video.
        if topic is None:
            # Get video by readable_id just to get the first topic for the video
            video = Video.get_for_readable_id(readable_id)
            if video is None:
                raise MissingVideoException("Missing video '%s'" % readable_id)

            topic = video.first_topic()
            if not topic:
                raise MissingVideoException("No topic has video '%s'" % readable_id)

            redirect_to_canonical_url = True

        exid = self.request_string('exid', default=None)

        if redirect_to_canonical_url:
            qs = {'topic': topic.id}
            if exid:
                qs['exid'] = exid

            urlpath = "/video/%s" % urllib.quote(readable_id)
            url = urlparse.urlunparse(('', '', urlpath, '', urllib.urlencode(qs), ''))
            self.redirect(url, True)
            return

        # If we got here, we have a readable_id and a topic, so we can display
        # the topic and the video in it that has the readable_id.  Note that we don't
        # query the Video entities for one with the requested readable_id because in some
        # cases there are multiple Video objects in the datastore with the same readable_id
        # (e.g. there are 2 "Order of Operations" videos).
        videos = Topic.get_cached_videos_for_topic(topic)
        previous_video = None
        next_video = None
        for v in videos:
            if v.readable_id == readable_id:
                v.selected = 'selected'
                video = v
            elif video is None:
                previous_video = v
            else:
                next_video = v
                break

        # If we're at the beginning or end of a topic, show the adjacent topic.
        # previous_topic/next_topic are the topic to display.
        # previous_video_topic/next_video_topic are the subtopics the videos
        # are actually in.
        previous_topic = None
        previous_video_topic = None
        next_topic = None
        next_video_topic = None

        if not previous_video:
            previous_topic = topic
            while not previous_video:
                previous_topic = previous_topic.get_previous_topic()
                if previous_topic:
                    (previous_video, previous_video_topic) = previous_topic.get_last_video_and_topic()
                else:
                    break

        if not next_video:
            next_topic = topic
            while not next_video:
                next_topic = next_topic.get_next_topic()
                if next_topic:
                    (next_video, next_video_topic) = next_topic.get_first_video_and_topic()
                else:
                    break

        if video is None:
            raise MissingVideoException("Missing video '%s'" % readable_id)

        if App.offline_mode:
            video_path = "/videos/" + get_mangled_topic_name(topic.id) + "/" + video.readable_id + ".flv"
        else:
            video_path = video.download_video_url()

        if video.description == video.title:
            video.description = None

        related_exercises = video.related_exercises()
        button_top_exercise = None
        if related_exercises:
            def ex_to_dict(exercise):
                return {
                    'name': exercise.display_name,
                    'url': exercise.relative_url,
                }
            button_top_exercise = ex_to_dict(related_exercises[0])

        user_video = UserVideo.get_for_video_and_user_data(video, UserData.current(), insert_if_missing=True)

        awarded_points = 0
        if user_video:
            awarded_points = user_video.points

        template_values = {
                            'topic': topic,
                            'video': video,
                            'videos': videos,
                            'video_path': video_path,
                            'video_points_base': consts.VIDEO_POINTS_BASE,
                            'button_top_exercise': button_top_exercise,
                            'related_exercises': [], # disabled for now
                            'previous_topic': previous_topic,
                            'previous_video': previous_video,
                            'previous_video_topic': previous_video_topic,
                            'next_topic': next_topic,
                            'next_video': next_video,
                            'next_video_topic': next_video_topic,
                            'selected_nav_link': 'watch',
                            'awarded_points': awarded_points,
                            'issue_labels': ('Component-Videos,Video-%s' % readable_id),
                            'author_profile': 'https://plus.google.com/103970106103092409324',
                            'is_mobile_allowed': True,
                        }
        template_values = qa.add_template_values(template_values, self.request)

        bingo([
            'struggling_videos_landing',
            'suggested_activity_videos_landing',
            'suggested_activity_videos_landing_binary',
        ])
        self.render_jinja2_template('viewvideo.html', template_values)
示例#10
0
    def get(self, readable_id=""):

        # This method displays a video in the context of a particular topic.
        # To do that we first need to find the appropriate topic.  If we aren't
        # given the topic title in a query param, we need to find a topic that
        # the video is a part of.  That requires finding the video, given it readable_id
        # or, to support old URLs, it's youtube_id.
        video = None
        topic = None
        video_id = self.request.get('v')
        topic_id = self.request_string('topic', default="")
        readable_id = urllib.unquote(readable_id).decode("utf-8")
        readable_id = re.sub(
            '-+$', '',
            readable_id)  # remove any trailing dashes (see issue 1140)

        # If either the readable_id or topic title is missing,
        # redirect to the canonical URL that contains them
        redirect_to_canonical_url = False
        if video_id:  # Support for old links
            query = Video.all()
            query.filter('youtube_id =', video_id)
            video = query.get()

            if not video:
                raise MissingVideoException(
                    "Missing video w/ youtube id '%s'" % video_id)

            readable_id = video.readable_id
            topic = video.first_topic()

            if not topic:
                raise MissingVideoException(
                    "No topic has video w/ youtube id '%s'" % video_id)

            redirect_to_canonical_url = True

        if topic_id is not None and len(topic_id) > 0:
            topic = Topic.get_by_id(topic_id)
            key_id = 0 if not topic else topic.key().id()

        # If a topic_id wasn't specified or the specified topic wasn't found
        # use the first topic for the requested video.
        if topic is None:
            # Get video by readable_id just to get the first topic for the video
            video = Video.get_for_readable_id(readable_id)
            if video is None:
                raise MissingVideoException("Missing video '%s'" % readable_id)

            topic = video.first_topic()
            if not topic:
                raise MissingVideoException("No topic has video '%s'" %
                                            readable_id)

            redirect_to_canonical_url = True

        exid = self.request_string('exid', default=None)

        if redirect_to_canonical_url:
            qs = {'topic': topic.id}
            if exid:
                qs['exid'] = exid

            urlpath = "/video/%s" % urllib.quote(readable_id)
            url = urlparse.urlunparse(
                ('', '', urlpath, '', urllib.urlencode(qs), ''))
            self.redirect(url, True)
            return

        # If we got here, we have a readable_id and a topic, so we can display
        # the topic and the video in it that has the readable_id.  Note that we don't
        # query the Video entities for one with the requested readable_id because in some
        # cases there are multiple Video objects in the datastore with the same readable_id
        # (e.g. there are 2 "Order of Operations" videos).
        videos = Topic.get_cached_videos_for_topic(topic)
        previous_video = None
        next_video = None
        for v in videos:
            if v.readable_id == readable_id:
                v.selected = 'selected'
                video = v
            elif video is None:
                previous_video = v
            else:
                next_video = v
                break

        # If we're at the beginning or end of a topic, show the adjacent topic.
        # previous_topic/next_topic are the topic to display.
        # previous_video_topic/next_video_topic are the subtopics the videos
        # are actually in.
        previous_topic = None
        previous_video_topic = None
        next_topic = None
        next_video_topic = None

        if not previous_video:
            previous_topic = topic
            while not previous_video:
                previous_topic = previous_topic.get_previous_topic()
                if previous_topic:
                    (previous_video, previous_video_topic
                     ) = previous_topic.get_last_video_and_topic()
                else:
                    break

        if not next_video:
            next_topic = topic
            while not next_video:
                next_topic = next_topic.get_next_topic()
                if next_topic:
                    (next_video, next_video_topic
                     ) = next_topic.get_first_video_and_topic()
                else:
                    break

        if video is None:
            raise MissingVideoException("Missing video '%s'" % readable_id)

        if App.offline_mode:
            video_path = "/videos/" + get_mangled_topic_name(
                topic.id) + "/" + video.readable_id + ".flv"
        else:
            video_path = video.download_video_url()

        if video.description == video.title:
            video.description = None

        related_exercises = video.related_exercises()
        button_top_exercise = None
        if related_exercises:

            def ex_to_dict(exercise):
                return {
                    'name': exercise.display_name,
                    'url': exercise.relative_url,
                }

            button_top_exercise = ex_to_dict(related_exercises[0])

        user_video = UserVideo.get_for_video_and_user_data(
            video, UserData.current(), insert_if_missing=True)

        awarded_points = 0
        if user_video:
            awarded_points = user_video.points

        subtitles_key_name = VideoSubtitles.get_key_name(
            'en', video.youtube_id)
        subtitles = VideoSubtitles.get_by_key_name(subtitles_key_name)
        subtitles_json = None
        if subtitles:
            subtitles_json = subtitles.load_json()

        template_values = {
            'topic': topic,
            'video': video,
            'videos': videos,
            'video_path': video_path,
            'video_points_base': consts.VIDEO_POINTS_BASE,
            'subtitles_json': subtitles_json,
            'button_top_exercise': button_top_exercise,
            'related_exercises': [],  # disabled for now
            'previous_topic': previous_topic,
            'previous_video': previous_video,
            'previous_video_topic': previous_video_topic,
            'next_topic': next_topic,
            'next_video': next_video,
            'next_video_topic': next_video_topic,
            'selected_nav_link': 'watch',
            'awarded_points': awarded_points,
            'issue_labels': ('Component-Videos,Video-%s' % readable_id),
            'author_profile': 'https://plus.google.com/103970106103092409324'
        }
        template_values = qa.add_template_values(template_values, self.request)

        bingo([
            'struggling_videos_landing',
            'suggested_activity_videos_landing',
            'suggested_activity_videos_landing_binary',
        ])
        self.render_jinja2_template('viewvideo.html', template_values)
示例#11
0
    def get(self):
        if not hasattr(secrets, 'ka_api_consumer_key') or    \
           not hasattr(secrets, 'ka_api_consumer_secret') or \
           not hasattr(secrets_dev, 'ka_api_token_key') or   \
           not hasattr(secrets_dev, 'ka_api_token_secret'):
            return self.redirect("/")

        self.setup_oauth()

        self.email = self.request_string("email")
        if not self.email:
            raise "Must supply email for user to import"

        params = copy.copy(self._default_kinds)
        params.update(self.request.params)

        # get proper user from addition 1 userexercise
        user_id_json = json.loads(
            self.api("/api/v1/user/exercises/addition_1"))
        user = users.User(user_id_json['user'])

        # UserData
        user_data_json_raw = self.api("/api/v1/user")
        user_data = UserData.from_json(json.loads(user_data_json_raw),
                                       user=user)
        self.output('user_data', user_data, user_data_json_raw)
        user_data.put()

        if 'UserVideo' in params:
            user_videos_json = json.loads(self.api("/api/v1/user/videos"))
            user_videos = []
            for user_video_json in user_videos_json[:params['UserVideo']]:
                user_video = UserVideo.from_json(user_video_json,
                                                 user_data=user_data)
                user_videos.append(user_video)
                self.output('user_video', user_video, jsonify(user_video_json))

            video_logs = defaultdict(list)
            if 'VideoLog' in params:
                for user_video in user_videos:
                    ytid = user_video.video.youtube_id
                    video_logs_json = json.loads(
                        self.api("/api/v1/user/videos/%s/log" % ytid))
                    for video_log_json in video_logs_json[:params[
                            'ProblemLog']]:
                        video_log = VideoLog.from_json(video_log_json,
                                                       user_video.video, user)
                        video_logs[user_video].append(video_log)
                        self.output("video_log", video_log,
                                    jsonify(video_log_json))

                # delete old video logs
                query = VideoLog.all(keys_only=True)
                query.filter('user ='******'UserExercise' in params:
            user_exercises_json = json.loads(
                self.api("/api/v1/user/exercises"))
            user_exercises = []
            for user_exercise_json in user_exercises_json[:params[
                    'UserExercise']]:
                user_exercise = UserExercise.from_json(user_exercise_json,
                                                       user_data)
                if user_exercise:
                    user_exercises.append(user_exercise)
                    self.output("user_exercise", user_exercise,
                                jsonify(user_exercise_json))

            problem_logs = defaultdict(list)
            if 'ProblemLog' in params:
                for user_exercise in user_exercises:
                    problem_logs_json = json.loads(
                        self.api("/api/v1/user/exercises/%s/log" %
                                 user_exercise.exercise))
                    for problem_log_json in problem_logs_json[:params[
                            'ProblemLog']]:
                        problem_log = ProblemLog.from_json(
                            problem_log_json,
                            user_data=user_data,
                            exercise=user_exercise.exercise_model)
                        problem_logs[user_exercise].append(problem_log)
                        self.output("problem_log", problem_log,
                                    jsonify(problem_log_json))

            db.put(user_exercises)
            for k, v in problem_logs.iteritems():
                db.put(v)

        if 'Goal' in params:
            with AutoNowDisabled(Goal):
                goals_json = json.loads(self.api("/api/v1/user/goals"))
                goals = []
                for goal_json in goals_json[:params['Goal']]:
                    goal = Goal.from_json(goal_json, user_data=user_data)
                    goals.append(goal)
                    self.output("goal", goal, jsonify(goal_json))

                db.put(goals)

                # need to tell the userdata that it has goals
                user_data.has_current_goals = not all(
                    [g.completed for g in goals])
                user_data.put()
示例#12
0
文件: handlers.py 项目: di445/server
    def get(self):
        if not hasattr(secrets, 'ka_api_consumer_key') or    \
           not hasattr(secrets, 'ka_api_consumer_secret') or \
           not hasattr(secrets_dev, 'ka_api_token_key') or   \
           not hasattr(secrets_dev, 'ka_api_token_secret'):
            return self.redirect("/")

        self.setup_oauth()

        self.email = self.request_string("email")
        if not self.email:
            raise "Must supply email for user to import"

        params = copy.copy(self._default_kinds)
        params.update(self.request.params)

        # get proper user from addition 1 userexercise
        user_id_json = json.loads(self.api("/api/v1/user/exercises/addition_1"))
        user = users.User(user_id_json['user'])

        # UserData
        user_data_json_raw = self.api("/api/v1/user")
        user_data = UserData.from_json(json.loads(user_data_json_raw), user=user)
        self.output('user_data', user_data, user_data_json_raw)
        user_data.put()

        if 'UserVideo' in params:
            user_videos_json = json.loads(self.api("/api/v1/user/videos"))
            user_videos = []
            for user_video_json in user_videos_json[:params['UserVideo']]:
                user_video = UserVideo.from_json(user_video_json, user_data=user_data)
                user_videos.append(user_video)
                self.output('user_video', user_video, jsonify(user_video_json))

            video_logs = defaultdict(list)
            if 'VideoLog' in params:
                for user_video in user_videos:
                    ytid = user_video.video.youtube_id
                    video_logs_json = json.loads(
                        self.api("/api/v1/user/videos/%s/log" % ytid))
                    for video_log_json in video_logs_json[:params['ProblemLog']]:
                        video_log = VideoLog.from_json(video_log_json, user_video.video, user)
                        video_logs[user_video].append(video_log)
                        self.output("video_log", video_log, jsonify(video_log_json))

                # delete old video logs
                query = VideoLog.all(keys_only=True)
                query.filter('user ='******'UserExercise' in params:
            user_exercises_json = json.loads(self.api("/api/v1/user/exercises"))
            user_exercises = []
            for user_exercise_json in user_exercises_json[:params['UserExercise']]:
                user_exercise = UserExercise.from_json(user_exercise_json, user_data)
                if user_exercise:
                    user_exercises.append(user_exercise)
                    self.output("user_exercise", user_exercise, jsonify(user_exercise_json))

            problem_logs = defaultdict(list)
            if 'ProblemLog' in params:
                for user_exercise in user_exercises:
                    problem_logs_json = json.loads(self.api(
                        "/api/v1/user/exercises/%s/log" % user_exercise.exercise))
                    for problem_log_json in problem_logs_json[:params['ProblemLog']]:
                        problem_log = ProblemLog.from_json(problem_log_json,
                            user_data=user_data,
                            exercise=user_exercise.exercise_model)
                        problem_logs[user_exercise].append(problem_log)
                        self.output("problem_log", problem_log,
                            jsonify(problem_log_json))

            db.put(user_exercises)
            for k, v in problem_logs.iteritems():
                db.put(v)

        if 'Goal' in params:
            with AutoNowDisabled(Goal):
                goals_json = json.loads(self.api("/api/v1/user/goals"))
                goals = []
                for goal_json in goals_json[:params['Goal']]:
                    goal = Goal.from_json(goal_json, user_data=user_data)
                    goals.append(goal)
                    self.output("goal", goal, jsonify(goal_json))

                db.put(goals)

                # need to tell the userdata that it has goals
                user_data.has_current_goals = not all([g.completed for g in goals])
                user_data.put()