Пример #1
0
def user_grouping(data):
    if data.get('group'):
        if not isinstance(data['group'], int):
            return http_err(400, 'group must be int')
    else:
        return http_err(400, 'group parameter is missing')
    group = Group.query.filter_by(id=data['group'], user_id=None).first()
    if not group:
        return http_err(404, 'group not found')
    if data.get('users'):
        if not isinstance(data['users'], (int, list)):
            return http_err(400, 'users must be int or array, users id')
        if isinstance(data['users'], int):
            data['users'] = [data['users']]
        resp = []

        for u_id in data['users']:
            user = User.query.get(u_id)
            if not user:
                return http_err(404, 'user {} not found'.format(u_id))
            resp.append(user.asdict())
            if request.method == 'POST':
                if user not in group.users:
                    group.users.append(user)
            else:
                if user in group.users:
                    group.users.remove(user)

        db.session.add(group)
        db.session.commit()
        return http_ok(**group.asdict(), users=resp)

    if data.get('entry_group'):
        if not isinstance(data['entry_group'], (int, list)):
            return http_err(400, 'entry_group must be int or array')
        if isinstance(data['entry_group'], int):
            data['entry_group'] = [data['entry_group']]
        resp = []
        for g_id in data['entry_group']:
            entry_group = Group.query.filter_by(id=g_id, user_id=None).first()
            if not entry_group:
                return http_err(404, 'entry_group not found')
            if not group_available(group.id, entry_group.id):
                return http_err(400, 'recursion error')
            group_group = GroupsGroups.query.filter_by(
                group=group.id, entry=entry_group.id).first()
            if request.method == 'POST':
                if not group_group:
                    group_group = GroupsGroups(group=group.id,
                                               entry=entry_group.id)
                    db.session.add(group_group)
            else:
                if group_group:
                    db.session.delete(group_group)

            resp.append(entry_group.asdict())
        db.session.commit()
        return http_ok(**group.asdict(), entry_group=resp)

    return http_err(400, 'users or entry_group parameter is missing')
Пример #2
0
def questions_get(token_data):
    questions = Question.query.filter_by(user_id=token_data['id']).all()
    resp = [q.asdict() for q in questions]
    # for question in questions:
    #     answers = [a.asdict() for a in question.answers]
    #     resp.append(dict(question=question.asdict(), answers=answers))
    return http_ok(questions=resp)
Пример #3
0
def me_patch(token_data, data):
    for k, v in data.items():
        if k not in ['username', 'old_password', 'new_password', 'email']:
            return http_err(400, 'unknown parameter {}'.format(k))
    user = User.query.filter_by(id=token_data['id']).first()
    username = data.get('username')
    email = data.get('email')
    password = data.get('new_password')
    if username:
        if user.query.filter_by(username=username).first():
            return http_err(404, 'user with given username already exists')
        user.username = username
    if email:
        if user.query.filter_by(email=email).first():
            return http_err(404, 'user with given email already exists')
        user.email = email
    if password:
        old_password = data.get('old_password')
        if not old_password:
            return http_err(400, 'old password not given')
        if not user.verify_password(old_password):
            return http_err(401, 'old password did not match')
        user.password = password

    db.session.add(user)
    db.session.commit()
    return http_ok(**user.asdict())
Пример #4
0
def competitions_post(data, token_data):
    if not isinstance(data['start_date'], (int, float)):
        return http_err(400, 'start_date must be timestamp unix format')
    if not isinstance(data['end_date'], (int, float)):
        return http_err(400, 'end_date must be timestamp unix format')
    if data['end_date'] < data['start_date']:
        return http_err(
            400, 'specify correct end_date *hint greater than start_date')
    if not isinstance(data['test'], int):
        return http_err(400, 'test must be int (id of the test)')
    if not isinstance(data['title'], str):
        return http_err(400, 'title must be string')
    if data.get('description'):
        if not isinstance(data['description'], str):
            return http_err(400, 'description must be string')

    test = Test.query.filter_by(id=data['test'],
                                owner=token_data['id']).first()
    if not test:
        return http_err(400, 'test not found')

    params = {
        k: v
        for k, v in data.items()
        if k in ['description', 'title', 'start_date', 'end_date']
    }
    competition = Competition(test_id=test.id,
                              user_id=token_data['id'],
                              **params)

    db.session.add(competition)
    db.session.commit()
    return http_ok(**competition.asdict())
