コード例 #1
0
def ws_message(message):
    # Send to all clients editing the topology
    channels.Group("topology-%s" % message.channel_session['topology_id']).send({"text": message['text']})
    # Send to networking_events handler
    networking_events_dispatcher.handle({"text": message['text'],
                                         "topology": message.channel_session['topology_id'],
                                         "client": message.channel_session['client_id']})
コード例 #2
0
def advance_participant(participant):
    p = participant
    unvisited_participants = []
    if p._index_in_pages == 0:
        unvisited_participants.append(p)
        client.get(p._start_url(), follow=True)

    if unvisited_participants:
        return

    try:
        if p._current_form_page_url:
            resp = client.post(p._current_form_page_url,
                               data={
                                   constants_internal.timeout_happened:
                                   True,
                                   constants_internal.admin_secret_code:
                                   ADMIN_SECRET_CODE
                               },
                               follow=True)
        else:
            resp = client.get(p._start_url(), follow=True)
    except:
        logging.exception("Failed to advance participant.")
        raise

    assert resp.status_code < 400
    channels.Group('auto-advance-{}'.format(p.code)).send(
        {'text': json.dumps({'auto_advanced': True})})
コード例 #3
0
    def advance_last_place_participants(self):

        participants = self.get_participants()

        # in case some participants haven't started
        unvisited_participants = []
        for p in participants:
            if p._index_in_pages == 0:
                unvisited_participants.append(p)
                client.get(p._start_url(), follow=True)

        if unvisited_participants:
            # that's it -- just visit the start URL, advancing by 1
            return

        last_place_page_index = min([p._index_in_pages for p in participants])
        last_place_participants = [
            p for p in participants
            if p._index_in_pages == last_place_page_index
        ]

        for p in last_place_participants:
            try:
                current_form_page_url = p._current_form_page_url
                if current_form_page_url:
                    resp = client.post(
                        current_form_page_url,
                        data={
                            constants_internal.timeout_happened: True,
                            constants_internal.admin_secret_code:
                            ADMIN_SECRET_CODE
                        },
                        follow=True)
                    # not sure why, but many users are getting HttpResponseNotFound
                    if resp.status_code >= 400:
                        msg = ('Submitting page {} failed, '
                               'returned HTTP status code {}.'.format(
                                   current_form_page_url, resp.status_code))
                        content = resp.content
                        if len(content) < 600:
                            msg += ' response content: {}'.format(content)
                        raise AssertionError(msg)

                else:
                    # it's possible that the slowest user is on a wait page,
                    # especially if their browser is closed.
                    # because they were waiting for another user who then
                    # advanced past the wait page, but they were never
                    # advanced themselves.
                    start_url = p._start_url()
                    resp = client.get(start_url, follow=True)
            except:
                logging.exception("Failed to advance participants.")
                raise

            # do the auto-advancing here,
            # rather than in increment_index_in_pages,
            # because it's only needed here.
            channels.Group('auto-advance-{}'.format(p.code)).send(
                {'text': json.dumps({'auto_advanced': True})})
コード例 #4
0
    def send_completion_message(self, participant_pk_set):

        if otree.common_internal.USE_REDIS:
            # only necessary to submit if next page has a timeout
            # or if it is a wait page
            player_lookup = self.participant.future_player_lookup(
                pages_ahead=1)
            if player_lookup:
                PageClass = get_view_from_url(player_lookup.url)
                if (issubclass(PageClass, InGameWaitPageMixin)
                        or PageClass.has_timeout()):
                    otree.timeout.tasks.ensure_pages_visited.schedule(kwargs={
                        'participant_pk_set':
                        participant_pk_set,
                        'wait_page_index':
                        self._index_in_pages
                    },
                                                                      delay=10)

        # _group_or_subsession might be deleted
        # in after_all_players_arrive, but it won't delete the cached model
        channels_group_name = self.get_channels_group_name()

        channels.Group(channels_group_name).send(
            {'text': json.dumps({'status': 'ready'})})
