コード例 #1
0
ファイル: views.py プロジェクト: matheus-arruda/proso-apps
def feedback(request):
    """
    Send feedback to the authors of the system.

    GET parameters:
        html
            turn on the HTML version of the API

    POST parameters (JSON):
        text:
            the main feedback content
        email (optional):
            user's e-mail
        username (optional):
            user's name
    """
    if request.method == 'GET':
        return render(request, 'feedback_feedback.html', {}, help_text=feedback.__doc__)
    if request.method == 'POST':
        feedback_data = json_body(request.body.decode("utf-8"))
        feedback_data['user_agent'] = Session.objects.get_current_session().http_user_agent.content
        if not feedback_data.get('username'):
            feedback_data['username'] = request.user.username
        if not feedback_data.get('email'):
            feedback_data['email'] = request.user.email
        comment = Comment.objects.create(
            username=feedback_data['username'],
            email=feedback_data['email'],
            text=feedback_data['text'])
        if get_config('proso_feedback', 'send_emails', default=True):
            feedback_domain = get_config('proso_feedback', 'domain', required=True)
            feedback_to = get_config('proso_feedback', 'to', required=True)
            if is_likely_worthless(feedback_data):
                mail_from = 'spam@' + feedback_domain
            else:
                mail_from = 'feedback@' + feedback_domain
            text_content = render_to_string("emails/feedback.plain.txt", {
                "feedback": feedback_data,
                "user": request.user,
            })
            html_content = render_to_string("emails/feedback.html", {
                "feedback": feedback_data,
                "user": request.user,
            })
            subject = feedback_domain + ' feedback ' + str(comment.id)
            mail = EmailMultiAlternatives(
                subject,
                text_content,
                mail_from,
                feedback_to,
            )
            mail.attach_alternative(html_content, "text/html")
            mail.send()
            LOGGER.debug("email sent %s\n", text_content)
        return HttpResponse('ok', status=201)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
コード例 #2
0
ファイル: cache.py プロジェクト: thanhtd91/proso-apps
 def __init__(self):
     name = 'locmemcache@%i' % hash(currentThread())
     params = {
         'max_entries':
         get_config('proso_common', 'request_cache.max_entries', 100000)
     }
     super(RequestCache, self).__init__(name, params)
コード例 #3
0
 def load_environment_info(self, initial, config_name):
     set_default_config_name(config_name)
     config = Config.objects.from_content(get_config('proso_models', 'predictive_model', default={}))
     if initial:
         if EnvironmentInfo.objects.filter(status=EnvironmentInfo.STATUS_LOADING).count() > 0:
             raise CommandError("There is already one currently loading environment.")
         last_revisions = EnvironmentInfo.objects.filter(config=config).order_by('-revision')[:1]
         if last_revisions:
             new_revision = last_revisions[0].id + 1
         else:
             new_revision = 0
         return EnvironmentInfo.objects.create(config=config, revision=new_revision)
     else:
         return EnvironmentInfo.objects.get(config=config, status=EnvironmentInfo.STATUS_LOADING)
コード例 #4
0
ファイル: models.py プロジェクト: matheus-arruda/proso-apps
def get_item_selector():
    cached = get_from_request_permenent_cache(ITEM_SELECTOR_CACHE_KEY)
    if cached is None:
        item_selector = instantiate_from_config(
            'proso_models', 'item_selector',
            default_class='proso.models.item_selection.ScoreItemSelection',
            pass_parameters=[get_predictive_model()]
        )
        nth = get_config('proso_models', 'random_test.nth')
        if nth is not None and nth > 0:
            item_selector = TestWrapperItemSelection(item_selector, nth)
        cached = item_selector
        set_to_request_permanent_cache(ITEM_SELECTOR_CACHE_KEY, cached)
    return cached
