Beispiel #1
0
def read(request, key):
    if 'user' in request.GET:
        user = get_user_id(request)
    else:
        user = None
    item = int(request.GET['item']) if 'item' in request.GET else None
    item_secondary = int(request.GET['item_secondary']
                         ) if 'item_secondary' in request.GET else None
    time = get_time(request)
    environment = get_environment()
    if is_time_overridden(request):
        environment.shift_time(time)
    value = environment.read(key,
                             user=user,
                             item=item,
                             item_secondary=item_secondary)
    if value is None:
        return render_json(request,
                           {'error': 'value with key "%s" not found' % key},
                           template='models_json.html',
                           status=404)
    else:
        return render_json(request, {
            'object_type': 'value',
            'key': key,
            'item_primary_id': item,
            'item_secondary_id': item_secondary,
            'user_id': user,
            'value': value
        },
                           template='models_json.html')
Beispiel #2
0
def read(request, key):
    if 'user' in request.GET:
        user = get_user_id(request)
    else:
        user = None
    item = int(request.GET['item']) if 'item' in request.GET else None
    item_secondary = int(request.GET['item_secondary']) if 'item_secondary' in request.GET else None
    time = get_time(request)
    environment = get_environment()
    if is_time_overridden(request):
        environment.shift_time(time)
    value = environment.read(key, user=user, item=item, item_secondary=item_secondary)
    if value is None:
        return render_json(
            request,
            {'error': 'value with key "%s" not found' % key},
            template='models_json.html', status=404)
    else:
        return render_json(
            request,
            {
                'object_type': 'value',
                'key': key,
                'item_primary_id': item,
                'item_secondary_id': item_secondary,
                'user_id': user,
                'value': value
            },
            template='models_json.html'
        )
Beispiel #3
0
def session(request):
    """
    Get the information about the current session or modify the current session.

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

    POST parameters:
      locale:
        client's locale
      time_zone:
        client's time zone
      display_width:
        width of the client's display
      display_height
        height of the client's display
    """

    if request.user.id is None:  # Google Bot
        return render_json(
            request, {
                'error': _('There is no user available to create a session.'),
                'error_type': 'user_undefined'
            },
            status=400,
            template='user_json.html')

    if request.method == 'GET':
        return render_json(request,
                           Session.objects.get_current_session(),
                           template='user_session.html',
                           help_text=session.__doc__)
    elif request.method == 'POST':
        current_session = Session.objects.get_current_session()
        if current_session is None:
            return HttpResponseBadRequest(
                "there is no current session to modify")
        data = json_body(request.body.decode("utf-8"))
        locale = data.get('locale', None)
        time_zone = data.get('time_zone', None)
        display_width = data.get('display_width', None)
        display_height = data.get('display_height', None)
        if locale:
            current_session.locale = locale
        if time_zone:
            current_session.time_zone = TimeZone.objects.from_content(
                time_zone)
        if display_width:
            current_session.display_width = display_width
        if display_height:
            current_session.display_height = display_height
        current_session.save()
        return HttpResponse('ok', status=202)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(
            request.method))
Beispiel #4
0
def login_student(request):
    """
    Log in student

    POST parameters (JSON):
        student:
            profile id of the student
    """
    if not get_config('proso_user', 'allow_login_students', default=False):
        return render_json(request, {
            'error': _('Log in as student is not allowed.'),
            'error_type': 'login_student_not_allowed'
        },
                           template='class_create_student.html',
                           help_text=login_student.__doc__,
                           status=403)

    if request.method == 'GET':
        return render(request,
                      'class_login_student.html', {},
                      help_text=login_student.__doc__)
    elif request.method == 'POST':
        if not request.user.is_authenticated() or not hasattr(
                request.user, "userprofile"):
            return render_json(request, {
                'error': _('User is not logged in.'),
                'error_type': 'user_unauthorized'
            },
                               template='class_create_student.html',
                               status=401)
        data = json_body(request.body.decode("utf-8"))
        try:
            student = User.objects.get(
                userprofile=data.get('student'),
                userprofile__classes__owner=request.user.userprofile)
        except User.DoesNotExist:
            return render_json(request, {
                'error': _('Student not found'),
                'error_type': 'student_not_found'
            },
                               template='class_login_student.html',
                               status=401)
        if not student.is_active:
            return render_json(
                request, {
                    'error': _('The account has not been activated.'),
                    'error_type': 'account_not_activated'
                },
                template='class_login_student.html',
                status=401)
        student.backend = 'django.contrib.auth.backends.ModelBackend'
        login(request, student)
        request.method = "GET"
        return profile(request)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(
            request.method))
Beispiel #5
0
def to_practice(request):
    practice_filter = get_filter(request)
    item_ids = Item.objects.filter_all_reachable_leaves(practice_filter, get_language(request))
    if len(item_ids) == 0:
        return render_json(request, {
            'error': _('There is no item for the given filter to practice.'),
            'error_type': 'empty_practice'
        }, status=404, template='models_json.html')
    result = [Item.objects.item_id_to_json(item_id) for item_id in item_ids]
    return render_json(request, result, template='models_json.html', help_text=to_practice.__doc__)
def classes(request):
    """Get all classes of current user"""

    if not request.user.is_authenticated() or not hasattr(request.user, "userprofile"):
        return render_json(request, {
            'error': _('User is not logged in'),
            'error_type': 'user_unauthorized'
        }, template='user_json.html', status=401)
    clss = [c.to_json() for c in Class.objects.filter(owner=request.user.userprofile)]

    return render_json(request, clss, status=200, template='user_json.html', help_text=classes.__doc__)
Beispiel #7
0
def create_class(request):
    """Create new class

    POST parameters (JSON):
        name:
            Human readable name of class
        code (optional):
            unique code of class used for joining to class
    """

    if request.method == 'GET':
        return render(request,
                      'classes_create.html', {},
                      help_text=create_class.__doc__)

    if request.method == 'POST':
        if not request.user.is_authenticated() or not hasattr(
                request.user, "userprofile"):
            return render_json(request, {
                'error': _('User is not logged in.'),
                'error_type': 'user_unauthorized'
            },
                               template='classes_create.html',
                               status=401)

        data = json_body(request.body.decode("utf-8"))
        if 'code' in data and Class.objects.filter(code=data['code']).exists():
            return render_json(
                request, {
                    'error': _('A class with this code already exists.'),
                    'error_type': 'class_with_code_exists'
                },
                template='classes_create.html',
                status=400)

        if 'name' not in data or not data['name']:
            return render_json(request, {
                'error': _('Class name is missing.'),
                'error_type': 'missing_class_name'
            },
                               template='classes_create.html',
                               status=400)

        cls = Class(name=data['name'], owner=request.user.userprofile)
        if 'code' in data:
            cls.code = data['code']
        cls.save()
        return render_json(request,
                           cls.to_json(),
                           template='classes_create.html',
                           status=201)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(
            request.method))