コード例 #5
0
ファイル: views.py プロジェクト: chapkovski/another-custom-wp
 def before_next_page(self):
     # we get the list of those players who are not last ones
     not_last_ones = [
         p for p in self.subsession.get_players() if p.last_one == False
     ]
     if len(self.subsession.get_players()) - 1 > len(not_last_ones):
         self.player.last_one = False
     else:
         # if this player is the last one in session...
         self.player.last_one = True
         # we set session level var to True so other players arriving to
         # app3.WaitPage later can go on immediately
         self.session.vars['gofurther'] = True
         # somehow the status is not updated automatically via idmap
         # so do save()
         self.session.save()
         # we get the index of current WaitPage via session.vars
         # (it is set by players arriving to app3.WaitPage)
         cur_wp_index = self.session.vars.get('wp_index')
         # if someone has already arrived the index is set and we
         # can get channel name using index and current session pk
         if cur_wp_index:
             curch = chname(self.session.pk, cur_wp_index)
             channels.Group(curch).send(
                 {'text': json.dumps({'status': 'ready'})})
コード例 #6
0
ファイル: views.py プロジェクト: starzia/otree-survey
    def before_next_page(self):
        # we get the list of those players who are already ahead of me
        already_passed = [p for p in self.player.get_others_in_subsession() if p.last_one == False]
        if len(already_passed) < len(self.player.get_others_in_subsession()):
            # this player is not the last one
            self.player.last_one = False
        else:
            # if this player is the last one in session...
            self.player.last_one = True

            # calculate payoffs
            self.group.set_payoffs()

            # we set session level var to True so other players arriving to
            # results.WaitPage later can go on immediately
            self.session.vars['two_thirds_all_done'] = True

            # send a message to other players who may be waiting on the results.TwoThirdsWaitPage
            wp_index = self.session.vars.get('two_thirds_wait_page_index')
            if wp_index:
                # for convenience, we use the "group_by_arrival_time" channel,
                # created by setting group_by_arrival_time = True in results.TwoThirdsWaitPage
                channel = channel_name(self.session.pk, wp_index)
                channels.Group(channel).send(
                    {'text': json.dumps({'status': 'ready'})}
                )
コード例 #7
0
 def run(self):
     request = self.args[0]
     page = request.path
     response = self.fn(*self.args, **self.kwargs)
     cache.set("page_{}".format(page), response.content, 12 * 60 * 60)
     channels.Group('render_page_{}'.format(
         urllib.parse.unquote(page).replace('/', '_').replace(
             '&', '_'))).send({'text': 'DONE'})
コード例 #8
0
ファイル: consumers.py プロジェクト: TheoVerhelst/DocHub
def get_pad(document_pk):
    group = channels.Group("pad" + str(document_pk))
    if not hasattr(group.channel_layer, "pads"):
        group.channel_layer.pads = {}
    pads = group.channel_layer.pads
    document = get_object_or_404(Document, pk=document_pk)
    data = document.original.read().decode("utf-8")
    return pads.setdefault(document_pk, pad_ns.Pad(data))
コード例 #9
0
    def _increment_index_in_pages(self):
        # when is this not the case?
        assert self._index_in_pages == self.participant._index_in_pages

        self._record_page_completion_time()
        # we should allow a user to move beyond the last page if it's mturk
        # also in general maybe we should show the 'out of sequence' page

        # the timeout record is irrelevant at this point, delete it
        # wait pages don't have a has_timeout attribute
        if hasattr(self, 'has_timeout') and self.has_timeout():
            PageTimeout.objects.filter(
                participant=self.participant,
                page_index=self.participant._index_in_pages).delete()
        # this is causing crashes because of the weird DB issue
        # ParticipantToPlayerLookup.objects.filter(
        #    participant=self.participant.pk,
        #    page_index=self.participant._index_in_pages).delete()

        # we skip any page that is a sequence page where is_displayed
        # evaluates to False to eliminate unnecessary redirection

        for page_index in range(
                # go to max_page_index+2 because range() skips the last index
                # and it's possible to go to max_page_index + 1 (OutOfRange)
                self._index_in_pages + 1,
                self.participant._max_page_index + 2):
            self.participant._index_in_pages = page_index
            if page_index == self.participant._max_page_index + 1:
                # break and go to OutOfRangeNotification
                break
            url = self.participant._url_i_should_be_on()

            Page = get_view_from_url(url)
            page = Page()

            if not hasattr(page, 'is_displayed'):
                break

            page.set_attributes(self.participant)
            if page.is_displayed():
                break

            # if it's a wait page, record that they visited
            # but don't run after_all_players_arrive
            if hasattr(page, '_register_wait_page_visit'):
                completion = page._register_wait_page_visit()
                if completion:
                    participant_pk_set = set(
                        page._group_or_subsession.player_set.values_list(
                            'participant__pk', flat=True))
                    page.send_completion_message(participant_pk_set)

        channels.Group('auto-advance-{}'.format(self.participant.code)).send({
            'text':
            json.dumps(
                {'new_index_in_pages': self.participant._index_in_pages})
        })