コード例 #5
0
ファイル: views.py プロジェクト: SykoraErik/geography
def home(request, hack=None):
    JS_FILES = (
        "dist/js/bower-libs.min.js",
        "dist/js/proso-apps-all.js",
        "dist/js/geography.min.js",
        "dist/js/geography.html.js",
    )
    CSS_FILES = (
        "dist/css/bower-libs.css",
        "dist/css/app.css",
        "dist/css/map.css"
    )
    if not hasattr(request.user, "userprofile") or request.user.userprofile is None:
        environment = get_environment()
        user = json.dumps({
            'user': {},
            'number_of_answers': environment.number_of_answers(user=request.user.id) if request.user.id is not None else 0,
            'number_of_correct_answers': environment.number_of_correct_answers(user=request.user.id) if request.user.id is not None else 0,
        })
        email = ''
    else:
        if get_config('proso_user', 'google.openid.migration', default=True) and not is_user_id_overridden(request):
            migrated_user = migrate_google_openid_user(request.user)
            if migrated_user is not None:
                auth.logout(request)
                migrated_user.backend = 'social_auth.backends.google.GoogleOAuth2Backend'
                auth.login(request, migrated_user)
        user = json.dumps(request.user.userprofile.to_json(stats=True))
        email = request.user.email
    c = {
        'title': _(u'Slepé mapy') + ' - ' + _(u'inteligentní aplikace na procvičování zeměpisu'),
        'map': get_map_from_url(hack),
        'is_production': settings.ON_PRODUCTION,
        'css_files': CSS_FILES,
        'js_files': JS_FILES,
        'continents': Category.objects.filter(
            lang=get_language(), type='continent').order_by('name'),
        'states': Category.objects.filter(
            lang=get_language(), type='state').order_by('name'),
        'user_json': user,
        'email': email,
        'LANGUAGE_CODE': get_language(),
        'LANGUAGES': settings.LANGUAGES,
        'is_homepage': hack is None,
        'config_json': json.dumps(get_global_config()),
    }
    return render_to_response('home.html', c)
コード例 #6
0
def home(request, hack=None):
    if not hasattr(request.user, "userprofile") or request.user.userprofile is None:
        environment = get_environment()
        user = json.dumps({
            'user': {},
            'number_of_answers': environment.number_of_answers(user=request.user.id) if request.user.id is not None else 0,
            'number_of_correct_answers': environment.number_of_correct_answers(user=request.user.id) if request.user.id is not None else 0,
        })
        email = ''
    else:
        if hack is None:
            return redirect('/overview/')
        if get_config('proso_user', 'google.openid.migration', default=True) and not is_user_id_overridden(request):
            migrated_user = migrate_google_openid_user(request.user)
            if migrated_user is not None:
                auth.logout(request)
                migrated_user.backend = 'social_auth.backends.google.GoogleOAuth2Backend'
                auth.login(request, migrated_user)
        user = json.dumps(request.user.userprofile.to_json(stats=True))
        email = request.user.email
    c = {
        'title': _(u'Slepé mapy') + ' - ' + _(u'inteligentní aplikace na procvičování zeměpisu'),
        'map': get_map_from_url(hack),
        'is_production': settings.ON_PRODUCTION,
        'css_files': CSS_FILES,
        'map_files': get_map_files(),
        'js_files': JS_FILES,
        'continents': Category.objects.filter(
            lang=get_language(), type='continent').order_by('name'),
        'states': Category.objects.filter(
            lang=get_language(), type='state').order_by('name'),
        'regions': Category.objects.filter(
            lang=get_language(), type='region').order_by('name'),
        'user_json': user,
        'email': email,
        'LANGUAGE_CODE': get_language(),
        'LANGUAGES': settings.LANGUAGES,
        'LANGUAGE_DOMAINS': settings.LANGUAGE_DOMAINS if hasattr(
            settings, 'LANGUAGE_DOMAINS') else {},
        'is_homepage': hack is None,
        'hack': hack or '',
        'config_json': json.dumps(get_global_config()),
        'DOMAIN': request.build_absolute_uri('/')[:-1],
        'screenshot_files': get_screenshot_files(request, hack),
    }
    return render_to_response('home.html', c)