Beispiel #8
0
def answer_question(request):
    if request.method == 'GET':
        return render(request, 'user_answer.html', {}, help_text=answer_question.__doc__)
    elif request.method == 'POST':
        with transaction.atomic():
            user_id = get_user_id(request)
            to_save = json_body(request.body.decode("utf-8"))
            for answer in to_save['answers']:
                question = get_object_or_404(UserQuestion, pk=answer['question'])
                if 'open_answer' in answer and 'closed_answer' in answer:
                    return render_json(request, {
                        'error': _('The answer can not contain both open and closed part'),
                        'error_type': 'answer_closed_open_both'
                    }, template='user_json.html', status=400)
                if 'open_answer' not in answer and 'closed_answer' not in answer:
                    return render_json(request, {
                        'error': _('The answer has to contain either open, or closed part.'),
                        'error_type': 'answer_closed_open_missing'
                    }, template='user_json.html', status=400)
                if question.answer_type == UserQuestion.TYPE_CLOSED and 'closed_answer' not in answer:
                    return render_json(request, {
                        'error': _('The answer has to contain closed part.'),
                        'error_type': 'answer_closed_missing'
                    }, template='user_json.html', status=400)
                if question.answer_type == UserQuestion.TYPE_OPEN and 'open_answer' not in answer:
                    return render_json(request, {
                        'error': _('The answer has to contain open part.'),
                        'error_type': 'answer_open_missing'
                    }, template='user_json.html', status=400)

                user_answer = None
                if not question.repeat:
                    user_answer = UserQuestionAnswer.objects.filter(user_id=user_id, question__identifier=question.identifier).first()
                    status = 202
                if user_answer is None:
                    status = 201
                    user_answer = UserQuestionAnswer(user_id=user_id, question=question)
                if 'closed_answer' in answer:
                    user_answer.closed_answer = get_object_or_404(UserQuestionPossibleAnswer, pk=answer['closed_answer'])
                    if user_answer.closed_answer.question_id != question.id:
                        return render_json(request, {
                            'error': _('The given question and question for the given closed answer does not match.'),
                            'error_type': 'closed_answer_no_match'
                        }, template='user_json.html', status=400)
                else:
                    user_answer.closed_answer = None
                user_answer.open_answer = answer['open_answer'] if 'open_answer' in answer else None
                user_answer.save()
            return HttpResponse('ok', status=status)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #9
0
def session(request):
    """
    Get the information about the current session or modify the current session.

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

    POST parameters:
      locale:
        client's locale
      time_zone:
        client's time zone
      display_width:
        width of the client's display
      display_height
        height of the client's display
    """

    if request.user.id is None:  # Google Bot
        return render_json(request, {
            'error': _('There is no user available to create a session.'),
            'error_type': 'user_undefined'
        }, status=400, template='user_json.html')

    if request.method == 'GET':
        return render_json(
            request,
            Session.objects.get_current_session(),
            template='user_session.html', help_text=session.__doc__)
    elif request.method == 'POST':
        current_session = Session.objects.get_current_session()
        if current_session is None:
            return HttpResponseBadRequest("there is no current session to modify")
        data = json_body(request.body.decode("utf-8"))
        locale = data.get('locale', None)
        time_zone = data.get('time_zone', None)
        display_width = data.get('display_width', None)
        display_height = data.get('display_height', None)
        if locale:
            current_session.locale = locale
        if time_zone:
            current_session.time_zone = TimeZone.objects.from_content(time_zone)
        if display_width:
            current_session.display_width = display_width
        if display_height:
            current_session.display_height = display_height
        current_session.save()
        return HttpResponse('ok', status=202)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #10
0
def user_stats_bulk(request):
    """
    Get statistics for selected users and concepts

    since:
      time as timestamp - get stats changed since
    users:
      list of identifiers of users
    concepts (Optional):
      list of identifiers of concepts
    language:
      language of concepts
    """

    language = get_language(request)
    users = load_query_json(request.GET, "users")
    if request.user.is_staff:
        if not hasattr(request.user, 'userprofile') or User.objects.filter(
                pk__in=users, userprofile__classes__owner=request.user.
                userprofile).count() < len(users):
            return render_json(
                request, {
                    'error':
                    _('Some requested users are not in owned classes'),
                    'error_type': 'permission_denied'
                },
                template='concepts_json.html',
                status=401)
    since = None
    if 'since' in request.GET:
        since = datetime.datetime.fromtimestamp(int(request.GET['since']))
    concepts = None
    if "concepts" in request.GET:
        concepts = Concept.objects.filter(lang=language,
                                          active=True,
                                          identifier__in=load_query_json(
                                              request.GET, "concepts"))
    stats = UserStat.objects.get_user_stats(users,
                                            language,
                                            concepts=concepts,
                                            since=since)
    data = {"users": []}
    for user, s in stats.items():
        data["users"].append({
            "user_id": user,
            "concepts": s,
        })
    return render_json(request,
                       data,
                       template='concepts_json.html',
                       help_text=user_stats_bulk.__doc__)
Beispiel #11
0
def join_class(request):
    """Join a class

    POST parameters (JSON):
        code:
            code of the class
    """

    if request.method == 'GET':
        return render(request,
                      'classes_join.html', {},
                      help_text=join_class.__doc__)

    if request.method == 'POST':
        if not request.user.is_authenticated() or not hasattr(
                request.user, "userprofile"):
            return render_json(request, {
                'error': _('User is not logged in.'),
                'error_type': 'user_unauthorized'
            },
                               template='classes_join.html',
                               status=401)

        data = json_body(request.body.decode("utf-8"))

        if 'code' not in data or not data['code']:
            return render_json(request, {
                'error': _('Class code is missing.'),
                'error_type': 'missing_class_code'
            },
                               template='classes_join.html',
                               status=400)

        try:
            cls = Class.objects.get(code=data['code'])
        except Class.DoesNotExist:
            return render_json(request, {
                'error': _('Class with given code not found.'),
                'error_type': 'class_not_found',
            },
                               template='classes_join.html',
                               status=404)

        cls.members.add(request.user.userprofile)
        return render_json(request,
                           cls.to_json(),
                           template='classes_join.html',
                           status=200)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(
            request.method))