Пример #5
0
def me_competition_submission(token_data, id):
    user = User.query.get(token_data['id'])
    competition = Competition.query.get(id)
    if not competition:
        return http_err(404, 'competition not found')
    if now() < competition.end_date:
        return http_err(404, 'competition not finished yet')
    if not competition:
        return http_err(404, 'competition not found')
    submissions = Submission.query.filter_by(
        user_id=user.id, competition_id=competition.id).all()
    if not submissions:
        return http_err(404, 'you have not submitted yet')

    test = Test.query.get(competition.test_id)
    questions = test.questions
    q_dict = []
    for question in questions:
        answers = [a.asdict() for a in question.answers]
        question = question.asdict()
        question['answers'] = answers
        q_dict.append(question)
    test = test.asdict()
    test['questions'] = q_dict
    return http_ok(test=test, submission=[s.asdict() for s in submissions])
Пример #6
0
def answers_get(q_id, token_data):
    question = Question.query.filter_by(id=q_id,
                                        user_id=token_data['id']).first()
    if not question:
        return http_err(404, 'question not found')
    answers = [a.asdict() for a in question.answers]
    return http_ok(answers=answers)
Пример #7
0
def test_delete(id, token_data):
    test = Test.query.filter_by(id=id, owner=token_data['id']).first()
    if not test:
        return http_err(404, 'test not found')
    db.session.delete(test)
    db.session.commit()
    return http_ok(**test.asdict())
Пример #8
0
def groups_post(data, token_data):
    if data.get('description'):
        if not isinstance(data['description'], str):
            return http_err(400, 'description parameter must be string')

        group = Group(title=data['title'],
                      description=data['description'],
                      user_id=token_data['id'])
    else:
        group = Group(title=data['title'], user_id=token_data['id'])
    unknowns = []
    if data.get('questions'):
        if not isinstance(data['questions'], list):
            return http_err(400, 'questions parameter must be array')
        for q_id in data['questions']:
            question = Question.query.get(q_id)
            if not question:
                unknowns.append(q_id)
                continue
            group.questions.append(question)
    if data.get('users'):
        if not isinstance(data['users'], list):
            return http_err(400, 'users parameter must be array')
        for u_id in data['users']:
            user = User.query.get(u_id)
            if not user:
                unknowns.append(u_id)
                continue
            group.users.append(user)
    db.session.add(group)
    db.session.commit()
    return http_ok(**group.asdict())
Пример #9
0
def question_get(id, token_data):
    question = Question.query.filter_by(user_id=token_data['id'],
                                        id=id).first()
    if not question:
        return http_err(404, 'not found')
    answers = [a.asdict() for a in question.answers]
    return http_ok(**question.asdict(), answers=answers)
Пример #10
0
def answer_post(data, token_data, q_id):
    question = Question.query.filter_by(id=q_id, user_id=token_data['id']).first()
    if not question:
        return http_err(404, 'question not found')
    answer = Answers(text=data['text'], correct=data['correct'], question_id=question.id)
    db.session.add(answer)
    db.session.commit()
    return http_ok(**answer.asdict())
Пример #11
0
def answer_get(token_data, q_id, a_id):
    question = Question.query.filter_by(id=q_id, user_id=token_data['id']).first()
    if not question:
        return http_err(404, 'question not found')
    answer = Answers.query.filter_by(question_id=question.id, id=a_id).first()
    if not answer:
        return http_err(404, 'answer not found')
    return http_ok(**answer.asdict())
Пример #12
0
def question_patch(id, token_data, data):
    question = Question.query.filter_by(user_id=token_data['id'],
                                        id=id).first()
    if not question:
        return http_err(404, 'not found')
    question.text = data['text']
    db.session.add(question)
    db.session.commit()
    return http_ok(**question.asdict())
Пример #13
0
def answer_delete(q_id, a_id, token_data):
    question = Question.query.filter_by(id=q_id, user_id=token_data['id']).first()
    if not question:
        return http_err(404, 'question not found')
    answer = Answers.query.filter_by(question_id=question.id, id=a_id).first()
    if not answer:
        return http_err(404, 'answer not found')
    db.session.delete(answer)
    db.session.commit()
    return http_ok(**answer.asdict())
Пример #14
0
def group_get(token_data, id):
    group = Group.query.filter_by(id=id, user_id=token_data['id']).first()
    if not group:
        return http_err(404, 'group not found')
    return http_ok(**get_group_tree(group))


# @app.route('/v1/groups/<id>', methods=['DELETE'])
# @secured('manager admin')
# def group_delete(id, token_data):
#     group =
Пример #15
0
def user_login(data):
    # TODO: email validation
    if '@' in data['testar']:
        user = User.query.filter_by(email=data['testar']).first()
    else:
        user = User.query.filter_by(username=data['testar']).first()
    if not user:
        return http_err(404, 'user with given credentials not found')
    if not user.verify_password(data['password']):
        return http_err(403, 'incorrect password')
    token = get_token(user.asdict())
    return http_ok(**user.asdict(), jwt=token)
