Esempio n. 1
0
class ExercisesCreatedHistogram(request_handler.RequestHandler):
    def get(self):
        past_days = self.request_int('past_days', 7)
        today_dt = dt.datetime.combine(dt.date.today(), dt.time())
        earliest_dt = today_dt - dt.timedelta(days=past_days)

        self.response.out.write(
            self.get_histogram_spline_for_highcharts(earliest_dt))

    @layer_cache.cache_with_key_fxn(lambda self, date: "%s|%s" %
                                    (Setting.cached_exercises_date(), date),
                                    expiration=CACHE_EXPIRATION_SECS,
                                    layer=layer_cache.Layers.Memcache)
    def get_histogram_spline_for_highcharts(self, earliest_dt=dt.datetime.min):
        histogram = {}
        for ex in Exercise.get_all_use_cache():
            if ex.creation_date:
                creation_day = dt.datetime.combine(ex.creation_date, dt.time())
                timestamp = to_unix_secs(creation_day) * 1000
                histogram[timestamp] = histogram.get(timestamp, 0) + 1

        total_exercises = {}
        prev_value = 0
        for day, value in sorted(histogram.items()):
            prev_value = total_exercises[day] = prev_value + value

        # Only retain recent dates
        earliest_unix = to_unix_secs(earliest_dt) * 1000
        histogram = [[k, v] for k, v in histogram.items()
                     if k >= earliest_unix]
        total_exercises = [[k, v] for k, v in total_exercises.items()
                           if k >= earliest_unix]

        context = {
            'series': [{
                'name': 'Histogram (created per day)',
                'type': 'column',
                'data_values': json.dumps(histogram),
                'axis': 0,
            }, {
                'name': 'Total exercises',
                'type': 'spline',
                'data_values': json.dumps(total_exercises),
                'axis': 1,
            }],
            # Let highcharts determine the scales for now.
            'axes': [
                {
                    'max': 'null'
                },
                {
                    'max': 'null'
                },
            ],
        }

        return self.render_jinja2_template_to_string(
            'exercisestats/highcharts_exercises_created_histogram.json',
            context)
Esempio n. 2
0
class ExerciseNumberTrivia(request_handler.RequestHandler):
    def get(self):
        number = self.request_int('num', len(Exercise.get_all_use_cache()))
        self.render_json(self.number_facts_for_geckboard_text(number))

    @staticmethod
    @layer_cache.cache_with_key_fxn(lambda number: "%s|%s" %
                                    (Setting.cached_exercises_date(), number),
                                    expiration=CACHE_EXPIRATION_SECS,
                                    layer=layer_cache.Layers.Memcache)
    def number_facts_for_geckboard_text(number):
        import exercisestats.number_trivia as number_trivia

        math_fact = number_trivia.math_facts.get(
            number,
            'This number is interesting. Why? Suppose there exists uninteresting '
            'natural numbers. Then the smallest in that set would be '
            'interesting by virtue of being the first: a contradiction. '
            'Thus all natural numbers are interesting.')
        year_fact = number_trivia.year_facts.get(
            number, 'nothing interesting happened')

        misc_fact_keys = sorted(number_trivia.misc_facts.keys())
        first_available_num = misc_fact_keys[
            bisect.bisect_left(misc_fact_keys, number) - 1]
        greater_than_fact = number_trivia.misc_facts[first_available_num]

        text1 = 'We now have more exercises than %s (%s)!' % (
            cgi.escape(greater_than_fact), str(first_available_num))
        text2 = math_fact
        text3 = "In year %d, %s" % (number, cgi.escape(year_fact))

        return {
            'item': [
                {
                    'text': text1
                },
                {
                    'text': text2
                },
                {
                    'text': text3
                },
            ]
        }
Esempio n. 3
0
class ExercisesLastAuthorCounter(request_handler.RequestHandler):
    def get(self):
        self.render_json(self.exercise_counter_for_geckoboard_rag())

    @staticmethod
    @layer_cache.cache_with_key_fxn(
        lambda: "last_author_%s" % Setting.cached_exercises_date(),
        expiration=CACHE_EXPIRATION_SECS,
        layer=layer_cache.Layers.Memcache)
    def exercise_counter_for_geckoboard_rag():
        exercises = Exercise.get_all_use_cache()
        exercises.sort(key=lambda ex: ex.creation_date, reverse=True)

        last_exercise = exercises[0]
        num_exercises = len(exercises)
        last_exercise_author = last_exercise.author.nickname(
        ) if last_exercise.author else 'random person'

        text = "Thanks %s for %s!" % (last_exercise_author,
                                      last_exercise.display_name)

        return {
            'item': [
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': num_exercises,
                    'text': text,
                },
            ]
        }