コード例 #10
0
def ws_connect(message):
    if not message.user.is_authenticated():
        logger.error("Request user is not authenticated to use websocket.")
        message.reply_channel.send({"close": True})
        return
    else:
        message.reply_channel.send({"accept": True})

    data = urlparse.parse_qs(message.content['query_string'])
    inventory_id = parse_inventory_id(data)
    topology_ids = list(TopologyInventory.objects.filter(inventory_id=inventory_id).values_list('pk', flat=True))
    topology_id = None
    if len(topology_ids) > 0:
        topology_id = topology_ids[0]
    if topology_id is not None:
        topology = Topology.objects.get(pk=topology_id)
    else:
        topology = Topology(name="topology", scale=1.0, panX=0, panY=0)
        topology.save()
        TopologyInventory(inventory_id=inventory_id, topology_id=topology.pk).save()
    topology_id = topology.pk
    message.channel_session['topology_id'] = topology_id
    channels.Group("topology-%s" % topology_id).add(message.reply_channel)
    client = Client()
    client.save()
    message.channel_session['client_id'] = client.pk
    channels.Group("client-%s" % client.pk).add(message.reply_channel)
    message.reply_channel.send({"text": json.dumps(["id", client.pk])})
    message.reply_channel.send({"text": json.dumps(["topology_id", topology_id])})
    topology_data = transform_dict(dict(id='topology_id',
                                        name='name',
                                        panX='panX',
                                        panY='panY',
                                        scale='scale',
                                        link_id_seq='link_id_seq',
                                        device_id_seq='device_id_seq'), topology.__dict__)

    message.reply_channel.send({"text": json.dumps(["Topology", topology_data])})
    send_snapshot(message.reply_channel, topology_id)
コード例 #11
0
ファイル: session.py プロジェクト: dheavy/otree-core
    def advance_last_place_participants(self):

        participants = self.get_participants()

        # in case some participants haven't started
        unvisited_participants = []
        for p in participants:
            if p._index_in_pages == 0:
                unvisited_participants.append(p)
                client.get(p._start_url(), follow=True)

        if unvisited_participants:
            # that's it -- just visit the start URL, advancing by 1
            return

        last_place_page_index = min([p._index_in_pages for p in participants])
        last_place_participants = [
            p for p in participants
            if p._index_in_pages == last_place_page_index
        ]

        for p in last_place_participants:
            try:
                if p._current_form_page_url:
                    resp = client.post(
                        p._current_form_page_url,
                        data={
                            constants_internal.auto_submit: True,
                            constants_internal.admin_secret_code:
                            ADMIN_SECRET_CODE
                        },
                        follow=True)
                else:
                    # it's possible that the slowest user is on a wait page,
                    # especially if their browser is closed.
                    # because they were waiting for another user who then
                    # advanced past the wait page, but they were never
                    # advanced themselves.
                    resp = client.get(p._start_url(), follow=True)
            except:
                logging.exception("Failed to advance participants.")
                raise

            assert resp.status_code < 400

            # do the auto-advancing here,
            # rather than in increment_index_in_pages,
            # because it's only needed here.
            channels.Group('auto-advance-{}'.format(p.code)).send(
                {'text': json.dumps({'auto_advanced': True})})