コード例 #7
0
 def confusing_factor_more_items(self, item, items, user=None):
     cached_all = {}
     confusing_factor_cache = cache.get('database_environment__confusing_factor', {})
     for item_secondary in items:
         _items = self._sorted([item, item_secondary])
         cache_key = '{}_{}_{}'.format(_items[0], _items[1], user)
         cached_item = confusing_factor_cache.get(cache_key)
         if cached_item:
             cached_all[item_secondary] = int(cached_item)
     to_find = [i for i in items if i not in list(cached_all.keys())]
     if len(cached_all) != 0:
         LOGGER.debug('cache hit for confusing factor, item {}, {} other items and user {}'.format(item, len(cached_all), user))
     if len(to_find) != 0:
         LOGGER.debug('cache miss for confusing factor, item {}, {} other items and user {}'.format(item, len(to_find), user))
         where, where_params = self._where({
             'item_answered_id': to_find,
             'item_asked_id': to_find,
         }, force_null=False, for_answers=True, conjuction=False)
         user_where, user_params = self._column_comparison('user_id', user, force_null=False)
         with closing(connection.cursor()) as cursor:
             cursor.execute(
                 '''
                 SELECT
                     item_asked_id,
                     item_answered_id,
                     COUNT(id) AS confusing_factor
                 FROM
                     proso_models_answer
                 WHERE guess = 0 AND (item_asked_id = %s OR item_asked_id = %s) AND
                 ''' + user_where + ' AND (' + where + ') GROUP BY item_asked_id, item_answered_id', [item, item] + user_params + where_params)
             found = {}
             for item_asked, item_answered, count in cursor:
                 if item_asked == item:
                     found[item_answered] = found.get(item_answered, 0) + count
                 else:
                     found[item_asked] = found.get(item_asked, 0) + count
             for i in to_find:
                 found[i] = found.get(i, 0)
             cache_expiration = get_config('proso_models', 'confusing_factor.cache_expiration', default=24 * 60 * 60)
             for item_secondary, count in found.items():
                 _items = self._sorted([item, item_secondary])
                 cache_key = '{}_{}_{}'.format(_items[0], _items[1], user)
                 confusing_factor_cache[cache_key] = count
                 cached_all[item_secondary] = count
             cache.set('database_environment__confusing_factor', confusing_factor_cache, cache_expiration)
     return [cached_all[i] for i in items]
コード例 #8
0
ファイル: environment.py プロジェクト: waffle-iron/proso-apps
 def confusing_factor_more_items(self, item, items, user=None):
     cached_all = {}
     confusing_factor_cache = cache.get('database_environment__confusing_factor', {})
     for item_secondary in items:
         _items = self._sorted([item, item_secondary])
         cache_key = '{}_{}_{}'.format(_items[0], _items[1], user)
         cached_item = confusing_factor_cache.get(cache_key)
         if cached_item:
             cached_all[item_secondary] = int(cached_item)
     to_find = [i for i in items if i not in list(cached_all.keys())]
     if len(cached_all) != 0:
         LOGGER.debug('cache hit for confusing factor, item {}, {} other items and user {}'.format(item, len(cached_all), user))
     if len(to_find) != 0:
         LOGGER.debug('cache miss for confusing factor, item {}, {} other items and user {}'.format(item, len(to_find), user))
         where, where_params = self._where({
             'item_answered_id': to_find,
             'item_asked_id': to_find,
         }, force_null=False, for_answers=True, conjuction=False)
         user_where, user_params = self._column_comparison('user_id', user, force_null=False)
         with closing(connection.cursor()) as cursor:
             cursor.execute(
                 '''
                 SELECT
                     item_asked_id,
                     item_answered_id,
                     COUNT(id) AS confusing_factor
                 FROM
                     proso_models_answer
                 WHERE guess = 0 AND (item_asked_id = %s OR item_asked_id = %s) AND
                 ''' + user_where + ' AND (' + where + ') GROUP BY item_asked_id, item_answered_id', [item, item] + user_params + where_params)
             found = {}
             for item_asked, item_answered, count in cursor:
                 if item_asked == item:
                     found[item_answered] = found.get(item_answered, 0) + count
                 else:
                     found[item_asked] = found.get(item_asked, 0) + count
             for i in to_find:
                 found[i] = found.get(i, 0)
             cache_expiration = get_config('proso_models', 'confusing_factor.cache_expiration', default=24 * 60 * 60)
             for item_secondary, count in found.items():
                 _items = self._sorted([item, item_secondary])
                 cache_key = '{}_{}_{}'.format(_items[0], _items[1], user)
                 confusing_factor_cache[cache_key] = count
                 cached_all[item_secondary] = count
             cache.set('database_environment__confusing_factor', confusing_factor_cache, cache_expiration)
     return [cached_all[i] for i in items]
