def create_session(message): group = Group(message['channels_group_name']) kwargs = message['kwargs'] # because it's launched through web UI kwargs['honor_browser_bots_config'] = True try: otree.session.create_session(**kwargs) except Exception as e: # full error message is printed to console (though sometimes not?) error_message = 'Failed to create session: "{}"'.format(e) traceback_str = traceback.format_exc() group.send({ 'text': json.dumps({ 'error': error_message, 'traceback': traceback_str, }) }) FailedSessionCreation.objects.create( pre_create_id=kwargs['_pre_create_id'], message=error_message[:FAILURE_MESSAGE_MAX_LENGTH], traceback=traceback_str) raise group.send({'text': json.dumps({'status': 'ready'})}) if 'room_name' in kwargs: Group(channels_room_participants_group_name(kwargs['room_name'])).send( {'text': json.dumps({'status': 'session_ready'})})
def send_data(message): """ Informs all site users and projector clients about changed data. """ collection_elements = CollectionElementList.from_channels_message(message) # Loop over all logged in site users and the anonymous user and send changed data. for user in itertools.chain(get_logged_in_users(), [AnonymousUser()]): channel = Group('user-{}'.format(user.id)) output = collection_elements.as_autoupdate_for_user(user) channel.send({'text': json.dumps(output)}) # Check whether broadcast is active at the moment and set the local # projector queryset. if config['projector_broadcast'] > 0: queryset = Projector.objects.filter(pk=config['projector_broadcast']) else: queryset = Projector.objects.all() # Loop over all projectors and send data that they need. for projector in queryset: output = [] for collection_element in collection_elements: if collection_element.is_deleted(): output.append(collection_element.as_autoupdate_for_projector()) else: for element in projector.get_collection_elements_required_for_this( collection_element): output.append(element.as_autoupdate_for_projector()) if output: if config['projector_broadcast'] > 0: Group('projector-all').send({'text': json.dumps(output)}) else: Group('projector-{}'.format(projector.pk)).send( {'text': json.dumps(output)})
def ws_message(message): '''Send a message via web sockets. Currently uses a group identified by notify-username. When a volume export form submission is received, the message is handed off to the volume-export channel, which is handled by :mod:`readux.books.consumers`. Otherwise, messages are routed to the user notification channel.''' # does this really need to be a group? can we just use the reply channel? notify = Group("notify-%s" % message.user.username) # check for volume export data (form submission) if 'volume_export' in message.content['text']: data = json.loads(message.content['text']) # parse_qs returns values as lists formdata = dict( (key, val[0]) for key, val in parse_qs(data['volume_export']).iteritems()) # breaking changes as of channels 1.0 # need to specify immediately=True to send messages before the consumer completes to the end Channel('volume-export').send( { # has to be json serializable, so send username rather than user 'user': message.user.username, 'formdata': formdata, # fixme: why is reply channel not automatically set? # 'reply_channel': message.reply_channel }, immediately=True) else: notify.send({ "text": "%s" % message.content['text'], }, immediately=True)
def send_data(message): """ Informs all users about changed data. The argument message has to be a dict with the keywords collection_string (string), pk (positive integer), id_deleted (boolean) and dispatch_uid (string). """ for access_permissions in BaseAccessPermissions.get_all(): if access_permissions.get_dispatch_uid() == message['dispatch_uid']: break else: raise ValueError('Invalid message. A valid dispatch_uid is missing.') if not message['is_deleted']: Model = get_model_from_collection_string(message['collection_string']) instance = Model.objects.get(pk=message['pk']) full_data = access_permissions.get_full_data(instance) # Loop over all logged in users and the anonymous user. for user in itertools.chain(get_logged_in_users(), [AnonymousUser()]): channel = Group('user-{}'.format(user.id)) output = { 'collection': message['collection_string'], 'id': instance.get_rest_pk(), 'action': 'deleted' if message['is_deleted'] else 'changed'} if not message['is_deleted']: data = access_permissions.get_restricted_data(full_data, user) if data is None: # There are no data for the user so he can't see the object. Skip him. continue output['data'] = data channel.send({'text': json.dumps(output)})
def __init__(self, owner): channel = ChannelGroup(owner.get_personal_channel_name()) channel.send({ 'text': json.dumps({'warning': 'You can not trade with yourself.'}) }) super().__init__('No trading with yourself')
def send_data(message): """ Informs all site users and projector clients about changed data. """ collection_elements = CollectionElementList.from_channels_message(message) # Loop over all logged in site users and the anonymous user and send changed data. for user in itertools.chain(get_logged_in_users(), [AnonymousUser()]): channel = Group('user-{}'.format(user.id)) output = collection_elements.as_autoupdate_for_user(user) channel.send({'text': json.dumps(output)}) # Check whether broadcast is active at the moment and set the local # projector queryset. if config['projector_broadcast'] > 0: queryset = Projector.objects.filter(pk=config['projector_broadcast']) else: queryset = Projector.objects.all() # Loop over all projectors and send data that they need. for projector in queryset: output = [] for collection_element in collection_elements: if collection_element.is_deleted(): output.append(collection_element.as_autoupdate_for_projector()) else: for element in projector.get_collection_elements_required_for_this(collection_element): output.append(element.as_autoupdate_for_projector()) if output: if config['projector_broadcast'] > 0: Group('projector-all').send( {'text': json.dumps(output)}) else: Group('projector-{}'.format(projector.pk)).send( {'text': json.dumps(output)})
def create_session(message): group = Group(message['channels_group_name']) kwargs = message['kwargs'] # because it's launched through web UI kwargs['honor_browser_bots_config'] = True try: otree.session.create_session(**kwargs) except Exception as e: # full error message is printed to console (though sometimes not?) error_message = ( 'Failed to create session: "{}" - ' 'For the full traceback, check the server logs.'.format( str(e))) group.send( {'text': json.dumps( {'error': error_message})} ) FailedSessionCreation.objects.create( pre_create_id=kwargs['_pre_create_id'], message=error_message[:FAILURE_MESSAGE_MAX_LENGTH] ) raise group.send( {'text': json.dumps( {'status': 'ready'})} ) if 'room_name' in kwargs: Group('room-participants-{}'.format(kwargs['room_name'])).send( {'text': json.dumps( {'status': 'session_ready'})} )
def ws_message(message): '''Send a message via web sockets. Currently uses a group identified by notify-username. When a volume export form submission is received, the message is handed off to the volume-export channel, which is handled by :mod:`readux.books.consumers`. Otherwise, messages are routed to the user notification channel.''' # does this really need to be a group? can we just use the reply channel? notify = Group("notify-%s" % message.user.username) # check for volume export data (form submission) if 'volume_export' in message.content['text']: data = json.loads(message.content['text']) # parse_qs returns values as lists formdata = dict((key, val[0]) for key, val in parse_qs(data['volume_export']).iteritems()) # breaking changes as of channels 1.0 # need to specify immediately=True to send messages before the consumer completes to the end Channel('volume-export').send({ # has to be json serializable, so send username rather than user 'user': message.user.username, 'formdata': formdata, # fixme: why is reply channel not automatically set? # 'reply_channel': message.reply_channel }, immediately=True) else: notify.send({ "text": "%s" % message.content['text'], }, immediately=True)
def ws_receive(message): print("In ws_receive") group = Group(message.channel_session['id']) message.reply_channel.send({'text': 'In ws_receive'}) group.send({ "text": message.content['text'], })
def broadcast_to_market(message, market_id=None): if market_id is None: market_id = message.market_id channel_group = CGroup(str(market_id)) json_msg = message if not isinstance(json_msg, str): json_msg = message.to_json() channel_group.send({"text": json_msg})
def send_knock(self, created=False): """ Send the knock in the associated channels Group """ knock = self.as_knock(created) if knock: gr = Group('knocker-{0}'.format(knock['language'])) gr.send({'text': json.dumps(knock)})
def __init__(self, owner): channel = ChannelGroup(owner.get_personal_channel_name()) channel.send({ 'text': json.dumps({ 'warning': 'You do not have not enough items to make this ask.' }) }) super().__init__('Not enough items to sell')
def chat_consumer(message): room = message.content['room'] text = message.content['message'] username = message.content['username'] ChatMessage.objects.create(room=room, message=message) data = json.dumps({'message': text, 'username': username}) group = Group('chat-%s' % room) group.send({'text': data})
class GroupStreamer(Streamer): def __init__(self): pass def prepare(self): from django.conf import settings from channels import Group self.group = Group(settings.TEMP_GROUP_NAME) def __call__(self, temperature): self.group.send({'text': self.format(temperature)})
def __init__(self, owner): channel = ChannelGroup(owner.get_personal_channel_name()) channel.send({ 'text': json.dumps({ 'warning': 'You need to make better bid.' ' Please increase your price.' }) }) super().__init__(' Please increase your price')
def __init__(self, owner): channel = ChannelGroup(owner.get_personal_channel_name()) channel.send({ 'text': json.dumps({ 'warning': 'You do not have enough funds to make this bid.' ' Please change the amount.' }) }) super().__init__('Not enough money to create a new bid of this amount')
def ws_message(message, post_pk): obj = json.loads(message.content['text']) group = Group('post-{}'.format(post_pk)) group.send({ 'text': json.dumps({ 'username': message.user.username, 'chat_text': obj['chat_text'], }), })
def connect_wait_for_session(message, pre_create_id): group = Group(channels_create_session_group_name(pre_create_id)) group.add(message.reply_channel) # in case message was sent before this web socket connects if Session.objects.filter(_pre_create_id=pre_create_id): group.send({'text': json.dumps({'status': 'ready'})}) elif FailedSessionCreation.objects.filter( pre_create_id=pre_create_id).exists(): group.send({ 'text': json.dumps( {'error': 'Failed to create session. Check the server logs.'}) })
def add_vote(self): self.votes = models.F('votes') + 1 self.save() # Broadcast update to the appropriate group channel_group = Group(self.question.get_channel_group_result()) data = self.question.to_dict() data.update({ 'action': 'update-results', }) channel_group.send({"text": json.dumps(data)})
def party_connected(message, party_id): if party_id != message.http_session['party_id']: raise Exception( f"Party ID mismatch: {party_id} != {message.channel_session['party_id']}" ) old_member_id = message.http_session.get('member_id') if old_member_id: try: member = PartyMember.objects.get(id=old_member_id) except: pass else: if member.nick: group = Group(f"party-{member.party.id}") group.send({ "text": json.dumps({ "action": "member_left", "channel": member.channel, "nick": member.nick }) }) group.discard(message.reply_channel) member.delete() message.http_session.delete('member_id') party = Party.objects.get(id=party_id) if party.members.count() >= 6: print("Too many members!") message.reply_channel.send({ "text": json.dumps({ "action": "goodbye", "message": "room_full" }) }) message.reply_channel.send({"close": True}) return member = PartyMember(party=party, channel=message.reply_channel.name) member.save() message.http_session['member_id'] = member.id message.http_session.save() message.reply_channel.send({"accept": True}) message.reply_channel.send({ "text": json.dumps({ "action": "hello", "channel": message.reply_channel.name }) })
def notify_subscribers(notifications, key): """ Notify all open channels about new notifications """ logger.debug("Broadcasting to subscribers") notification_type_ids = models.NotificationType.objects.values( 'key').filter(key=key) for notification_type in notification_type_ids: g = Group( settings.NOTIFICATION_CHANNEL.format( notification_key=notification_type['key'])) g.send({'text': 'new-notification'})
def post(self, request, channel_id, format=None): """ Send command+args+options to sushi chef daeamon hooked up for the channel. """ serializer = ChannelControlSerializer(data=request.data) if serializer.is_valid(): group = Group('control-' + channel_id) msg_dict = dict( command=serializer.data['command'], args=serializer.data['args'], options=serializer.data['options'], ) msg_text = json.dumps(msg_dict) group.send({'text': msg_text}) return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def connect_wait_for_session(message, pre_create_id): group = Group(channels_create_session_group_name(pre_create_id)) group.add(message.reply_channel) # in case message was sent before this web socket connects if Session.objects.filter(_pre_create_id=pre_create_id): group.send( {'text': json.dumps( {'status': 'ready'})} ) elif FailedSessionCreation.objects.filter( pre_create_id=pre_create_id ).exists(): group.send( {'text': json.dumps( {'error': 'Failed to create session. Check the server logs.'})} )
def chat_send(message): logging.debug("[Server] Received message:%s from:%s to:%s" % (message["message"], message.user.username, message["to"])) group = Group("room-%s" % message["to"]) final_msg = { 'from': message.user.id, 'username': message.user.username, 'to': int(message["to"]), 'message': message["message"], 'msg_type': MSG_TYPE_MESSAGE } group.send({"text": json.dumps(final_msg)}) to_user = User.objects.get(id=int(message['to'])) message.user.messages_sent.create(to_user=to_user, message=message['message'])
def data_entry_receive(message, game_id): game = Game.objects.get(pk=game_id) group = Group('data-entry-%s' % game_id) data = json.loads(message['text']) round_score, created = RoundScore.objects.get_or_create( score__game=game, score_id=data['score'], round_number=data['round'], defaults={'value': data['value']}, ) if not created: round_score.value = data['value'] round_score.save() group.send({ 'text': json.dumps({ 'data': _round_scores_for_game(game) }) })
def create_session(message): group = Group(message['channels_group_name']) kwargs = message['kwargs'] try: otree.session.create_session(**kwargs) except Exception as e: group.send({ 'text': json.dumps( # doesn't get shown because not yet localized {'error': 'Failed to create session. Check the server logs.'}) }) FailedSessionCreation(pre_create_id=kwargs['_pre_create_id']).save() raise e group.send({'text': json.dumps({'status': 'ready'})})
def task_using_websocket(user_http_session_key, start, end): name = 'session-{}'.format(user_http_session_key) group = Group(name) total = end - start for i in range(start, end): group.send({ 'text': json.dumps({ 'func': 'task_using_websocket', 'status': 'message from task_using_websocket #{}'.format(i), 'percent': 100 * i / total, }), }) time.sleep(0.3)
def notify_subscribers(notifications, key): """ Notify all open channels about new notifications """ logger.debug("Broadcasting to subscribers") notification_type_ids = models.NotificationType.objects.values('key').filter(key=key) for notification_type in notification_type_ids: g = Group( settings.NOTIFICATION_CHANNEL.format( notification_key=notification_type['key'] ) ) g.send( {'text': 'new-notification'} )
def create_session(message): group = Group(message['channels_group_name']) kwargs = message['kwargs'] try: session = otree.session.create_session(**kwargs) if message['use_browser_bots']: otree.bots.browser.initialize_session( session_pk=session.pk, case_number=None ) session.ready_for_browser = True session.save() except Exception as e: # full error message is printed to console (though sometimes not?) error_message = 'Failed to create session: "{}"'.format(e) traceback_str = traceback.format_exc() group.send( {'text': json.dumps( { 'error': error_message, 'traceback': traceback_str, })} ) FailedSessionCreation.objects.create( pre_create_id=kwargs['pre_create_id'], message=error_message[:FAILURE_MESSAGE_MAX_LENGTH], traceback=traceback_str ) raise group.send( {'text': json.dumps( {'status': 'ready'})} ) if 'room_name' in kwargs: Group(channel_utils.room_participants_group_name(kwargs['room_name'])).send( {'text': json.dumps( {'status': 'session_ready'})} )
def create_session(message): group = Group(message['channels_group_name']) kwargs = message['kwargs'] try: otree.session.create_session(**kwargs) except Exception as e: group.send( {'text': json.dumps( {'error': 'Failed to create session. Check the server logs.'})} ) FailedSessionCreation(pre_create_id=kwargs['_pre_create_id']).save() raise e group.send( {'text': json.dumps( {'status': 'ready'})} )
def ws_message(message): read = json.loads(message.content['text']) room_id = read['room'] room = ChatRoom.objects.get(pk=read['room']) author = ChatUser.objects.get(user=message.user) action_type = read["type"] group = Group("chat-%s" % room_id) if action_type == "message": send_message(room, author, read["msg"]) elif action_type == "open": open_room(room, author) elif action_type == "join": join(room, author, message.reply_channel) elif action_type == "leave": leave(room, author) elif room.is_creator(author) or room.is_admin(author): if action_type == "ban": chatuser = ChatUser.objects.get(pk=read["target"]) ban(room, author, chatuser) return elif action_type == "delete": ChatMessage.objects.get(pk=read["target"]).delete() group.send({ "text": json.dumps({ "type": "delete", "admin": message.user.username, "message": read["target"], "room": room_id }) }) elif action_type == "admin": chatuser = ChatUser.objects.get(pk=read["target"]) room.set_admin(chatuser) send_notify(room, "{} is now an admin".format(chatuser), chatuser) return
def send_log_stream(proc): stream = Group('stream') for line in iter(proc.stdout.readline, b''): line = line.decode('utf-8') stream.send( {"text": json.dumps({ 'code': Message.STREAM_OPENED, 'log': line })}) stream.send( {"text": json.dumps({ 'code': Message.STREAM_CLOSED, 'log': None })}) proc.stdout.close() proc.wait()
def create_session(message): group = Group(message['channels_group_name']) kwargs = message['kwargs'] try: otree.session.create_session(**kwargs) except Exception as e: error_message = 'Failed to create session: "{}" - Check the server logs'.format( str(e)) group.send( {'text': json.dumps( {'error': error_message})} ) FailedSessionCreation( pre_create_id=kwargs['_pre_create_id'], message=error_message[:FAILURE_MESSAGE_MAX_LENGTH] ).save() raise group.send({'text': json.dumps({'status': 'ready'})})
def post_save(cls, sender, instance, created, *args, **kwargs): employer, worker = instance.employer, instance.worker group = instance.group contract_parties = [employer, worker] if instance.worker: for p in contract_parties: p.matched = True p.save() p_group = ChannelGroup(p.get_personal_channel_name()) p_group.send({'text': json.dumps({ 'day_over': True, })}) group_channel = ChannelGroup(group.get_channel_group_name()) group_message = {} if not group.is_active(): group_message['day_over'] = True group_message['open_offers'] = group.get_active_offers_html() group_message['general_info'] = group.get_general_info_html() group_channel.send({'text': json.dumps(group_message)})
def connect_wait_for_session(message, pre_create_id): group = Group(channels_create_session_group_name(pre_create_id)) group.add(message.reply_channel) # in case message was sent before this web socket connects if Session.objects.filter(_pre_create_id=pre_create_id, ready=True): group.send( {'text': json.dumps( {'status': 'ready'})} ) else: failure = FailedSessionCreation.objects.filter( pre_create_id=pre_create_id ).first() if failure: group.send( {'text': json.dumps( {'error': failure.message, 'traceback': failure.traceback})} )
def connect_wait_for_session(message, pre_create_id): group = Group(channels_create_session_group_name(pre_create_id)) group.add(message.reply_channel) # in case message was sent before this web socket connects if Session.objects.filter(_pre_create_id=pre_create_id, ready=True): group.send( {'text': json.dumps( {'status': 'ready'})} ) else: failures = FailedSessionCreation.objects.filter( pre_create_id=pre_create_id ) if failures: failure = failures[0] group.send( {'text': json.dumps( {'error': failure.message})} )
def party_disconnected(message): if 'member_id' not in message.http_session: return try: PartyMember.objects.get(id=message.http_session['member_id']).delete() except PartyMember.DoesNotExist: print("No such party member.") message.http_session.delete('member_id') message.http_session.save() if 'nickname' not in message.http_session: return group = Group(f"party-{message.http_session['party_id']}") group.discard(message.reply_channel) group.send({ "text": json.dumps({ "action": "member_left", "channel": message.reply_channel.name, "nick": message.http_session['nickname'] }) })
def send_game_list(channel): games = Game.objects.filter(status__in=['Created', 'Started']) game_list = [] for game in games: state = cache.get(GAME + str(game.id), new_state()) game_list.append({ 'id': game.id, 'name': game.name, 'level': game.level, 'players_num': game.players_num, 'players': state['players'] }) if isinstance(channel, str): channel = Group(channel) channel.send({ 'text': json.dumps({ 'game_list': game_list, }) })
def broadcast(message_type, message_schemas=message_schemas, **kwargs): """ broadcast via channel layer """ event_fields = message_schemas.get(message_type) if event_fields is None: raise Exception('unknown broadcast event: %s in message %s' % (message_type, kwargs)) message = {} message['type'] = message_type for key, value_type in event_fields.items(): value = kwargs.get(key) if value is None: raise ValueError('key: %s is none in broadcast message: %s' % (key, kwargs)) elif not isinstance(value, value_type): value = value_type(value) message[key] = value message = json.dumps(message) market_id = kwargs.get('market_id') if market_id is None: raise ValueError('market id is None: %s' % kwargs) channel_group = CGroup(str(market_id)) channel_group.send({"text": message})
def create_session(message): group = Group(message['channels_group_name']) kwargs = message['kwargs'] # because it's launched through web UI kwargs['honor_browser_bots_config'] = True try: otree.session.create_session(**kwargs) except Exception as e: # full error message is printed to console (though sometimes not?) error_message = 'Failed to create session: "{}"'.format(e) traceback_str = traceback.format_exc() group.send( {'text': json.dumps( { 'error': error_message, 'traceback': traceback_str, })} ) FailedSessionCreation.objects.create( pre_create_id=kwargs['pre_create_id'], message=error_message[:FAILURE_MESSAGE_MAX_LENGTH], traceback=traceback_str ) raise group.send( {'text': json.dumps( {'status': 'ready'})} ) if 'room_name' in kwargs: Group(channel_utils.room_participants_group_name(kwargs['room_name'])).send( {'text': json.dumps( {'status': 'session_ready'})} )
def connect_waiter(message): # When the phone number progress websocket connects # we need to check if the task already finnished by # the time the WS connected. task_id = message.http_session['active_phone_number_task_id'] task = AsyncResult(task_id) # If that's the case, send back an already done message if task.ready(): content = json.dumps({'success': True, 'msg': 'already done'}) message.reply_channel.send({'text': content}) else: group = Group("phone_verify-%s" % message.user.username) group.add(message.reply_channel) content = json.dumps({ 'sending': True, }) # Send currently in progress message group.send({'text': content})
def chat_receive(msg): if not msg.user.is_authenticated(): # TODO return data = json.loads(msg.content['text']) pprint(data) tag = data['tag'] room = data['data']['room'] group = Group('chat-' + room) if tag == 'send': group.add(msg.reply_channel) group.send({ 'text': json.dumps({ 'user': msg.user.player.id, 'room': room, 'msg': data['data']['msg'], }), }) elif tag == 'subscribe': if data['data']['yes']: group.add(msg.reply_channel) else: group.discard(msg.reply_channel)
def ws_connect(message, room): g = Group('chat:{}'.format(room)) data = {'text': 'A new user connected', 'type': 'log'} g.send({'text': json.dumps(data)}) g.add(message.reply_channel)
def send_message_to_group(message, group_name): """Send message to a group.""" assert isinstance(message, dict), "message must be a dict instance." group = Group(group_name) group.send(message)
def ws_disconnect(message, room): g = Group('chat:{}'.format(room)) g.discard(message.reply_channel) data = {'text': 'A user disconnected', 'type': 'log'} g.send({'text': json.dumps(data)})