コード例 #12
0
 def send_stream_group(self):
     """
     Sends a notification of us to our groups's stream.
     """
     data = {
         "id": str(self.id),
         "type": "thread",
         "num_messages": self.num_messages,
         "num_top_level_messages": self.num_top_level_messages,
     }
     channels.Group("stream-group-%s" % self.group.id).send({
         "content":
         json.dumps(data),
     })
コード例 #13
0
ファイル: abstract.py プロジェクト: dheavy/otree-core
    def send_completion_message(self, participant_pk_set):

        if otree.common_internal.USE_REDIS:
            # 2016-11-15: we used to only ensure the next page is visited
            # if the next page has a timeout, or if it's a wait page
            # but this is not reliable because next page might be skipped anyway,
            # and we don't know what page will actually be shown next to the user.
            otree.timeout.tasks.ensure_pages_visited.schedule(
                kwargs={'participant_pk_set': participant_pk_set}, delay=10)

        # _group_or_subsession might be deleted
        # in after_all_players_arrive, but it won't delete the cached model
        channels_group_name = self.get_channels_group_name()
        channels.Group(channels_group_name).send(
            {'text': json.dumps({'status': 'ready'})})
コード例 #14
0
 def receive(self, text=None, bytes=None, **kwargs):
     self.clean_kwargs()
     player = self.get_player()
     group = self.get_group()
     player.leave_auction()
     player.save()
     group.remaining_bidders()
     group.save()
     channels.Group(
         group.get_channel_group_name()
     ).send(
         {'text': json.dumps(
             {'num': group.num_in_auction,
              })}
     )
コード例 #15
0
ファイル: views.py プロジェクト: tanveerahmad1517/thiuff
def post(request):
    """
    Receives a chat message.
    """
    if request.POST.get("message"):
        channels.Group("stream-chat").send({
            "content":
            json.dumps({
                "type": "chat",
                "message": request.POST["message"],
                "author": request.POST.get("author", "anonymous"),
            }),
        })
        return JsonResponse({"posted": True})
    return redirect("/chat/")
コード例 #16
0
    def post(self, request, *args, **kwargs):
        num_participants = int(request.POST['num_participants'])
        session_config_name = request.POST['session_config_name']
        bot_case_number = int(request.POST['bot_case_number'])
        session = create_session(session_config_name=session_config_name,
                                 num_participants=num_participants,
                                 bot_case_number=bot_case_number,
                                 force_browser_bots=True)
        BrowserBotsLauncherSessionCode.objects.update_or_create(
            # i don't know why the update_or_create arg is called 'defaults'
            # because it will update even if the instance already exists
            # maybe for consistency with get_or_create
            defaults={'code': session.code})
        channels.Group('browser_bot_wait').send(
            {'text': json.dumps({'status': 'session_ready'})})

        return HttpResponse(session.code)
コード例 #17
0
ファイル: consumers.py プロジェクト: TheoVerhelst/DocHub
def chat_receive(message):
    """Handles a websocket message by saving it and broadcasting it to all
    connected users.

    Connected to "chat.receive".
    """
    # Save the message in the database
    group_slug = message.content['group']
    chatMessage = Message.objects.create(
        user=message.content['user'],
        group=get_object_or_404(catalog.models.Group, slug=group_slug),
        text=message.content['text']
    )
    # Escape the text before sending it, so that no XSS injection is possible
    # But we don't need to escape it before saving in database, since Django
    # escapes everything
    chatMessage.text = html.escape(chatMessage.text)
    # Send the message to the group (i.e. all users connected on the group chat)
    channels.Group("chat" + group_slug).send({'text': chatMessage.dump_json()})
コード例 #18
0
 def send_stream_thread(self):
     """
     Sends a notification of us to our thread's stream.
     """
     data = {
         "id": str(self.id),
         "thread_id": str(self.thread_id),
     }
     if self.parent:
         data['type'] = "reply"
         data['discussion_id'] = str(self.parent_id)
         data['html'] = htmlmin.minify(self.reply_html())
     else:
         data['type'] = "discussion"
         data['html'] = htmlmin.minify(self.discussion_html())
     channels.Group("stream-thread-%s" % self.thread.id).send({
         "content":
         json.dumps(data),
     })
