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')
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)
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())
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())
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])
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)
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())
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())
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)
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())
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())
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())
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())
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 =
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)
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)
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)
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)
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())
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)
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())
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']))
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)
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())
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)
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)
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)
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)
def me_competitions(token_data): user = User.query.get(token_data['id']) return http_ok(competitions=[c.asdict() for c in user.competitions])
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))