コード例 #9
0
ファイル: models.py プロジェクト: matheus-arruda/proso-apps
def get_active_environment_info():
    if is_cache_prepared():
        cached = get_request_cache().get(ENVIRONMENT_INFO_CACHE_KEY)
        if cached is not None:
            return cached
    cached = cache.get(ENVIRONMENT_INFO_CACHE_KEY)
    if cached is None:
        try:
            active_envinfo = EnvironmentInfo.objects.select_related('config').get(status=EnvironmentInfo.STATUS_ACTIVE)
        except EnvironmentInfo.DoesNotExist:
            config = Config.objects.from_content(get_config('proso_models', 'predictive_model', default={}))
            active_envinfo, _ = EnvironmentInfo.objects.get_or_create(config=config, status=EnvironmentInfo.STATUS_ACTIVE, revision=0)
        cached = active_envinfo.to_json()
        if is_cache_prepared():
            get_request_cache().set(ENVIRONMENT_INFO_CACHE_KEY, cached)
        if EnvironmentInfo.objects.filter(status=EnvironmentInfo.STATUS_LOADING).count() == 0:
            cache.set(ENVIRONMENT_INFO_CACHE_KEY, cached, ENVIRONMENT_INFO_CACHE_EXPIRATION)
    return cached
コード例 #10
0
 def load_environment_info(self, initial, config_name):
     set_default_config_name(config_name)
     config = Config.objects.from_content(
         get_config('proso_models', 'predictive_model', default={}))
     if initial:
         if EnvironmentInfo.objects.filter(
                 status=EnvironmentInfo.STATUS_LOADING).count() > 0:
             raise CommandError(
                 "There is already one currently loading environment.")
         last_revisions = EnvironmentInfo.objects.filter(
             config=config).order_by('-revision')[:1]
         if last_revisions:
             new_revision = last_revisions[0].id + 1
         else:
             new_revision = 0
         return EnvironmentInfo.objects.create(config=config,
                                               revision=new_revision)
     else:
         return EnvironmentInfo.objects.get(
             config=config, status=EnvironmentInfo.STATUS_LOADING)
コード例 #11
0
ファイル: views.py プロジェクト: MatheusArrudaLab/proso-apps
def profile(request, status=200):
    """
    Get the user's profile. If the user has no assigned profile, the HTTP 404
    is returned. Make a POST request to modify the user's profile.

    GET parameters:
        html
            turn on the HTML version of the API
        username:
            username of user (only for users with public profile)
        stats:
            attache addition user statistics

    POST parameters (JSON):
        send_emails:
            switcher turning on sending e-mails to user
        public:
            swicher making the user's profile publicly available
        user:
            password:
                user's password
            password_check:
                user's password again to check it
            first_name (optional):
                user's first name
            last_name (optional):
                user's last name
    """
    if request.method == 'GET':
        if request.GET.get("username", False):
            try:
                user_profile = User.objects.get(username=request.GET.get("username"),
                                                userprofile__public=True).userprofile
            except ObjectDoesNotExist:
                raise Http404("user not found or have not public profile")
        else:
            user_id = get_user_id(request)
            if get_config('proso_user', 'google.openid.migration', default=True) and not is_user_id_overridden(request):
                migrated_user = migrate_google_openid_user(request.user)
                if migrated_user is not None:
                    auth.logout(request)
                    migrated_user.backend = 'social.backends.google.GoogleOAuth2'
                    auth.login(request, migrated_user)
            user_profile = get_object_or_404(UserProfile, user_id=user_id)
        return render_json(
            request, user_profile, status=status,
            template='user_profile.html', help_text=profile.__doc__)
    elif request.method == 'POST':
        with transaction.atomic():
            to_save = json_body(request.body.decode("utf-8"))
            user_id = get_user_id(request)
            user_profile = get_object_or_404(UserProfile, user_id=user_id)
            user = to_save.get('user', None)
            if 'send_emails' in to_save:
                user_profile.send_emails = bool(to_save['send_emails'])
            if 'public' in to_save:
                user_profile.public = bool(to_save['public'])
            if user:
                error = _save_user(request, user, new=False)
                if error:
                    return render_json(request, error, template='user_json.html', status=400)
            if 'properties' in to_save:
                user_profile.save_properties(to_save['properties'])
            user_profile.save()
        request.method = "GET"
        return profile(request, status=202)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
