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))
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))
def analysis(request, app_name=None): data = {} if app_name is None: data["apps"] = list(os.listdir(analyse.OUTPUT_DIR)) else: data["imgs"] = ["analysis/{}/{}".format(app_name, i) for i in os.listdir(os.path.join(analyse.OUTPUT_DIR, app_name))] data["app_name"] = app_name return render(request, 'common_analysis.html', data)
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))
def feedback(request): """ Send feedback to the authors of the system. GET parameters: html turn on the HTML version of the API POST parameters (JSON): text: the main feedback content email (optional): user's e-mail username (optional): user's name """ if request.method == 'GET': return render(request, 'feedback_feedback.html', {}, help_text=feedback.__doc__) if request.method == 'POST': feedback_data = json_body(request.body.decode("utf-8")) feedback_data['user_agent'] = Session.objects.get_current_session().http_user_agent.content if not feedback_data.get('username'): feedback_data['username'] = request.user.username if not feedback_data.get('email'): feedback_data['email'] = request.user.email comment = Comment.objects.create( username=feedback_data['username'], email=feedback_data['email'], text=feedback_data['text']) if get_config('proso_feedback', 'send_emails', default=True): feedback_domain = get_config('proso_feedback', 'domain', required=True) feedback_to = get_config('proso_feedback', 'to', required=True) if is_likely_worthless(feedback_data): mail_from = 'spam@' + feedback_domain else: mail_from = 'feedback@' + feedback_domain text_content = render_to_string("emails/feedback.plain.txt", { "feedback": feedback_data, "user": request.user, }) html_content = render_to_string("emails/feedback.html", { "feedback": feedback_data, "user": request.user, }) subject = feedback_domain + ' feedback ' + str(comment.id) mail = EmailMultiAlternatives( subject, text_content, mail_from, feedback_to, ) mail.attach_alternative(html_content, "text/html") mail.send() LOGGER.debug("email sent %s\n", text_content) return HttpResponse('ok', status=201) else: return HttpResponseBadRequest("method %s is not allowed".format(request.method))
def analysis(request, app_name=None): data = {} if app_name is None: data["apps"] = list(os.listdir(analyse.OUTPUT_DIR)) else: data["imgs"] = [ "analysis/{}/{}".format(app_name, i) for i in os.listdir(os.path.join(analyse.OUTPUT_DIR, app_name)) ] data["app_name"] = app_name return render(request, 'common_analysis.html', data)
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))
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))
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))
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))
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))
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))
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))
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, True) return render_json(request, saved_answers, status=200, template='models_answer.html') else: return HttpResponseBadRequest("method %s is not allowed".format( request.method))
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))
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))
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))
def user_service(request): if not hasattr(request.user, "userprofile"): user = "" else: user = json.dumps(request.user.userprofile.to_json()) return render(request, "user_service.html", {"user": user})
def create_student(request): """ Create new user in class POST parameters (JSON): class: id of the class username (optional): username of student, if not provided username is create based on name password (optional): password of student first_name: first_name of student last_name (optional): last_name of student email (optional): e-mail of student """ if not get_config('proso_user', 'allow_create_students', default=False): return render_json(request, { 'error': _('Creation of new users is not allowed.'), 'error_type': 'student_creation_not_allowed' }, template='class_create_student.html', help_text=create_student.__doc__, status=403) if request.method == 'GET': return render(request, 'class_create_student.html', {}, help_text=create_student.__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='class_create_student.html', status=401) data = json_body(request.body.decode("utf-8")) try: cls = Class.objects.get(pk=data['class'], owner=request.user.userprofile) except (Class.DoesNotExist, KeyError): return render_json(request, { 'error': _('Class with given id not found.'), 'error_type': 'class_not_found', }, template='class_create_student.html', status=404) if 'first_name' not in data or not data['first_name']: return render_json(request, { 'error': _('First name code is missing.'), 'error_type': 'missing_first_name' }, template='class_create_student.html', status=400) user = User(first_name=data['first_name']) if data.get('last_name'): user.last_name = data['last_name'] if data.get('email'): if User.objects.filter(email=data['email']).exists(): return render_json(request, { 'error': _('There is already a user with the given e-mail.'), 'error_type': 'email_exists' }, template='class_create_student.html', status=400) user.email = data['email'] if data.get('username'): if User.objects.filter(username=data['username']).exists(): return render_json(request, { 'error': _('There is already a user with the given username.'), 'error_type': 'username_exists' }, template='class_create_student.html', status=400) user.username = data['username'] else: user.username = get_unused_username(user) if data.get('password'): user.set_password(data['password']) user.save() cls.members.add(user.userprofile) return render_json(request, user.userprofile.to_json(nested=True), template='class_create_student.html', status=201) else: return HttpResponseBadRequest("method %s is not allowed".format(request.method))
def create_student(request): """ Create new user in class POST parameters (JSON): class: id of the class username (optional): username of student, if not provided username is create based on name password (optional): password of student first_name: first_name of student last_name (optional): last_name of student email (optional): e-mail of student """ if not get_config('proso_user', 'allow_create_students', default=False): return render_json(request, { 'error': _('Creation of new users is not allowed.'), 'error_type': 'student_creation_not_allowed' }, template='class_create_student.html', help_text=create_student.__doc__, status=403) if request.method == 'GET': return render(request, 'class_create_student.html', {}, help_text=create_student.__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='class_create_student.html', status=401) data = json_body(request.body.decode("utf-8")) try: cls = Class.objects.get(pk=data['class'], owner=request.user.userprofile) except (Class.DoesNotExist, KeyError): return render_json(request, { 'error': _('Class with given id not found.'), 'error_type': 'class_not_found', }, template='class_create_student.html', status=404) if 'first_name' not in data or not data['first_name']: return render_json(request, { 'error': _('First name code is missing.'), 'error_type': 'missing_first_name' }, template='class_create_student.html', status=400) user = User(first_name=data['first_name']) if data.get('last_name'): user.last_name = data['last_name'] if data.get('email'): if User.objects.filter(email=data['email']).exists(): return render_json(request, { 'error': _('There is already a user with the given e-mail.'), 'error_type': 'email_exists' }, template='class_create_student.html', status=400) user.email = data['email'] if data.get('username'): if User.objects.filter(username=data['username']).exists(): return render_json(request, { 'error': _('There is already a user with the given username.'), 'error_type': 'username_exists' }, template='class_create_student.html', status=400) user.username = data['username'] else: user.username = get_unused_username(user) if data.get('password'): user.set_password(data['password']) user.save() cls.members.add(user.userprofile) return render_json(request, user.userprofile.to_json(nested=True), template='class_create_student.html', status=201) else: return HttpResponseBadRequest("method %s is not allowed".format( request.method))