コード例 #19
0
ファイル: views.py プロジェクト: dododedodonl/osiristue
def getCourses(courses, path):
    if type(courses) != list:
        return []
    API = OsirisApi()
    coursesinfo = []
    for i, course in enumerate(courses):
        info = API.course(course)
        if info is not None:
            for c in info:
                staff = c.pop('responsiblestaff')
                owner = c.pop('owner')
                c['teacher'] = staff['name']
                c['teachermail'] = staff['email']
                c['group'] = owner['group']
                coursesinfo.append(c)
            channels.Group('render_page_{}'.format(path.replace(
                '&', '_'))).send(
                    {'text': str(floor(((i + 1) / len(courses)) * 100))})

    return coursesinfo
コード例 #20
0
    def receive(self, content, multiplexer, **kwargs):
        # Subscribe user to kit measurement updates
        if "kit" not in content:
            multiplexer.send({"error": "Kit to subscribe to not given."})
            return

        try:
            kit = backend.models.Kit.objects.get(username=content['kit'])
            if not self.message.user.has_perm(
                    'backend.subscribe_to_kit_measurements_websocket', kit):
                multiplexer.send({
                    "error":
                    "Kit not found or you do not have access to it."
                })
                return

            channels.Group("kit-measurements-%s" % kit.username).add(
                multiplexer.reply_channel)
            multiplexer.send({"action": "subscribe", "kit": kit.username})
        except:
            multiplexer.send(
                {"error": "Kit not found or you do not have access to it."})
コード例 #21
0
ファイル: consumers.py プロジェクト: TheoVerhelst/DocHub
def get_user_group(user):
    return channels.Group("pad_user_" + user.netid)
コード例 #22
0
ファイル: consumers.py プロジェクト: TheoVerhelst/DocHub
def get_chat_from_message(message):
    """Returns the channel group to which this message belongs."""
    return channels.Group("chat" + message.channel_session['group'])
コード例 #23
0
ファイル: browser.py プロジェクト: shaf91/otree-core
def send_completion_message(*, session_code, participant_code):
    group_name = channel_utils.browser_bots_launcher_group(session_code)
    # don't need to put in JSON since it's just a participant code
    channels.Group(group_name).send({'text': participant_code})
コード例 #24
0
ファイル: models.py プロジェクト: tianzan/retention-signaling
def runEverySecond():
    if group_model_exists():
        # Groups are hidden started once all group members reach Wait
        invisible_wait_groups = Group.objects.filter(hidden_start=True)
        for g in invisible_wait_groups:
            if g.hidden_time_till > 0:
                g.hidden_time_till = g.hidden_time_till - 1
                g.save()
            else:
                g.start = True
                g.hidden_start = False
                g.save()

        active_wait_groups = Group.objects.filter(activated=False, start=True)
        for g in active_wait_groups:
            if g.time_till > 0:
                g.time_till = g.time_till - 1
                # Save commands are necessary for the database to change
                g.save()
                channels.Group(g.get_channel_group_name()).send({
                    'text':
                    json.dumps({
                        'started': True,
                        'activated': False,
                        'time_till': g.time_till,
                        'over': False,
                        'activate_exit': False,
                    })
                })
            if g.time_till == 0:
                # Group is activated once timer hits 0
                g.activated = True
                g.start = False
                g.price = g.start_price
                g.price_float = g.start_price
                g.save()
                channels.Group(g.get_channel_group_name()).send({
                    'text':
                    json.dumps({
                        'started': True,
                        'activated': True,
                        'time_till': g.time_till,
                        'activate_exit': True,
                        'over': False,
                    })
                })
        # The auction is live in activated groups
        activated_groups = Group.objects.filter(activated=True,
                                                auction_over=False)

        for g in activated_groups:
            g.remaining_bidders()
            g.save()
            if g.price < g.fH and g.num_in_auction > 1:
                g.price += g.increment_size
                g.save()
                channels.Group(g.get_channel_group_name()).send({
                    'text':
                    json.dumps({
                        'price': g.price,
                        'expense': g.price * g.group_quantity,
                        'num': g.num_in_auction,
                        'over': False,
                        'activated': True,
                        'activate_exit': False,
                        'started': True
                    })
                })
            if int(g.price) == g.fH or g.num_in_auction <= 1:
                g.auction_over = True
                g.save()
                channels.Group(g.get_channel_group_name()).send({
                    'text':
                    json.dumps({
                        'price': g.price,
                        'expense': g.price * g.group_quantity,
                        # Sometimes the incorrect number of remaining bidders is displayed for some reason
                        'num': g.num_in_auction,
                        'over': True,
                        'started': True,
                        'activated': True,
                        'activate_exit': False
                    })
                })