コード例 #12
0
ファイル: models.py プロジェクト: matheus-arruda/proso-apps
def get_mastery_trashold():
    return get_config("proso_models", "mastery_threshold", default=0.9)
コード例 #13
0
ファイル: cache.py プロジェクト: adaptive-learning/proso-apps
 def __init__(self):
     name = 'locmemcache@%i' % hash(currentThread())
     params = {'max_entries': get_config('proso_common', 'request_cache.max_entries', 100000)}
     super(RequestCache, self).__init__(name, params)
コード例 #14
0
 def test_get_config(self):
     self.assertEqual(get_config('proso_tests', 'a.b.c'), 'blah')
     self.assertEqual(get_config('proso_tests', 'unknown', default='is here'), 'is here')
     with self.assertRaises(Exception):
         get_config('proso_tests', 'unknown', require=True)
コード例 #15
0
 def test_config_default_name(self):
     set_default_config_name('super')
     self.assertEqual(get_default_config_name(), 'super')
     self.assertIsNone(get_config('proso_tests', 'a.b.c'))
コード例 #16
0
def profile(request, status=200):
    """
    Get the user's profile. If the user has no assigned profile, the HTTP 404
    is returned. Make a POST request to modify the user's profile.

    GET parameters:
        html
            turn on the HTML version of the API
        username:
            username of user (only for users with public profile)
        stats:
            attache addition user statistics

    POST parameters (JSON):
        send_emails:
            switcher turning on sending e-mails to user
        public:
            swicher making the user's profile publicly available
        user:
            password:
                user's password
            password_check:
                user's password again to check it
            first_name (optional):
                user's first name
            last_name (optional):
                user's last name
    """
    if request.method == 'GET':
        if request.GET.get("username", False):
            try:
                user_profile = User.objects.get(
                    username=request.GET.get("username"),
                    userprofile__public=True).userprofile
            except ObjectDoesNotExist:
                raise Http404("user not found or have not public profile")
        else:
            user_id = get_user_id(request)
            if get_config('proso_user',
                          'google.openid.migration',
                          default=True) and not is_user_id_overridden(request):
                migrated_user = migrate_google_openid_user(request.user)
                if migrated_user is not None:
                    auth.logout(request)
                    migrated_user.backend = 'social.backends.google.GoogleOAuth2'
                    auth.login(request, migrated_user)
            user_profile = get_object_or_404(UserProfile, user_id=user_id)
        return render_json(request,
                           user_profile,
                           status=status,
                           template='user_profile.html',
                           help_text=profile.__doc__)
    elif request.method == 'POST':
        with transaction.atomic():
            to_save = json_body(request.body.decode("utf-8"))
            user_id = get_user_id(request)
            user_profile = get_object_or_404(UserProfile, user_id=user_id)
            user = to_save.get('user', None)
            if 'send_emails' in to_save:
                user_profile.send_emails = bool(to_save['send_emails'])
            if 'public' in to_save:
                user_profile.public = bool(to_save['public'])
            if user:
                error = _save_user(request, user, new=False)
                if error:
                    return render_json(request,
                                       error,
                                       template='user_json.html',
                                       status=400)
            if 'properties' in to_save:
                user_profile.save_properties(to_save['properties'])
            user_profile.save()
        request.method = "GET"
        return profile(request, status=202)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(
            request.method))
コード例 #17
0
 def test_get_config(self):
     self.assertEqual(get_config('proso_tests', 'a.b.c'), 'blah')
     self.assertEqual(
         get_config('proso_tests', 'unknown', default='is here'), 'is here')
     with self.assertRaises(Exception):
         get_config('proso_tests', 'unknown', require=True)
コード例 #18
0
 def test_config_default_name(self):
     set_default_config_name('super')
     self.assertEqual(get_default_config_name(), 'super')
     self.assertIsNone(get_config('proso_tests', 'a.b.c'))