Пример #16
0
def question_delete(id, token, token_data):
    question = Question.query.filter_by(user_id=token_data['id'],
                                        id=id).first()
    if not question:
        return http_err(404, 'not found')
    ans = []
    for a in question.answers:
        db.session.delete(a)
        ans.append(a.asdict())
    db.session.delete(question)
    db.session.commit()
    return http_ok(**question.asdict(), answers=ans)
Пример #17
0
def test_get(id, token_data):
    test = Test.query.filter_by(id=id, owner=token_data['id']).first()
    if not test:
        return http_err(404, 'test not found')
    questions = test.questions
    q_dict = []
    for question in questions:
        answers = [a.asdict() for a in question.answers]
        question = question.asdict()
        question['answers'] = answers
        q_dict.append(question)

    return http_ok(**test.asdict(), questions=q_dict)
Пример #18
0
def participants_get(id, token_data):
    competition = Competition.query.filter_by(
        id=id, user_id=token_data['id']).first()
    if not competition:
        return http_err(404, 'competition not found')
    users = []
    for user in competition.participants:
        submission = [
            s.asdict() for s in Submission.query.filter_by(
                user_id=user.id, competition_id=competition.id).all()
        ]
        user_dict = user.asdict()
        user_dict['submission'] = submission
        users.append(user_dict)
    return http_ok(participants=users)
Пример #19
0
def answer_patch(q_id, a_id, token_data, data):
    for k, v in data.items():
        if k not in ['text', 'correct']:
            return http_err(400, 'unknown parameter {}'.format(k))
    question = Question.query.filter_by(id=q_id, user_id=token_data['id']).first()
    if not question:
        return http_err(404, 'question not found')
    answer = Answers.query.filter_by(question_id=question.id, id=a_id).first()
    if not answer:
        return http_err(404, 'answer not found')
    if data.get('text'):
        answer.text = data['text']
    if data.get('correct'):
        answer.correct = data['correct']
    db.session.add(answer)
    db.session.commit()
    return http_ok(**answer.asdict())
Пример #20
0
def questions_post(data, token_data):
    if not isinstance(data['incorrect_answers'], list):
        return http_err(400, 'incorrect_answers must be array')
    if not isinstance(data['correct_answers'], list):
        return http_err(400, 'correct_answers must be array')
    if not isinstance(data['text'], str):
        return http_err(400, 'text must be string')
    corrects = set()
    incorrects = set()
    for answer in data['correct_answers']:
        if not isinstance(answer, str):
            return http_err(
                400,
                'correct_answers must consist only strings, but {} ({}) found'.
                format(type(answer), answer))
        corrects.add(answer.lower())
    for answer in data['incorrect_answers']:
        if not isinstance(answer, str):
            return http_err(
                400,
                'incorrect_answers must consist only strings, but {} ({}) found'
                .format(type(answer), answer))
        incorrects.add(answer.lower())

    matched = corrects.intersection(incorrects)
    if matched:
        return http_err(
            400,
            'there is matches between correct_answers and incorrect_answers',
            matched=list(matched))

    question = Question(text=data['text'], user_id=token_data['id'])

    for answer in data['correct_answers']:
        ans = Answers(text=answer, correct=True)
        question.answers.append(ans)
    for answer in data['incorrect_answers']:
        ans = Answers(text=answer, correct=False)
        question.answers.append(ans)

    db.session.add(question)
    db.session.commit()

    answers = [q.asdict() for q in question.answers]
    return http_ok(question=question.asdict(), answers=answers)
Пример #21
0
def user_groups_post(data):
    if data.get('description'):
        if not isinstance(data['description'], str):
            return http_err(400, 'description parameter must be string')

        group = Group(title=data['title'], description=data['description'])
    else:
        group = Group(title=data['title'])
    if data.get('users'):
        if not isinstance(data['users'], list):
            return http_err(400, 'users parameter must be array')
        for u_id in data['users']:
            user = User.query.get(u_id)
            if not user:
                return http_err(404, 'user {} not found'.format(u_id))
            group.users.append(user)
    db.session.add(group)
    db.session.commit()
    return http_ok(**group.asdict())