コード例 #25
0
 def send_completion_message(self):
     channels.Group('browser-bots-client-{}'.format(
         self.session.code)).send({'text': self.participant.code})
コード例 #26
0
ファイル: abstract.py プロジェクト: jpg75/otree-core
    def dispatch(self, request, *args, **kwargs):
        if self.wait_for_all_groups:
            self._group_or_subsession = self.subsession
        else:
            self._group_or_subsession = self.group
        if self._is_ready():
            return self._response_when_ready()
        # take a lock because we set "waiting for" list here
        with lock_on_this_code_path():
            unvisited_participants = self._tally_unvisited()
        if unvisited_participants:
            # only skip the wait page if there are still
            # unvisited participants. otherwise, you need to
            # mark the page as completed.
            # see _increment_index_in_pages, which needs to
            # handle this case also
            if not self.is_displayed():
                return self._response_when_ready()
            self.participant.is_on_wait_page = True
            return self._get_wait_page()
        else:
            try:
                if self.wait_for_all_groups:
                    completion = CompletedSubsessionWaitPage(
                        page_index=self._index_in_pages,
                        session_pk=self.session.pk)
                else:
                    completion = CompletedGroupWaitPage(
                        page_index=self._index_in_pages,
                        group_pk=self.group.pk,
                        session_pk=self.session.pk)
                completion.save()
            # if the record already exists
            # (enforced through unique_together)
            except django.db.IntegrityError:
                self.participant.is_on_wait_page = True
                return self._get_wait_page()
            try:
                # need to check this before deleting
                # reference to self.player
                is_displayed = self.is_displayed()

                # in case there is a timeout on the next page, we
                # should ensure the next pages are visited promptly
                # TODO: can we make this run only if next page is a
                # timeout page?
                # or if a player is auto playing.
                # we could instead make this request the current page
                # URL, but it's different for each player

                # _group_or_subsession might be deleted
                # in after_all_players_arrive, so calculate this first
                participant_pk_set = set([
                    p.participant.pk
                    for p in self._group_or_subsession.player_set.all()
                ])

                # _group_or_subsession might be deleted
                # in after_all_players_arrive, so calculate this first
                channels_group_name = self.channels_group_name()

                # block users from accessing self.player inside
                # after_all_players_arrive, because conceptually
                # there is no single player in this context
                # (method is executed once for the whole group)

                player = self.player
                del self.player

                # make sure we get the most up-to-date player objects
                # e.g. if they were queried in is_displayed(),
                # then they could be out of date
                # but don't delete the current player from cache
                # because we need it to be saved at the end
                import idmap.tls
                cache = getattr(idmap.tls._tls, 'idmap_cache', {})
                for p in list(cache.get(self.PlayerClass, {}).values()):
                    if p != player:
                        self.PlayerClass.flush_cached_instance(p)

                # if any player can skip the wait page,
                # then we shouldn't run after_all_players_arrive
                # because if some players are able to proceed to the next page
                # before after_all_players_arrive is run,
                # then after_all_players_arrive is probably not essential.
                # often, there are some wait pages that all players skip,
                # because they should only be shown in certain rounds.
                # maybe the fields that after_all_players_arrive depends on
                # are null
                # something to think about: ideally, should we check if
                # all players skipped, or any player skipped?
                # as a shortcut, we just check if is_displayed is true
                # for the last player.
                if is_displayed:
                    self.after_all_players_arrive()
            except Exception as e:
                completion.delete()
                raise e

            self.player = player

            if otree.common_internal.USE_REDIS:
                # 2015-07-27:
                #   why not check if the next page has_timeout?
                otree.timeout.tasks.ensure_pages_visited.schedule(kwargs={
                    'participant_pk_set':
                    participant_pk_set,
                    'wait_page_index':
                    self._index_in_pages,
                },
                                                                  delay=10)

            completion.after_all_players_arrive_run = True
            completion.save()

            # send a message to the channel to move forward
            # this should happen at the very end,
            channels.Group(channels_group_name).send(
                {'text': json.dumps({'status': 'ready'})})

            # we can assume it's ready because
            # even if it wasn't created, that means someone else
            # created it, and therefore that whole code block
            # finished executing (including the after_all_players_arrive)
            # inside the transaction
            return self._response_when_ready()
