def message_send(token, channel_id, message): ''' Sends the message (str) by storing it in the channel with channel_id (int) and sender as user with token (str) Output: message_id (int) of message stored ''' # Retrieve data auth_user = user_with_token(token) channel = channel_with_id(channel_id) # Error check if auth_user is None: raise AccessError('Invalid token') elif channel is None: raise InputError('Invalid channel') elif auth_user not in channel.get_all_members(): raise AccessError('User not in channel') elif not message: raise InputError('Empty message not allowed') elif len(message) > 1000: raise InputError('Message should be 1000 characters or less') # Store message new_message = Message(auth_user, message, current_time()) channel.get_messages().append(new_message) bot_message_parser(token, channel_id, message) return { 'message_id': new_message.get_message_id(), }
def message_sendlater(token, channel_id, message, time_sent): ''' Send a message from authorised_user to the channel specified by channel_id automatically at a specified time in the future. Input: token (str), channel_id (int), message (str), time_sent (UNIX timestamp - float) Output: message_id (int) of message to be sent ''' # Retrieve data auth_user = user_with_token(token) channel = channel_with_id(channel_id) time_diff = time_sent - current_time() # Error check if auth_user is None: raise AccessError('Invalid token') elif channel is None: raise InputError('Invalid channel') elif auth_user not in channel.get_all_members(): raise AccessError('User not in channel') elif not message: raise InputError('Empty message not allowed') elif len(message) > 1000: raise InputError('Message should be 1000 characters or less') elif time_diff < 0: raise InputError('Time is in the past') # Note that message will still be sent later even if the user # leaves channel or logs out before message is actually sent new_message = Message(auth_user, message, time_created=time_sent) t = Timer(time_diff, channel.get_messages().append, args=[new_message]) t.start() return { 'message_id': new_message.get_message_id(), }
async def handle_message(message: str, user_id: UUID) -> Optional[Message]: try: message = Message(**json.loads(message)) except ValueError: return ErrorMessage(response_code=ResponseCode.BAD_REQUEST, data="Invalid message format") if message.type == MessageType.CREATE_ROOM.value: print(f"Creating room") new_room = Room(creator=user_id) rooms[new_room.id] = new_room print(f"Room {new_room.id} created") return Message(message_type=MessageType.CREATED, room_id=new_room.id) elif message.type == MessageType.JOIN_ROOM.value: print(f"Joining room {message.room_id}") if message.room_id not in rooms: return ErrorMessage(response_code=ResponseCode.NOT_FOUND, data=f"Room {message.room_id} does not exist") rooms[message.room_id].join(user_id) return Message(message_type=MessageType.JOINED, room_id=message.room_id) elif message.type == MessageType.MESSAGE.value: if message.room_id not in rooms: return ErrorMessage(response_code=ResponseCode.NOT_FOUND, data=f"Room {message.room_id} does not exist") print(f"Message sent to room {message.room_id}") response_message = json.dumps(Message(message_type=MessageType.MESSAGE, room_id=message.room_id, data=message.data).__dict__) for user_id in rooms[message.room_id].members: print(f"To: {user_id}") await connections[user_id].send(response_message) return None return ErrorMessage(response_code=ResponseCode.BAD_REQUEST, data=f"Unkown message_type {message.type}")
def updateChatMessages(self, username, msg, sended): print(self.active_users) for user in self.active_users: if sended: if user._username == username: user._chat.append(Message(self.username, self.get_timestamp(), msg)) else: if user._username == username: user._chat.append(Message(username, self.get_timestamp(), msg)) gui_dict = {"name":"chat", "data": user._chat} self.queue.put(gui_dict) print(gui_dict)
def connectTo(self, evt: wx.CommandEvent) -> None: dialog = wx.TextEntryDialog( parent=self, message='Insert server address (host:port)', caption='Connect to server', value=self.client.getAddress()) if dialog.ShowModal() == wx.ID_OK: pair: list[str] = dialog.GetValue().split(':') if len(pair) == 1: pair.append('20307') host, port = pair # check if host/port are empty and if they're valid if not ((not (host or port)) or self.client.CheckIsValid(host, port)): self.AppendStyled(f'invalid address "{host}:{port}"!', self.colors.FindColour('red')) else: self.Reset() self.client.setAddress(host, port) self.client.send( Message(self.username, f':CHGUNAME:{self.username}')) self.input.Enable() self.menus['disconnect'].Enable()
def standup_send(token, channel_id, message): ''' Send a message to get buffered in the standup queue, assuming a standup is currently active Input: token (str), channel_id (int), message (str) Output: empty dict ''' # Retrieve data auth_user = user_with_token(token) channel = channel_with_id(channel_id) # Error check if auth_user is None: raise AccessError('Invalid token') elif channel is None: raise InputError('Invalid channel') elif auth_user not in channel.get_all_members(): raise AccessError('User not member of channel') elif not channel.get_standup_status()['is_active']: raise InputError('An active standup is not currently running') elif not message: raise InputError('Empty message not allowed') elif len(message) > 1000: raise InputError('Message should be 1000 characters or less') # Add message to queue msg = Message(auth_user, message, time_created=current_time()) channel.get_standup_status()['queued_messages'].append(msg) return {}
async def Send(self, message: Message) -> None: if self.isAlive(): message = await self.ReplacePlaceholders(message) enc_message = message.toJson().encode('utf8') header = int.to_bytes(len(enc_message), length=4, byteorder='big') self.writer.write(header) self.writer.write(enc_message) await self.writer.drain()
def store_messages(self): for message_dict in self.messages_data: id = message_dict.get('id') sender_id = message_dict.get('sender_id') user_id = message_dict.get('user_id') sender_name = message_dict.get('name') favorite_count = len(message_dict.get('favorited_by')) created_at = message_dict.get('created_at') text = message_dict.get('text') attachment_num = 1 for attachment_dict in message_dict.get('attachments'): type = attachment_dict.get('type') attachment_url = attachment_dict.get('url', None) attachment = Attachment(message_id=id, attachment_num=attachment_num, type=type, attachment_url=attachment_url) try: self.db_session.add(attachment) except Exception as e: logger.error("Unable to insert into database") raise finally: self.db_session.close() attachment_num += 1 message = Message() message.id = id message.sender_id = sender_id message.user_id = user_id message.sender_name = sender_name message.favorite_count = favorite_count message.group_id = self.group_id message.created_at = created_at message.text = text try: self.db_session.add(message) self.db_session.commit() except Exception as e: logger.error("Unable to insert into database") raise finally: self.db_session.close() self.last_message_id = id
def send(self, msg: Message | str) -> None: if self._running: if isinstance(msg, str): msg = Message(self._uname, msg) msgRaw: bytes = msg.toJson().encode() header = int.to_bytes(len(msgRaw), 4, 'big') self._socket.send(header) self._socket.send(msgRaw)
async def HandleMessage(self, msg: Message): print(f'[{self.addr}] -> {msg}') # handle commands if msg.content.startswith(':'): await self.HandleCommand(msg) else: msg.content = f'[{self.username}] {msg.content}' await self.server.broadcast(msg, self)
async def HandleCommand(self, msg: Message): cmd = msg.content[1:].split(':') if cmd[0] == 'CHGUNAME': oldname = self.username self.username = cmd[1] if oldname == 'unregistered': await self.server.broadcast(msg=Message( 'system', f'{self.username} joined the server', time_ns()), sender=self) await self.Send( Message('system', f'joined "{self.server.getName()}"', time_ns())) await self.Send( Message('system', f'MOTD:\n{self.server.getMotd()}', time_ns())) else: await self.server.broadcast(msg=Message( 'system', f'{oldname} changed his name to {self.username}', time_ns()), sender=self) await self.Send( Message('system', 'changed name to {username}', time_ns())) elif cmd[0] == 'SSERVER': if self.permissions['shutdownServer']: raise KeyboardInterrupt else: await self.Send( Message('system', 'i\'m afraid i cannot do that, {username}.', time_ns())) else: await self.Send( Message('system', f'unknown command {cmd}', time_ns()))
def parse_buffer(self): msgs = [] while self.buffer != "": try: msg, rest = Message.deserialize(self.buffer) msgs.append(msg) self.buffer = rest except MessageIncomplete: break return msgs
async def InputLoop(self) -> None: while (self.isAlive() and (self.reader.exception() is None or isinstance(self.reader.exception(), ConnectionResetError))): size = int.from_bytes(await self.reader.read(4), 'big') msg = Message.fromJson((await self.reader.read(size)).decode('utf8')) await self.HandleMessage(msg) print(f'closed connection to [{self.addr}]') self._alive = False
def changeUsername(self, evt: wx.CommandEvent) -> None: dialog = wx.TextEntryDialog(parent=self, message='Insert new username', caption='Change username', value=self.username) if dialog.ShowModal() == wx.ID_OK: username = dialog.GetValue() if username == '': self.AppendStyled(f'invalid username "{username}"!', self.colors.FindColour('red')) else: self.username = username self.client.send( Message('system', f':CHGUNAME:{self.username}'))
def bot_send_message(channel, message, temporary): ''' Sends a message to a provided channel through the bot The message can be temporary ''' bot_user = bot_init() # Bot sends message to channel msg = Message(sender=bot_user, message=message, time_created=current_time()) channel.get_messages().append(msg) # Temporary message (automatically removes after 10 seconds) if temporary: t = Timer(5, channel.get_messages().remove, args=[msg]) t.start()
async def InputLoop(self) -> None: try: while self.isAlive(): async for msg in self.wsocket: assert isinstance( msg, str ), 'got invalid message in bytes from web client, wtf?' try: await self.HandleMessage(Message.fromJson(msg)) except JSONDecodeError as e: await self.wsocket.send( f'Expected JSON Message object, got {msg}: { util.getException(e) }' ) except ConnectionClosedError as e: print('CCE:', e) self._alive = False
def send_message(user_id, chat_id, text, is_system=False): check_user_in_chat(chat_id, user_id) session = db_session.create_session() message = Message(user_id=user_id, chat_id=chat_id, text=text, is_system=is_system) session.add(message) user = session.query(User).get(user_id) session.commit() notify_longpoll_requests({ 'type': 'new_message', 'text': message.text, 'user_id': user_id, 'chat_id': chat_id, 'username': user.username, 'is_system': is_system })
def _rcv(self) -> None: while self._running: # noinspection PyBroadException try: raw_size = self._socket.recv(4) except Exception: if self.ignoreErrors: continue elif self._running: self._running = False self._onClose() raise else: return size = int.from_bytes(raw_size, 'big') if size == 0: continue logger.info(f'incoming message size: {size}') self._messageCallback( Message.fromJson(self._socket.recv(size).decode()))
def str_to_message(raw_str) -> Message: res, match = None, R_MESSAGE.match(raw_str) if match: res = Message(*(match['sender'], match['channel'], match['msg'])) return res
def decode(self, raw): if raw == None: return None rtn = [] s = str(raw) if self.incompleteBuffer != None: s = self.incompleteBuffer + s; msgs = s.split(self.sMsgMarkerStart) for m in msgs: print(m) if len(m) == 0: continue if not(m.endswith(self.sMsgMarkerEnd)): self.incompleteBuffer = self.sMsgMarkerStart + m break else: self.incompleteBuffer = None print("--> m (size = " + str(len(m)) + "): " + m); hdr = m.split(self.sHeaderMarker) if len(hdr) != 2: print("Unexpected message format") return None size = int(hdr[0]) t = hdr[1] bd = t.split(self.sBodyMarker) if len(bd)!= 2: print('Unexpected message format (2)') return None header = bd[0] body = bd[1] body = body[0:len(body)-1] hparts = header.split(',') if len(hparts)!=5: print('Unexpected message format') return None bo = Message() bo.setType(hparts[0]) if len(hparts[1]) > 0: bo.setReceived(long(float(hparts[1]))) bo.setSource(hparts[1]) bodySize = int(hparts[4]) if bodySize != len(body): print("Body does not match checksum") return None bo.setPayload(body) print("--> h: " + header); print("--> b: " + body); rtn.append(bo) return rtn
def setUsername(self, uname: str) -> None: logger.info(f'changing username to {uname}') self._uname = uname self.send(Message('system', f':CHGUNAME:{uname}'))
def OnEnterPressed(self, evt: wx.CommandEvent) -> None: text = self.input.GetValue() self.client.send(Message(self.username, text, time())) self.chat.AppendText(f'[{self.username}] {text}\n') self.input.Clear()
async def ReplacePlaceholders(self, msg: Message) -> Message: msg.content = msg.content.format(username=self.username, time=datetime.now().strftime("%H:%M"), servername=self.server.getName()) return msg