Esempio n. 4
0
 def get_cache_key(self, exids, dates, title='', showLegend=False):
     return "%s|%s|%s|%s|%s" % (Setting.cached_exercises_date(),
         sorted(exids), sorted(dates), title, showLegend)
Esempio n. 5
0
import layer_cache
from models import Video, Url, Topic, Setting, TopicVersion, Exercise


@layer_cache.cache_with_key_fxn(
    lambda: "exercise_title_dicts_%s" % Setting.cached_exercises_date())
def exercise_title_dicts():
    return [{
        "title": exercise.display_name,
        "key": str(exercise.key()),
        "relative_url": exercise.relative_url,
        "id": exercise.name,
    } for exercise in Exercise.get_all_use_cache() if not exercise.summative]


@layer_cache.cache_with_key_fxn(
    lambda version_number=None: "video_title_dicts_%s" %
    (version_number or Setting.topic_tree_version()))
def video_title_dicts(version_number=None):
    if version_number:
        version = TopicVersion.get_by_number(version_number)
    else:
        version = None

    return [{
        "title": video.title,
        "key": str(video.key()),
        "relative_url": "/video/%s" % video.readable_id,
        "id": video.readable_id
    } for video in Video.get_all_live(version=version) if video is not None]
Esempio n. 6
0
class ExerciseStatsMapGraph(request_handler.RequestHandler):
    # TODO: Just move this logic into get and make get_use_cache take a day parameter.
    def get_request_params(self):
        default_day = dt.date.today() - dt.timedelta(days=2)
        interested_day = self.request_date('date', "%Y/%m/%d", default_day)

        return {'interested_day': interested_day}

    def get(self):
        self.response.out.write(self.get_use_cache())

    @layer_cache.cache_with_key_fxn(
        lambda self: "%s|%s" %
        (Setting.cached_exercises_date(), self.get_request_params()),
        expiration=CACHE_EXPIRATION_SECS,
        layer=layer_cache.Layers.Memcache)
    def get_use_cache(self):
        params = self.get_request_params()

        # Get the maximum so we know how the data label circles should be scaled
        most_new_users = 1
        ex_stat_dict = {}
        for ex in Exercise.get_all_use_cache():
            stat = ExerciseStatistic.get_by_date(ex.name,
                                                 params['interested_day'])
            ex_stat_dict[ex.name] = stat
            if stat:
                most_new_users = max(most_new_users, stat.num_new_users())

        data_points = []
        min_y, max_y = -1, 1
        for ex in Exercise.get_all_use_cache():
            stat = ex_stat_dict[ex.name]

            y, x = -int(ex.h_position), int(ex.v_position)

            min_y, max_y = min(y, min_y), max(y, max_y)

            # Set the area of the circle proportional to the data value
            radius = 1
            if stat:
                radius = math.sqrt(
                    float(stat.num_new_users()) /
                    most_new_users) * MAX_POINT_RADIUS

            point = {
                'x': x,
                'y': y,
                'name': ex.display_name,
                'marker': {
                    'radius': max(radius, 1)
                },
            }
            data_points.append(point)

        context = {
            'title': 'Exercises map - First attempts',
            'series': {
                'name': 'First attempts',
                'data_values': json.dumps(data_points),
            },
            'minYValue': min_y - 1,
            'maxYValue': max_y + 1,
        }

        return self.render_jinja2_template_to_string(
            'exercisestats/highcharts_scatter_map.json', context)
Esempio n. 7
0
 def get_cache_key(self, exids, dates, title='', showLegend=False):
     return "%s|%s|%s|%s|%s" % (Setting.cached_exercises_date(),
                                sorted(exids), sorted(dates), title,
                                showLegend)
Esempio n. 8
0
import layer_cache
from models import Video, Url, Topic, Setting, TopicVersion, Exercise

@layer_cache.cache_with_key_fxn(lambda:
    "exercise_title_dicts_%s" % Setting.cached_exercises_date())
def exercise_title_dicts():
    return [{
        "title": exercise.display_name,
        "key": str(exercise.key()),
        "relative_url": exercise.relative_url,
        "id": exercise.name,
    } for exercise in Exercise.get_all_use_cache() if not exercise.summative]

@layer_cache.cache_with_key_fxn(lambda version_number=None: 
    "video_title_dicts_%s" % (
    version_number or Setting.topic_tree_version()))
def video_title_dicts(version_number=None):
    if version_number:
        version = TopicVersion.get_by_number(version_number)
    else:
        version = None

    return [{
        "title": video.title,
        "key": str(video.key()),
        "relative_url": "/video/%s" % video.readable_id,
        "id": video.readable_id
    } for video in Video.get_all_live(version=version) if video is not None]

@layer_cache.cache_with_key_fxn(lambda version_number=None: 
    "url_title_dicts_%s" % (