コード例 #27
0
ファイル: abstract.py プロジェクト: jpg75/otree-core
    def _increment_index_in_pages(self):
        # when is this not the case?
        assert self._index_in_pages == self.participant._index_in_pages

        self._record_page_completion_time()
        # we should allow a user to move beyond the last page if it's mturk
        # also in general maybe we should show the 'out of sequence' page

        # the timeout record is irrelevant at this point, delete it
        # wait pages don't have a has_timeout attribute
        if hasattr(self, 'has_timeout') and self.has_timeout():
            PageTimeout.objects.filter(
                participant_pk=self.participant.pk,
                page_index=self.participant._index_in_pages).delete()
        # this is causing crashes because of the weird DB issue
        # ParticipantToPlayerLookup.objects.filter(
        #    participant_pk=self.participant.pk,
        #    page_index=self.participant._index_in_pages).delete()

        # performance optimization:
        # we skip any page that is a sequence page where is_displayed
        # evaluates to False to eliminate unnecessary redirection
        views_module = otree.common_internal.get_views_module(
            self.subsession._meta.app_config.name)
        pages = views_module.page_sequence

        assert self.__class__ in pages
        pages_to_jump_by = 1
        indexes = list(range(self.player._index_in_game_pages + 1, len(pages)))
        for target_index in indexes:
            Page = pages[target_index]

            # FIXME: are there other attributes? should i do As_view,
            # or simulate the
            # request?
            page = Page()
            page.player = self.player
            page.group = self.group
            page.subsession = self.subsession
            page.session = self.session

            # don't skip wait pages
            # because the user has to pass through them
            # so we record that they visited
            if hasattr(Page, 'is_displayed') and not page.is_displayed():
                if hasattr(Page, '_tally_unvisited'):
                    page._index_in_pages = self._index_in_pages + pages_to_jump_by
                    if page.wait_for_all_groups:
                        page._group_or_subsession = self.subsession
                    else:
                        page._group_or_subsession = self.group
                    with lock_on_this_code_path():
                        unvisited_participants = page._tally_unvisited()
                    # don't count myself; i only need to visit this page
                    # if everybody else already passed it
                    unvisited_participants.discard(self.participant.id)
                    if not unvisited_participants:
                        # if it's the last person
                        # because they need to complete the wait page
                        # don't skip past the wait page
                        break
                pages_to_jump_by += 1
            else:
                break

        self.player._index_in_game_pages += pages_to_jump_by
        self.participant._index_in_pages += pages_to_jump_by

        channels.Group('auto-advance-{}'.format(self.participant.code)).send({
            'text':
            json.dumps(
                {'new_index_in_pages': self.participant._index_in_pages})
        })
コード例 #28
0
ファイル: consumers.py プロジェクト: TheoVerhelst/DocHub
def get_pad_group(document):
    """Returns the channel group to which this document belongs."""
    return channels.Group("pad" + document)
コード例 #29
0
ファイル: consumers.py プロジェクト: dododedodonl/osiristue
def waiting(message, page):
    message.reply_channel.send({'accept': True})
    channels.Group('render_page_{}'.format(page.replace('&', '_'))).add(
        message.reply_channel)
コード例 #30
0
def ws_disconnect(message):
    if 'topology_id' in message.channel_session:
        channels.Group("topology-%s" % message.channel_session['topology_id']).discard(message.reply_channel)