Beispiel #12
0
def answer_question(request):
    if request.method == 'GET':
        return render(request, 'user_answer.html', {}, help_text=answer_question.__doc__)
    elif request.method == 'POST':
        with transaction.atomic():
            user_id = get_user_id(request)
            to_save = json_body(request.body.decode("utf-8"))
            for answer in to_save['answers']:
                question = get_object_or_404(UserQuestion, pk=answer['question'])
                if 'open_answer' in answer and 'closed_answer' in answer:
                    return render_json(request, {
                        'error': _('The answer can not contain both open and closed part'),
                        'error_type': 'answer_closed_open_both'
                    }, template='user_json.html', status=400)
                if 'open_answer' not in answer and 'closed_answer' not in answer:
                    return render_json(request, {
                        'error': _('The answer has to contain either open, or closed part.'),
                        'error_type': 'answer_closed_open_missing'
                    }, template='user_json.html', status=400)
                if question.answer_type == UserQuestion.TYPE_CLOSED and 'closed_answer' not in answer:
                    return render_json(request, {
                        'error': _('The answer has to contain closed part.'),
                        'error_type': 'answer_closed_missing'
                    }, template='user_json.html', status=400)
                if question.answer_type == UserQuestion.TYPE_OPEN and 'open_answer' not in answer:
                    return render_json(request, {
                        'error': _('The answer has to contain open part.'),
                        'error_type': 'answer_open_missing'
                    }, template='user_json.html', status=400)

                user_answer = None
                if not question.repeat:
                    user_answer = UserQuestionAnswer.objects.filter(user_id=user_id, question__identifier=question.identifier).first()
                    status = 202
                if user_answer is None:
                    status = 201
                    user_answer = UserQuestionAnswer(user_id=user_id, question=question)
                if 'closed_answer' in answer:
                    user_answer.closed_answer = get_object_or_404(UserQuestionPossibleAnswer, pk=answer['closed_answer'])
                    if user_answer.closed_answer.question_id != question.id:
                        return render_json(request, {
                            'error': _('The given question and question for the given closed answer does not match.'),
                            'error_type': 'closed_answer_no_match'
                        }, template='user_json.html', status=400)
                else:
                    user_answer.closed_answer = None
                user_answer.open_answer = answer['open_answer'] if 'open_answer' in answer else None
                user_answer.save()
            return HttpResponse('ok', status=status)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #13
