def dispatch(self, request, *args, **kwargs): participant_code = kwargs.pop(constants.participant_code) if otree.common_internal.USE_REDIS: lock = redis_lock.Lock( otree.common_internal.get_redis_conn(), participant_code, expire=60, auto_renewal=True ) else: lock = participant_lock(participant_code) with lock, otree.db.idmap.use_cache(): try: participant = Participant.objects.get( code=participant_code) except Participant.DoesNotExist: msg = ( "This user ({}) does not exist in the database. " "Maybe the database was recreated." ).format(participant_code) raise Http404(msg) # if the player tried to skip past a part of the subsession # (e.g. by typing in a future URL) # or if they hit the back button to a previous subsession # in the sequence. url_should_be_on = participant._url_i_should_be_on() if not self.request.path == url_should_be_on: return HttpResponseRedirect(url_should_be_on) self.set_attributes(participant) self.participant._current_page_name = self.__class__.__name__ response = super(FormPageOrInGameWaitPageMixin, self).dispatch( request, *args, **kwargs) self.participant._last_request_timestamp = time.time() # need to render the response before saving objects, # because the template might call a method that modifies # player/group/etc. if hasattr(response, 'render'): response.render() self.save_objects() if ( self.session.use_browser_bots and 'browser-bot-auto-submit' in response.content.decode( 'utf-8')): bot = EphemeralBrowserBot(self) bot.prepare_next_submit(response.content.decode('utf-8')) return response
def dispatch(self, request, *args, **kwargs): participant_code = kwargs.pop(constants.participant_code) if otree.common_internal.USE_REDIS: lock = redis_lock.Lock(otree.common_internal.get_redis_conn(), participant_code, expire=60, auto_renewal=True) else: lock = participant_lock(participant_code) with lock, otree.db.idmap.use_cache(): try: participant = Participant.objects.get(code=participant_code) except Participant.DoesNotExist: msg = ("This user ({}) does not exist in the database. " "Maybe the database was recreated." ).format(participant_code) raise Http404(msg) # if the player tried to skip past a part of the subsession # (e.g. by typing in a future URL) # or if they hit the back button to a previous subsession # in the sequence. url_should_be_on = participant._url_i_should_be_on() if not self.request.path == url_should_be_on: return HttpResponseRedirect(url_should_be_on) self.set_attributes(participant) self.participant._current_page_name = self.__class__.__name__ response = super(FormPageOrInGameWaitPageMixin, self).dispatch(request, *args, **kwargs) self.participant._last_request_timestamp = time.time() # need to render the response before saving objects, # because the template might call a method that modifies # player/group/etc. if hasattr(response, 'render'): response.render() self.save_objects() if (self.session.use_browser_bots and 'browser-bot-auto-submit' in response.content.decode('utf-8')): bot = EphemeralBrowserBot(self) bot.prepare_next_submit(response.content.decode('utf-8')) return response
def post(self, request, *args, **kwargs): self.object = self.get_object() if request.POST.get(constants.auto_submit): self.timeout_happened = True # for public API self._set_auto_submit_values() else: self.timeout_happened = False if self.session.use_browser_bots: bot = EphemeralBrowserBot(self) try: submission = bot.get_next_post_data() except StopIteration: bot.send_completion_message() return HttpResponse('Bot completed') else: post_data = dict(request.POST) post_data.update(submission) else: post_data = request.POST form = self.get_form(data=post_data, files=request.FILES, instance=self.object) is_bot = self.participant._is_bot if form.is_valid(): if is_bot and post_data.get('must_fail'): # clean up noise in post data post_data.pop('csrfmiddlewaretoken', None) post_data.pop('origin_url', None) post_data.pop('must_fail', None) raise AssertionError( 'Bot tried to submit intentionally invalid data with ' 'SubmissionMustFail, but it passed validation anyway:' ' {}.'.format(dict(post_data))) self.form = form self.object = form.save() else: if is_bot and not post_data.get('must_fail'): errors = [ "{}: {}".format(k, repr(v)) for k, v in form.errors.items() ] raise AssertionError( 'Bot submission failed form validation: {} ' 'Check your bot in tests.py, ' 'then create a new session.'.format(errors)) return self.form_invalid(form) self.before_next_page() if self.session.use_browser_bots: if self._index_in_pages == self.participant._max_page_index: bot = EphemeralBrowserBot(self) try: bot.prepare_next_submit(html='') submission = bot.get_next_post_data() except StopIteration: bot.send_completion_message() return HttpResponse('Bot completed') else: raise AssertionError( 'Finished the last page, ' 'but the bot is still trying ' 'to submit more data ({}).'.format(submission)) self._increment_index_in_pages() return self._redirect_to_page_the_user_should_be_on()
def post(self, request, *args, **kwargs): self.object = self.get_object() auto_submitted = request.POST.get(constants.auto_submit) # if the page doesn't have a timeout_seconds, only the timeoutworker # should be able to auto-submit it. # otherwise users could append auto_submit to the URL to skip pages has_secret_code = (request.POST.get( constants.admin_secret_code) == ADMIN_SECRET_CODE) if auto_submitted and (self.has_timeout() or has_secret_code): self.timeout_happened = True # for public API self._set_auto_submit_values() else: self.timeout_happened = False if self.session.use_browser_bots: bot = EphemeralBrowserBot(self) try: submission = bot.get_next_post_data() except StopIteration: bot.send_completion_message() return HttpResponse('Bot completed') else: # convert MultiValueKeyDict to regular dict # so that we can add entries to it in a simple way # before, we used dict(request.POST), but that caused # errors with BooleanFields with blank=True that were # submitted empty...it said [''] is not a valid value post_data = request.POST.dict() post_data.update(submission) else: post_data = request.POST form = self.get_form(data=post_data, files=request.FILES, instance=self.object) is_bot = self.participant._is_bot if form.is_valid(): if is_bot and post_data.get('must_fail'): raise AssertionError( 'Page "{}": Bot tried to submit intentionally invalid ' 'data with ' 'SubmissionMustFail, but it passed validation anyway:' ' {}.'.format(self.__class__.__name__, bot_prettify_post_data(post_data))) self.form = form self.object = form.save() else: if is_bot and not post_data.get('must_fail'): errors = [ "{}: {}".format(k, repr(v)) for k, v in form.errors.items() ] raise AssertionError( 'Page "{}": Bot submission failed form validation: {} ' 'Check your bot in tests.py, ' 'then create a new session. ' 'Data submitted was: {}'.format( self.__class__.__name__, errors, bot_prettify_post_data(post_data), )) return self.form_invalid(form) self.before_next_page() if self.session.use_browser_bots: if self._index_in_pages == self.participant._max_page_index: bot = EphemeralBrowserBot(self) try: bot.prepare_next_submit(html='') submission = bot.get_next_post_data() except StopIteration: bot.send_completion_message() return HttpResponse('Bot completed') else: raise AssertionError( 'Finished the last page, ' 'but the bot is still trying ' 'to submit more data ({}).'.format(submission)) self._increment_index_in_pages() return self._redirect_to_page_the_user_should_be_on()
def post(self, request, *args, **kwargs): self.object = self.get_object() if request.POST.get(constants.auto_submit): self.timeout_happened = True # for public API self._set_auto_submit_values() else: self.timeout_happened = False if self.session.use_browser_bots: bot = EphemeralBrowserBot(self) try: submission = bot.get_next_post_data() except StopIteration: bot.send_completion_message() return HttpResponse('Bot completed') else: post_data = dict(request.POST) post_data.update(submission) else: post_data = request.POST form = self.get_form( data=post_data, files=request.FILES, instance=self.object) is_bot = self.participant._is_bot if form.is_valid(): if is_bot and post_data.get('must_fail'): # clean up noise in post data post_data.pop('csrfmiddlewaretoken', None) post_data.pop('origin_url', None) post_data.pop('must_fail', None) raise AssertionError( 'Bot tried to submit intentionally invalid data with ' 'SubmissionMustFail, but it passed validation anyway:' ' {}.'.format(dict(post_data))) self.form = form self.object = form.save() else: if is_bot and not post_data.get('must_fail'): errors = [ "{}: {}".format(k, repr(v)) for k, v in form.errors.items()] raise AssertionError( 'Bot submission failed form validation: {} ' 'Check your bot in tests.py, ' 'then create a new session.'.format(errors)) return self.form_invalid(form) self.before_next_page() if self.session.use_browser_bots: if self._index_in_pages == self.participant._max_page_index: bot = EphemeralBrowserBot(self) try: bot.prepare_next_submit(html='') submission = bot.get_next_post_data() except StopIteration: bot.send_completion_message() return HttpResponse('Bot completed') else: raise AssertionError( 'Finished the last page, ' 'but the bot is still trying ' 'to submit more data ({}).'.format(submission) ) self._increment_index_in_pages() return self._redirect_to_page_the_user_should_be_on()
def post(self, request, *args, **kwargs): self.object = self.get_object() auto_submitted = request.POST.get(constants.auto_submit) # if the page doesn't have a timeout_seconds, only the timeoutworker # should be able to auto-submit it. # otherwise users could append auto_submit to the URL to skip pages has_secret_code = ( request.POST.get(constants.admin_secret_code) == ADMIN_SECRET_CODE) if auto_submitted and (self.has_timeout() or has_secret_code): self.timeout_happened = True # for public API self._set_auto_submit_values() else: self.timeout_happened = False if self.session.use_browser_bots: bot = EphemeralBrowserBot(self) try: submission = bot.get_next_post_data() except StopIteration: bot.send_completion_message() return HttpResponse('Bot completed') else: # convert MultiValueKeyDict to regular dict # so that we can add entries to it in a simple way # before, we used dict(request.POST), but that caused # errors with BooleanFields with blank=True that were # submitted empty...it said [''] is not a valid value post_data = request.POST.dict() post_data.update(submission) else: post_data = request.POST form = self.get_form( data=post_data, files=request.FILES, instance=self.object) is_bot = self.participant._is_bot if form.is_valid(): if is_bot and post_data.get('must_fail'): raise AssertionError( 'Page "{}": Bot tried to submit intentionally invalid ' 'data with ' 'SubmissionMustFail, but it passed validation anyway:' ' {}.'.format( self.__class__.__name__, bot_prettify_post_data(post_data))) self.form = form self.object = form.save() else: if is_bot and not post_data.get('must_fail'): errors = [ "{}: {}".format(k, repr(v)) for k, v in form.errors.items()] raise AssertionError( 'Page "{}": Bot submission failed form validation: {} ' 'Check your bot in tests.py, ' 'then create a new session. ' 'Data submitted was: {}'.format( self.__class__.__name__, errors, bot_prettify_post_data(post_data), )) return self.form_invalid(form) self.before_next_page() if self.session.use_browser_bots: if self._index_in_pages == self.participant._max_page_index: bot = EphemeralBrowserBot(self) try: bot.prepare_next_submit(html='') submission = bot.get_next_post_data() except StopIteration: bot.send_completion_message() return HttpResponse('Bot completed') else: raise AssertionError( 'Finished the last page, ' 'but the bot is still trying ' 'to submit more data ({}).'.format(submission) ) self._increment_index_in_pages() return self._redirect_to_page_the_user_should_be_on()