Пример #22
0
def submission_post(id, data, token_data):
    if not isinstance(data['questions'], list):
        return http_err(400, 'questions must be array of dict', example=[dict(question=1, answer=4)])
    if not isinstance(data['questions'][0], dict):
        return http_err(400, 'questions must be array of dict', example=[dict(question=1, answer=4)])

    now = time()
    competition = Competition.query.get(id)
    if not competition:
        return http_err(404, 'competition not found')
    if competition.start_date > now:
        return http_err(404, "competition starts {}".format(datetime.fromtimestamp(competition.start_date)))
    if competition.end_date < now:
        return http_err(404, 'competition finished')

    participant = User.query.get(token_data['id'])
    if participant not in competition.participants:
        return http_err(403, 'you are not allowed to submit competition')
    test = Test.query.get(competition.test_id)
    if not test:
        return http_err(404, 'owner deleted the test')
    submitted = Submission.query.filter_by(user_id=participant.id, competition_id=competition.id).all()
    if submitted:
        return http_err(400, 'you have already submitted', submission=[s.asdict() for s in submitted])
    corrects = test.corrects()
    correct_count = 0
    for selected in data['questions']:
        if not selected.get('question') or 'answer' not in selected:
            return http_err(400, 'questions must be array of dict', example=[dict(question=1, answer=4)])
        if not corrects.get(selected['question']):
            return http_err(404, 'question not found', questions=selected)

        submission = Submission(question_id=selected['question'], answer_id=selected['answer'], user_id=participant.id,
                                competition_id=competition.id)
        db.session.add(submission)

        if selected['answer'] in corrects[selected['question']]:
            correct_count += 1
        selected['corrects'] = corrects[selected['question']]
    db.session.commit()
    return http_ok(corrects=correct_count, total=len(data['questions']))
Пример #23
0
def user_register(data):
    if User.query.filter_by(email=data['email']).first():
        return http_err(404, 'user with given email already exists')
    if User.query.filter_by(username=data['username']).first():
        return http_err(404, 'user with given username already exists')
    if not isinstance(data['first_name'], str):
        return http_err(400, 'first name must be string')
    if not isinstance(data['last_name'], str):
        return http_err(400, 'last_name must be string')
    new_user = User(username=data['username'],
                    email=data['email'],
                    password=data['password'],
                    first_name=data['first_name'],
                    last_name=data['last_name'])
    db.session.add(new_user)
    db.session.commit()
    token = get_token(new_user.asdict())

    # TODO: email verification

    return http_ok(**new_user.asdict(), jwt=token)
Пример #24
0
def tests_post(data, token_data):
    if not isinstance(data['questions'], list):
        return http_err(400, 'questions must be array of question ids')
    for q_id in data['questions']:
        if not isinstance(q_id, int):
            return http_err(400, 'questions must be array of question ids')
    params = {k: v for k, v in data.items() if k in ['title', 'description']}
    test = Test(
        **params,
        owner=token_data['id'],
    )

    for q_id in data['questions']:
        question = Question.query.filter_by(id=q_id,
                                            user_id=token_data['id']).first()
        if not question:
            return http_err(400, 'question not found, save question first')
        test.questions.append(question)
    db.session.add(test)
    db.session.commit()
    return http_ok(**test.asdict())
Пример #25
0
def competition_get(token_data, id):
    competition = Competition.query.filter_by(user_id=token_data['id'],
                                              id=id).first()
    if not competition:
        return http_err(404, 'competition not found')
    resp = competition.asdict()

    test = Test.query.get(competition.test_id)
    if not test:
        resp['test'] = 'not found'
    else:
        resp['test'] = test.asdict()
        resp['test']['questions'] = []
        for question in test.questions:
            q_dict = question.asdict()
            q_dict['answers'] = [q.asdict() for q in question.answers]
            resp['test']['questions'].append(q_dict)
    resp['participants'] = []
    for participant in competition.participants:
        resp['participants'].append(participant.asdict())
    return http_ok(**resp)
Пример #26
0
def submissions_get(token_data, id):
    now = time()
    competition = Competition.query.get(id)
    if not competition:
        return http_err(404, 'competition not found')
    if competition.start_date > now:
        return http_err(404, "competition starts {}".format(datetime.fromtimestamp(competition.start_date)))
    if competition.end_date < now:
        return http_err(404, 'competition finished')
    test = Test.query.get(competition.test_id)
    if not test:
        return http_err(404, 'test not found')
    participant = User.query.get(token_data['id'])
    if participant not in competition.participants:
        competition.participants.append(participant)
        db.session.add(competition)
        db.session.commit()
    competition = competition.asdict()
    test_dict = test.asdict()
    test_dict['questions'] = test.mixed_questions()
    competition['test'] = test_dict
    return http_ok(**competition)
Пример #27
0
def tests_get(token_data):
    tests = Test.query.filter_by(owner=token_data['id']).all()
    data = [t.asdict() for t in tests]
    return http_ok(tests=data)
Пример #28
0
def user_groups_get():
    groups = Group.query.filter_by(user_id=None).all()
    groups = [g.asdict() for g in groups]
    return http_ok(groups=groups)
Пример #29
0
def me_competitions(token_data):
    user = User.query.get(token_data['id'])
    return http_ok(competitions=[c.asdict() for c in user.competitions])
Пример #30
0
def user_group_get(id):
    group = Group.query.filter_by(id=id, user_id=None).first()
    if not group:
        return http_err(404, 'group not found')
    return http_ok(**get_group_tree(group))