0
def signup(request):
    """
    Create a new user with the given credentials.

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

    POST parameters (JSON):
        username:
            user's name
        email:
            user's e-mail
        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':
        return render(request,
                      'user_signup.html', {},
                      help_text=signup.__doc__)
    elif request.method == 'POST':
        if request.user.is_authenticated() and hasattr(request.user,
                                                       "userprofile"):
            return render_json(request, {
                'error': _('User already logged in'),
                'error_type': 'username_logged'
            },
                               template='user_json.html',
                               status=400)
        credentials = json_body(request.body.decode("utf-8"))
        error = _save_user(request, credentials, new=True)
        if error is not None:
            return render_json(request,
                               error,
                               template='user_json.html',
                               status=400)
        else:
            auth.login(request, request.user)
            request.method = "GET"
            return profile(request, status=201)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(
            request.method))
Beispiel #14
0
def user_stats_api(request, provider):
    """
    Get statistics for selected Edookit users

    key:
      api key
    since:
      time as timestamp - get stats changed since
    """

    if 'key' not in request.GET or provider not in settings.USER_STATS_API_KEY \
            or request.GET['key'] != settings.USER_STATS_API_KEY[provider]:
        return HttpResponse('Unauthorized', status=401)
    since = None
    if 'since' in request.GET:
        since = datetime.datetime.fromtimestamp(int(request.GET['since']))

    social_users = list(UserSocialAuth.objects.filter(provider=provider).select_related('user'))
    user_map = {u.user.id: u for u in social_users}
    stats = UserStat.objects.get_user_stats([u.user for u in social_users], lang=None, since=since, recalculate=False)
    data = {"users": []}
    for user, s in stats.items():
        data["users"].append({
            "user_id": user_map[user].uid,
            "concepts": s,
        })
    return render_json(request, data, template='concepts_json.html', help_text=user_stats_bulk.__doc__)
Beispiel #15
0
def _csv_list(request):
    apps = defaultdict(dict)
    for app, app_data in get_tables_allowed_to_export().items():
        apps[app]['tables'] = list(map(lambda d: {'name': d[1], 'url': reverse('csv_table', kwargs={'filename': d[1]})}, app_data))
    for app, app_data in get_custom_exports().items():
        apps[app]['custom_exports'] = list(map(lambda name: {'name': name, 'url': reverse('csv_table', kwargs={'filename': name})}, app_data))
    return render_json(request, apps, template='common_json.html')
Beispiel #16
0
def learning_curve(request):
    '''
    Shows a learning curve based on the randomized testing.

    GET parameters:
      length:
        length of the learning curve
      context:
        JSON representing the practice context
      all_users:
        if present stop filtering users based on the minimal number of testing
        answers (=length)
    '''
    context = PracticeContext.objects.from_content(get_filter(request))
    length = int(request.GET.get('length', 10))
    if 'all_users' in request.GET:
        user_length = 1
    else:
        user_length = None
    return render_json(request,
                       models_learning_curve(length,
                                             context=context.id,
                                             user_length=user_length),
                       template='models_json.html',
                       help_text=learning_curve.__doc__)
Beispiel #17
0
def discount_code_view(request, code):
    return render_json(request,
                       get_object_or_404(
                           DiscountCode,
                           code=DiscountCode.objects.prepare_code(code),
                           active=True).to_json(),
                       template='subscription_json.html')
Beispiel #18
0
def user_stats_bulk(request):
    """
    Get statistics for selected users and concepts

    since:
      time as timestamp - get stats changed since
    users:
      list of identifiers of users
    concepts (Optional):
      list of identifiers of concepts
    language:
      language of concepts
    """

    language = get_language(request)
    users = load_query_json(request.GET, "users")
    since = None
    if 'since' in request.GET:
        since = datetime.datetime.fromtimestamp(int(request.GET['since']))
    concepts = None
    if "concepts" in request.GET:
        concepts = Concept.objects.filter(lang=language, active=True,
                                          identifier__in=load_query_json(request.GET, "concepts"))
    stats = UserStat.objects.get_user_stats(users, language, concepts=concepts, since=since)
    data = {"users": []}
    for user, s in stats.items():
        data["users"].append({
            "user_id": user,
            "concepts": s,
        })
    return render_json(request, data, template='concepts_json.html', help_text=user_stats_bulk.__doc__)
Beispiel #19
0
def answer(request):
    """
    Save the answer.

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

    BODY
    json in following format:
    {
        "answer": #answer,                          -- for one answer
        "answers": [#answer, #answer, #answer ...]  -- for multiple answers
    }

    answer = {
        "answer_class": str,            -- class of answer to save (e.g., flashcard_answer)
        "response_time": int,           -- response time in milliseconds
        "meta": "str"                   -- optional information
        "time_gap": int                 -- waiting time in frontend in seconds
        ...                             -- other fields depending on aswer type
                                          (see from_json method of Django model class)
    }
    """
    if request.method == 'GET':
        return render(request, 'models_answer.html', {}, help_text=answer.__doc__)
    elif request.method == 'POST':
        practice_filter = get_filter(request)
        practice_context = PracticeContext.objects.from_content(practice_filter)
        saved_answers = _save_answers(request, practice_context)
        return render_json(request, saved_answers, status=200, template='models_answer.html')
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #20
0
def audit(request, key):
    if 'user' in request.GET:
        user = get_user_id(request)
    else:
        user = None
    limit = 100
    if request.user.is_staff:
        limit = request.GET.get('limit', limit)
    item = int(request.GET['item']) if 'item' in request.GET else None
    item_secondary = int(request.GET['item_secondary']) if 'item_secondary' in request.GET else None
    time = get_time(request)
    environment = get_environment()
    if is_time_overridden(request):
        environment.shift_time(time)
    values = environment.audit(
        key, user=user, item=item, item_secondary=item_secondary, limit=limit)

    def _to_json_audit(audit):
        (time, value) = audit
        return {
            'object_type': 'value',
            'key': key,
            'item_primary_id': item,
            'item_secondary_id': item_secondary,
            'user_id': user,
            'value': value,
            'time': time.strftime('%Y-%m-%d %H:%M:%S')
        }
    return render_json(request, list(map(_to_json_audit, values)), template='models_json.html')
Beispiel #21
0
def custom_config(request):
    """
    Save user-specific configuration property.

    POST parameters (JSON keys):
        app_name: application name for which the configuration property is
            valid (e.g., proso_models)
        key: name of the property (e.g., predictive_model.class)
        value: value of the property (number, string, boolean, ...,
            e.g, proso.models.prediction.PriorCurrentPredictiveModel)
        condition_key (optional): name of the condition which is used to filter
            the property (e.g., practice_filter)
        condition_value (optional): value for the condition filtering the
            property (e.g., [["context/world"],["category/state"]])
    """
    if request.method == 'POST':
        config_dict = json_body(request.body.decode('utf-8'))
        CustomConfig.objects.try_create(
            config_dict['app_name'], config_dict['key'], config_dict['value'],
            request.user.id,
            config_dict.get('condition_key')
            if config_dict.get('condition_key') else None,
            urllib.parse.unquote(config_dict.get('condition_value'))
            if config_dict.get('condition_value') else None)
        return config(request)
    else:
        return render_json(request, {},
                           template='common_custom_config.html',
                           help_text=custom_config.__doc__)
Beispiel #22
0
def user_stats(request):
    """
    JSON of user stats of the user

    GET parameters:
      html (bool):
        turn on the HTML version of the API, defaults to false
      user (int):
        identifier of the user, defaults to logged user
      concepts (list):
        list of identifiers of concepts, defaults to all concepts
      lang (str):
        language of requested concepts, defaults to language from django
    """
    user = get_user_id(request)
    language = get_language(request)

    concepts = None  # meaning all concept
    if "concepts" in request.GET:
        concepts = Concept.objects.filter(lang=language,
                                          active=True,
                                          identifier__in=load_query_json(
                                              request.GET, "concepts"))
    data = UserStat.objects.get_user_stats(user, language, concepts)
    return render_json(request,
                       data,
                       template='concepts_json.html',
                       help_text=user_stats.__doc__)
Beispiel #23
0
def log(request):
    """
    Log an event from the client to the server.

    POST parameters (JSON keys):
      message:
        description (str) of the logged event
      level:
        debug|info|warn|error
      data:
        additional data (JSON) describing the logged event
    """
    if request.method == "POST":
        log_dict = json_body(request.body.decode("utf-8"))
        if 'message' not in log_dict:
            return HttpResponseBadRequest('There is no message to log!')
        levels = {
            'debug': JAVASCRIPT_LOGGER.debug,
            'info': JAVASCRIPT_LOGGER.info,
            'warn': JAVASCRIPT_LOGGER.warn,
            'error': JAVASCRIPT_LOGGER.error,
        }
        log_fun = JAVASCRIPT_LOGGER.info
        if 'level' in log_dict:
            log_fun = levels[log_dict['level']]
        log_fun(log_dict['message'], extra={
            'request': request,
            'user': request.user.id if request.user.is_authenticated() else None,
            'client_data': json_lib.dumps(log_dict.get('data', {})),
        })
        return HttpResponse('ok', status=201)
    else:
        return render_json(request, {}, template='common_log_service.html', help_text=log.__doc__)
Beispiel #24
0
def user_stats_api(request, provider):
    """
    Get statistics for selected Edookit users

    key:
      api key
    since:
      time as timestamp - get stats changed since
    """

    if 'key' not in request.GET or provider not in settings.USER_STATS_API_KEY \
            or request.GET['key'] != settings.USER_STATS_API_KEY[provider]:
        return HttpResponse('Unauthorized', status=401)
    since = None
    if 'since' in request.GET:
        since = datetime.datetime.fromtimestamp(int(request.GET['since']))

    social_users = list(
        UserSocialAuth.objects.filter(
            provider=provider).select_related('user'))
    user_map = {u.user.id: u for u in social_users}
    stats = UserStat.objects.get_user_stats([u.user for u in social_users],
                                            lang=None,
                                            since=since,
                                            recalculate=False)
    data = {"users": []}
    for user, s in stats.items():
        data["users"].append({
            "user_id": user_map[user].uid,
            "concepts": s,
        })
    return render_json(request,
                       data,
                       template='concepts_json.html',
                       help_text=user_stats_bulk.__doc__)
Beispiel #25
0
def survival_curve(request, metric):
    '''
    Shows a learning curve based on the randomized testing.

    GET parameters:
      length:
        length of the learning curve
      context:
        JSON representing the practice context
      all_users:
        if present stop filtering users based on the minimal number of testing
        answers (=length)
    '''
    practice_filter = get_filter(request, force=False)
    context = None if practice_filter is None else PracticeContext.objects.from_content(
        practice_filter).id
    if metric == 'answers':
        length = int(request.GET.get('length', 100))
        models_survival_curve_answers(length, context=context)
    else:
        length = int(request.GET.get('length', 600))
        models_survival_curve_time(length, context=context)
    return render_json(request,
                       models_learning_curve(length, context=context),
                       template='models_json.html',
                       help_text=learning_curve.__doc__)
Beispiel #26
0
def rating(request):
    """
    Rate the current practice.

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

    POST parameters (JSON):
        value:
            one of the following numbers:
                (1) too easy,
                (2) appropriate,
                (3) too difficult
    """
    if request.method == 'GET':
        return render(request, 'feedback_rating.html', {}, help_text=rating.__doc__)
    if request.method == 'POST':
        data = json_body(request.body.decode("utf-8"))
        if data['value'] not in list(range(1, 4)):
            return render_json(
                request,
                {'error': _('The given value is not valid.'), 'error_type': 'invalid_value'},
                template='feedback_json.html', status=400
            )
        rating_object = Rating(
            user=request.user,
            value=data['value'],
        )
        rating_object.save()
        return HttpResponse('ok', status=201)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #27
0
def my_referrals(request):
    return render_json(request, [
        s.to_json(confidential=True)
        for s in request.user.referred_subscriptions.order_by(
            '-created').filter(payment__state=PaymentStatus.PAID)
    ],
                       template='subscription_json.html')
Beispiel #28
0
def _csv_table(request, filename):
    if filename not in [x[1] for xs in get_tables_allowed_to_export().values() for x in xs] and \
            filename not in [x for xs in get_custom_exports().values() for x in xs.keys()]:
        response = {
            "error": "the requested file '%s' is not valid" % filename
        }
        return render_json(request, response, status=400, template='common_json.html')
    download_file = settings.DATA_DIR + '/' + filename + ".csv"
    if not os.path.exists(download_file):
        response = {
            "error": "there is no data for the given table"
        }
        return render_json(request, response, status=204, template='common_json.html')
    response = HttpResponse(FileWrapper(open(download_file)), content_type='application/csv')
    response['Content-Length'] = os.path.getsize(download_file)
    response['Content-Disposition'] = 'attachment; filename=' + filename + '.csv'
    return response
Beispiel #29
0
 def process_exception(self, request, exception):
     if isinstance(exception, HttpError):
         return render_json(request, {
             'error': str(exception),
             'error_type': 'bad_request'
         },
                            template='common_json.html',
                            status=exception.http_status)
Beispiel #30
0
def to_practice(request):
    practice_filter = get_filter(request)
    item_ids = Item.objects.filter_all_reachable_leaves(
        practice_filter, get_language(request))
    if len(item_ids) == 0:
        return render_json(
            request, {
                'error':
                _('There is no item for the given filter to practice.'),
                'error_type': 'empty_practice'
            },
            status=404,
            template='models_json.html')
    result = [Item.objects.item_id_to_json(item_id) for item_id in item_ids]
    return render_json(request,
                       result,
                       template='models_json.html',
                       help_text=to_practice.__doc__)
Beispiel #31
0
def subscribe(request, description_id):
    return_url = request.GET.get('return_url', request.META['HTTP_HOST'])
    description = get_object_or_404(SubscriptionPlanDescription, id=description_id)
    discount_code = get_discount_code(request)
    subscription = Subscription.objects.subscribe(
        request.user, description, discount_code,
        get_referral_user(request), return_url
    )
    return render_json(request, subscription.to_json(), template='subscription_json.html', status=202)
Beispiel #32
0
def csv(request, filename=None):
    if not request.user.is_staff:
        response = {
            "error": "Permission denied: you need to be staff member. If you think you should be able to access logs, contact admins."}
        return render_json(request, response, status=401, template='common_json.html')
    if filename:
        return _csv_table(request, filename)
    else:
        return _csv_list(request)
Beispiel #33
0
def to_practice_counts(request):
    """
    Get number of items available to practice.

    filters:                -- use this or body
      json as in BODY
    language:
      language of the items

    BODY
      json in following format:
      {
        "#identifier": []         -- custom identifier (str) and filter
        ...
      }
    """
    data = None
    if request.method == "POST":
        data = json.loads(request.body.decode("utf-8"))["filters"]
    if "filters" in request.GET:
        data = load_query_json(request.GET, "filters")
    if data is None or len(data) == 0:
        return render_json(request, {},
                           template='models_json.html',
                           help_text=to_practice_counts.__doc__)
    language = get_language(request)
    timer('to_practice_counts')
    filter_names, filter_filters = list(zip(*sorted(data.items())))
    reachable_leaves = Item.objects.filter_all_reachable_leaves_many(
        filter_filters, language)
    response = {
        group_id: {
            'filter': data[group_id],
            'number_of_items': len(items),
        }
        for group_id, items in zip(filter_names, reachable_leaves)
    }
    LOGGER.debug(
        "to_practice_counts - getting items in groups took %s seconds",
        (timer('to_practice_counts')))
    return render_json(request,
                       response,
                       template='models_json.html',
                       help_text=to_practice_counts.__doc__)
Beispiel #34
0
def login(request):
    """
    Log in

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

    POST parameters (JSON):
        username:
            user's name
        password:
            user's password
    """
    if request.method == 'GET':
        return render(request, 'user_login.html', {}, help_text=login.__doc__)
    elif request.method == 'POST':
        credentials = json_body(request.body.decode("utf-8"))
        user = auth.authenticate(
            username=credentials.get('username', ''),
            password=credentials.get('password', ''),
        )
        if user is None:
            return render_json(
                request, {
                    'error': _('Password or username does not match.'),
                    'error_type': 'password_username_not_match'
                },
                template='user_json.html',
                status=401)
        if not user.is_active:
            return render_json(
                request, {
                    'error': _('The account has not been activated.'),
                    'error_type': 'account_not_activated'
                },
                template='user_json.html',
                status=401)
        auth.login(request, user)
        request.method = "GET"
        return profile(request)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(
            request.method))
Beispiel #35
0
def plans(request):
    lang = get_language(request)
    discount_code = get_discount_code(request)
    if discount_code is not None:
        discount_code.is_valid(request.user, throw_exception=True)
    return render_json(request, [
        p.to_json(lang=lang, discount_code=discount_code)
        for p in SubscriptionPlan.objects.prepare_related().filter(active=True)
    ],
                       template='subscription_json.html')
Beispiel #36
0
def stop_sending_emails(request, user_id, token):
    profile = get_object_or_404(UserProfile, user_id=user_id)
    if UserProfile.objects.get_user_hash(profile.user) != token:
        return render_json(request, {
            'error': _('The given token does not match.'),
            'error_type': 'unauthorized'
        }, status=401, template='user_json.html')
    profile.send_emails = False
    profile.save()
    return HttpResponse('ok', status=202)
Beispiel #37
0
def plans(request):
    lang = get_language(request)
    discount_code = get_discount_code(request)
    if discount_code is not None:
        discount_code.is_valid(request.user, throw_exception=True)
    return render_json(
        request,
        [p.to_json(lang=lang, discount_code=discount_code) for p in SubscriptionPlan.objects.prepare_related().filter(active=True)],
        template='subscription_json.html'
    )
Beispiel #38
0
def languages(request):
    """
    Returns languages that are available in the system.

    Returns Dict: language_code -> domain
    """
    return render_json(request,
                       settings.LANGUAGE_DOMAINS if hasattr(settings, 'LANGUAGE_DOMAINS') else
                       {"error": "Languages are not set. (Set LANGUAGE_DOMAINS in settings.py)"},
                       template='common_json.html', help_text=languages.__doc__)
def login_student(request):
    """
    Log in student

    POST parameters (JSON):
        student:
            profile id of the student
    """
    if not get_config('proso_user', 'allow_login_students', default=False):
        return render_json(request, {
            'error': _('Log in as student is not allowed.'),
            'error_type': 'login_student_not_allowed'
        }, template='class_create_student.html', help_text=login_student.__doc__, status=403)

    if request.method == 'GET':
        return render(request, 'class_login_student.html', {}, help_text=login_student.__doc__)
    elif request.method == 'POST':
        if not request.user.is_authenticated() or not hasattr(request.user, "userprofile"):
            return render_json(request, {
                'error': _('User is not logged in.'),
                'error_type': 'user_unauthorized'
            }, template='class_create_student.html', status=401)
        data = json_body(request.body.decode("utf-8"))
        try:
            student = User.objects.get(userprofile=data.get('student'),
                                       userprofile__classes__owner=request.user.userprofile)
        except User.DoesNotExist:
            return render_json(request, {
                'error': _('Student not found'),
                'error_type': 'student_not_found'
            }, template='class_login_student.html', status=401)
        if not student.is_active:
            return render_json(request, {
                'error': _('The account has not been activated.'),
                'error_type': 'account_not_activated'
            }, template='class_login_student.html', status=401)
        student.backend = 'django.contrib.auth.backends.ModelBackend'
        login(request, student)
        request.method = "GET"
        return profile(request)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #40
0
def _csv_table(request, filename):
    if filename not in [x[1] for xs in get_tables_allowed_to_export().values() for x in xs] and \
            filename not in [x for xs in get_custom_exports().values() for x in xs.keys()]:
        response = {"error": "the requested file '%s' is not valid" % filename}
        return render_json(request,
                           response,
                           status=400,
                           template='common_json.html')
    download_file = settings.DATA_DIR + '/' + filename + ".csv"
    if not os.path.exists(download_file):
        response = {"error": "there is no data for the given table"}
        return render_json(request,
                           response,
                           status=204,
                           template='common_json.html')
    response = HttpResponse(FileWrapper(open(download_file)),
                            content_type='application/csv')
    response['Content-Length'] = os.path.getsize(download_file)
    response[
        'Content-Disposition'] = 'attachment; filename=' + filename + '.csv'
    return response
Beispiel #41
0
def stop_sending_emails(request, user_id, token):
    profile = get_object_or_404(UserProfile, user_id=user_id)
    if UserProfile.objects.get_user_hash(profile.user) != token:
        return render_json(request, {
            'error': _('The given token does not match.'),
            'error_type': 'unauthorized'
        },
                           status=401,
                           template='user_json.html')
    profile.send_emails = False
    profile.save()
    return HttpResponse('ok', status=202)
Beispiel #42
0
def status(request):
    user_id = get_user_id(request)
    time = get_time(request)
    environment = get_environment()
    if is_time_overridden(request):
        environment.shift_time(time)
    return render_json(request, {
        'object_type': 'status',
        'number_of_answers': environment.number_of_answers(user=user_id),
        'number_of_correct_answers': environment.number_of_correct_answers(user=user_id),
        'environment_info': get_active_environment_info(),
    }, template='models_json.html')
Beispiel #43
0
def classes(request):
    """Get all classes of current user"""

    if not request.user.is_authenticated() or not hasattr(
            request.user, "userprofile"):
        return render_json(request, {
            'error': _('User is not logged in'),
            'error_type': 'user_unauthorized'
        },
                           template='user_json.html',
                           status=401)
    clss = [
        c.to_json()
        for c in Class.objects.filter(owner=request.user.userprofile)
    ]

    return render_json(request,
                       clss,
                       status=200,
                       template='user_json.html',
                       help_text=classes.__doc__)
Beispiel #44
0
def signup(request):
    """
    Create a new user with the given credentials.

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

    POST parameters (JSON):
        username:
            user's name
        email:
            user's e-mail
        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':
        return render(request, 'user_signup.html', {}, help_text=signup.__doc__)
    elif request.method == 'POST':
        if request.user.is_authenticated() and hasattr(request.user, "userprofile"):
            return render_json(request, {
                'error': _('User already logged in'),
                'error_type': 'username_logged'
            }, template='user_json.html', status=400)
        credentials = json_body(request.body.decode("utf-8"))
        error = _save_user(request, credentials, new=True)
        if error is not None:
            return render_json(request, error, template='user_json.html', status=400)
        else:
            auth.login(request, request.user)
            request.method = "GET"
            return profile(request, status=201)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #45
0
def answers(request):
    limit = min(int(request.GET.get('limit', 10)), 1000)
    user_id = get_user_id(request)
    item_ids = Item.objects.filter_all_reachable_leaves(
        get_filter(request), get_language(request))
    found_answers = Answer.objects.answers(
        Answer.objects.filter(item_asked_id__in=item_ids,
                              user_id=user_id).order_by('-id').values_list(
                                  'id', flat=True)[:limit])
    return render_json(request,
                       found_answers,
                       template='models_json.html',
                       help_text=answers.__doc__)
Beispiel #46
0
def subscribe(request, description_id):
    return_url = request.GET.get('return_url', request.META['HTTP_HOST'])
    description = get_object_or_404(SubscriptionPlanDescription,
                                    id=description_id)
    discount_code = get_discount_code(request)
    subscription = Subscription.objects.subscribe(request.user, description,
                                                  discount_code,
                                                  get_referral_user(request),
                                                  return_url)
    return render_json(request,
                       subscription.to_json(),
                       template='subscription_json.html',
                       status=202)
def create_class(request):
    """Create new class

    POST parameters (JSON):
        name:
            Human readable name of class
        code (optional):
            unique code of class used for joining to class
    """

    if request.method == 'GET':
        return render(request, 'classes_create.html', {}, help_text=create_class.__doc__)

    if request.method == 'POST':
        if not request.user.is_authenticated() or not hasattr(request.user, "userprofile"):
            return render_json(request, {
                'error': _('User is not logged in.'),
                'error_type': 'user_unauthorized'
            }, template='classes_create.html', status=401)

        data = json_body(request.body.decode("utf-8"))
        if 'code' in data and Class.objects.filter(code=data['code']).exists():
            return render_json(request, {
                'error': _('A class with this code already exists.'),
                'error_type': 'class_with_code_exists'
            }, template='classes_create.html', status=400)

        if 'name' not in data or not data['name']:
            return render_json(request, {'error': _('Class name is missing.'), 'error_type': 'missing_class_name'},
                               template='classes_create.html', status=400)

        cls = Class(name=data['name'], owner=request.user.userprofile)
        if 'code' in data:
            cls.code = data['code']
        cls.save()
        return render_json(request, cls.to_json(), template='classes_create.html', status=201)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #48
0
def user_stats_bulk(request):
    """
    Get statistics for selected users and concepts

    since:
      time as timestamp - get stats changed since
    users:
      list of identifiers of users
    concepts (Optional):
      list of identifiers of concepts
    language:
      language of concepts
    """

    language = get_language(request)
    users = load_query_json(request.GET, "users")
    if request.user.is_staff:
        if not hasattr(request.user, 'userprofile') or User.objects.filter(pk__in=users,
                       userprofile__classes__owner=request.user.userprofile).count() < len(users):
            return render_json(request, {
                'error': _('Some requested users are not in owned classes'),
                'error_type': 'permission_denied'
            }, template='concepts_json.html', status=401)
    since = None
    if 'since' in request.GET:
        since = datetime.datetime.fromtimestamp(int(request.GET['since']))
    concepts = None
    if "concepts" in request.GET:
        concepts = Concept.objects.filter(lang=language, active=True,
                                          identifier__in=load_query_json(request.GET, "concepts"))
    stats = UserStat.objects.get_user_stats(users, language, concepts=concepts, since=since)
    data = {"users": []}
    for user, s in stats.items():
        data["users"].append({
            "user_id": user,
            "concepts": s,
        })
    return render_json(request, data, template='concepts_json.html', help_text=user_stats_bulk.__doc__)
Beispiel #49
0
def csv(request, filename=None):
    if not request.user.is_staff:
        response = {
            "error":
            "Permission denied: you need to be staff member. If you think you should be able to access logs, contact admins."
        }
        return render_json(request,
                           response,
                           status=401,
                           template='common_json.html')
    if filename:
        return _csv_table(request, filename)
    else:
        return _csv_list(request)
Beispiel #50
0
def tag_values(request):
    """
    Get tags types and values with localized names

    language:
      language of tags
    """

    data = defaultdict(lambda: {"values": {}})
    for tag in Tag.objects.filter(lang=get_language(request)):
        data[tag.type]["name"] = tag.type_name
        data[tag.type]["values"][tag.value] = tag.value_name

    return render_json(request, data, template='concepts_json.html', help_text=tag_values.__doc__)
Beispiel #51
0
def login(request):
    """
    Log in

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

    POST parameters (JSON):
        username:
            user's name
        password:
            user's password
    """
    if request.method == 'GET':
        return render(request, 'user_login.html', {}, help_text=login.__doc__)
    elif request.method == 'POST':
        credentials = json_body(request.body.decode("utf-8"))
        user = auth.authenticate(
            username=credentials.get('username', ''),
            password=credentials.get('password', ''),
        )
        if user is None:
            return render_json(request, {
                'error': _('Password or username does not match.'),
                'error_type': 'password_username_not_match'
            }, template='user_json.html', status=401)
        if not user.is_active:
            return render_json(request, {
                'error': _('The account has not been activated.'),
                'error_type': 'account_not_activated'
            }, template='user_json.html', status=401)
        auth.login(request, user)
        request.method = "GET"
        return profile(request)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #52
0
def to_practice_counts(request):
    """
    Get number of items available to practice.

    filters:                -- use this or body
      json as in BODY
    language:
      language of the items

    BODY
      json in following format:
      {
        "#identifier": []         -- custom identifier (str) and filter
        ...
      }
    """
    data = None
    if request.method == "POST":
        data = json.loads(request.body.decode("utf-8"))["filters"]
    if "filters" in request.GET:
        data = load_query_json(request.GET, "filters")
    if data is None:
        return render_json(request, {}, template='models_json.html', help_text=to_practice_counts.__doc__)
    language = get_language(request)
    timer('to_practice_counts')
    filter_names, filter_filters = list(zip(*sorted(data.items())))
    reachable_leaves = Item.objects.filter_all_reachable_leaves_many(filter_filters, language)
    response = {
        group_id: {
            'filter': data[group_id],
            'number_of_items': len(items),
        }
        for group_id, items in zip(filter_names, reachable_leaves)
    }
    LOGGER.debug("flashcard_counts - getting flashcards in groups took %s seconds", (timer('to_practice_counts')))
    return render_json(request, response, template='models_json.html', help_text=to_practice_counts.__doc__)
def join_class(request):
    """Join a class

    POST parameters (JSON):
        code:
            code of the class
    """

    if request.method == 'GET':
        return render(request, 'classes_join.html', {}, help_text=join_class.__doc__)

    if request.method == 'POST':
        if not request.user.is_authenticated() or not hasattr(request.user, "userprofile"):
            return render_json(request, {
                'error': _('User is not logged in.'),
                'error_type': 'user_unauthorized'
            }, template='classes_join.html', status=401)

        data = json_body(request.body.decode("utf-8"))

        if 'code' not in data or not data['code']:
            return render_json(request, {'error': _('Class code is missing.'), 'error_type': 'missing_class_code'},
                               template='classes_join.html', status=400)

        try:
            cls = Class.objects.get(code=data['code'])
        except Class.DoesNotExist:
            return render_json(request, {
                'error': _('Class with given code not found.'),
                'error_type': 'class_not_found',
            }, template='classes_join.html', status=404)

        cls.members.add(request.user.userprofile)
        return render_json(request, cls.to_json(), template='classes_join.html', status=200)
    else:
        return HttpResponseBadRequest("method %s is not allowed".format(request.method))
Beispiel #54
0
def show_one(request, post_process_fun, object_class, id, template='common_json.html'):
    """
    Return object of the given type with the specified identifier.

    GET parameters:
      user:
        identifier of the current user
      stats:
        turn on the enrichment of the objects by some statistics
      html
        turn on the HTML version of the API
    """
    obj = get_object_or_404(object_class, pk=id)
    json = post_process_fun(request, obj)
    return render_json(request, json, template=template, help_text=show_one.__doc__)
Beispiel #55
0
def languages(request):
    """
    Returns languages that are available in the system.

    Returns Dict: language_code -> domain
    """
    return render_json(
        request,
        settings.LANGUAGE_DOMAINS
        if hasattr(settings, 'LANGUAGE_DOMAINS') else {
            "error":
            "Languages are not set. (Set LANGUAGE_DOMAINS in settings.py)"
        },
        template='common_json.html',
        help_text=languages.__doc__)
Beispiel #56
0
def recommend_users(request):
    '''
    Recommend users for further analysis.

    GET parameters:
      register_min:
        minimal date of user's registration ('%Y-%m-%d')
      register_max:
        maximal date of user's registration ('%Y-%m-%d')
      number_of_answers_min:
        minimal number of user's answers
      number_of_answers_max:
        maximal number of user's answers
      success_min:
        minimal user's success rate
      success_max:
        maximal user's success rate
      variable_name:
        name of the filtered parameter
      variable_min:
        minimal value of the parameter of the model
      variable_max:
        maximal value of parameter of the model
      limit:
        number of returned questions (default 10, maximum 100)
    '''
    limit = int(request.GET.get('limit', 1))

    def _get_interval(key):
        return request.GET.get('{}_min'.format(key)), request.GET.get(
            '{}_max'.format(key))

    def _convert_time_interval(interval):
        mapped = [
            None if x is None else datetime.datetime.strptime(x, '%Y-%m-%d')
            for x in list(interval)
        ]
        return mapped[0], mapped[1]

    recommended = models_recommend_users(
        _convert_time_interval(_get_interval('register')),
        _get_interval('number_of_answers'), _get_interval('success'),
        request.GET.get('variable_name'), _get_interval('variable'), limit)
    return render_json(request,
                       recommended,
                       template='models_json.html',
                       help_text=recommend_users.__doc__)
Beispiel #57
0
def _csv_list(request):
    apps = defaultdict(dict)
    for app, app_data in get_tables_allowed_to_export().items():
        apps[app]['tables'] = list(
            map(
                lambda d: {
                    'name': d[1],
                    'url': reverse('csv_table', kwargs={'filename': d[1]})
                }, app_data))
    for app, app_data in get_custom_exports().items():
        apps[app]['custom_exports'] = list(
            map(
                lambda name: {
                    'name': name,
                    'url': reverse('csv_table', kwargs={'filename': name})
                }, app_data))
    return render_json(request, apps, template='common_json.html')
Beispiel #58
0
def recommend_users(request):
    '''
    Recommend users for further analysis.

    GET parameters:
      register_min:
        minimal date of user's registration ('%Y-%m-%d')
      register_max:
        maximal date of user's registration ('%Y-%m-%d')
      number_of_answers_min:
        minimal number of user's answers
      number_of_answers_max:
        maximal number of user's answers
      success_min:
        minimal user's success rate
      success_max:
        maximal user's success rate
      variable_name:
        name of the filtered parameter
      variable_min:
        minimal value of the parameter of the model
      variable_max:
        maximal value of parameter of the model
      limit:
        number of returned questions (default 10, maximum 100)
    '''
    limit = int(request.GET.get('limit', 1))

    def _get_interval(key):
        return request.GET.get('{}_min'.format(key)), request.GET.get('{}_max'.format(key))

    def _convert_time_interval(interval):
        mapped = [None if x is None else datetime.datetime.strptime(x, '%Y-%m-%d') for x in list(interval)]
        return mapped[0], mapped[1]

    recommended = models_recommend_users(
        _convert_time_interval(_get_interval('register')),
        _get_interval('number_of_answers'),
        _get_interval('success'),
        request.GET.get('variable_name'),
        _get_interval('variable'),
        limit)
    return render_json(request, recommended, template='models_json.html', help_text=recommend_users.__doc__)
Beispiel #59
0
def user_stats(request):
    """
    JSON of user stats of the user

    GET parameters:
      html (bool):
        turn on the HTML version of the API, defaults to false
      user (int):
        identifier of the user, defaults to logged user
      concepts (list):
        list of identifiers of concepts, defaults to all concepts
      lang (str):
        language of requested concepts, defaults to language from django
    """
    user = get_user_id(request)
    language = get_language(request)

    concepts = None    # meaning all concept
    if "concepts" in request.GET:
        concepts = Concept.objects.filter(lang=language, active=True,
                                          identifier__in=load_query_json(request.GET, "concepts"))
    data = UserStat.objects.get_user_stats(user, language, concepts)
    return render_json(request, data, template='concepts_json.html', help_text=user_stats.__doc__)