async def write_tcp_connection(
    host: str,
    port: int,
    token: str,
    sending_queue: asyncio.Queue,
    status_queue: asyncio.Queue,
    watchdog_queue: asyncio.Queue
) -> None:
    async with manage_status(status_queue, gui.SendingConnectionStateChanged):
        async with open_connection(host, port) as connection:
            reader, writer = connection

            watchdog_queue.put_nowait('Prompt before auth')
            recieved_data = await authorise(token, writer, reader)
            watchdog_queue.put_nowait('Authorization done')
            if not recieved_data:
                raise InvalidToken('Проверьте токен, сервер его не узнал.')

            await reader.readuntil(b'\n')
            event = gui.NicknameReceived(recieved_data['nickname'])
            status_queue.put_nowait(event)
            
            while True:
                message = await sending_queue.get()
                await submit_message(writer, message)
                watchdog_queue.put_nowait('Message sent')
示例#2
0
async def handle_connection(host, reader_port, writer_port, history, token,
                            queues):
    while True:
        try:
            async with mc.get_connection(host, writer_port, history,
                                         queues) as streams:
                async with timeout(CONNECTION_TIMEOUT):
                    is_authorized, account_info = await mc.authorise(
                        *streams, token)
                    if not is_authorized:
                        messagebox.showerror(
                            'Неизвестный токен',
                            'Проверьте токен или зарегистрируйте заново.')
                        raise InvalidToken
                    event = gui.NicknameReceived(account_info['nickname'])
                    queues['status_updates_queue'].put_nowait(event)

                async with utils.create_handy_nursery() as nursery:
                    nursery.start_soon(
                        mc.restore_history(history, queues['messages_queue']))
                    nursery.start_soon(
                        read_msgs(host, reader_port, history, queues))
                    nursery.start_soon(send_msgs(*streams, queues))
                    nursery.start_soon(
                        watch_for_connection(queues["watchdog_queue"]))
                    nursery.start_soon(
                        ping_pong(*streams, queues["watchdog_queue"]))

        except (ConnectionRefusedError, ConnectionResetError, ConnectionError,
                asyncio.TimeoutError):
            continue
        else:
            break
示例#3
0
async def send_msgs(host: str, port: int, token: Token,
                    sending_queue: asyncio.Queue, status_queue: asyncio.Queue,
                    watchdog_queue: asyncio.Queue) -> None:
    authorized = False
    async with connect(
            host=host,
            port=port,
            status_queue=status_queue,
            connect_state_mode=gui.SendingConnectionStateChanged) as (reader,
                                                                      writer):

        if not token.is_exist:
            status_queue.put_nowait(gui.SendingConnectionStateChanged.CLOSED)
            token.value, user = await registration(reader, writer)
            status_queue.put_nowait(
                gui.SendingConnectionStateChanged.INITIATED)
            authorized = True
        await watchdog_queue.put(WatchdogSwitcher.ENABLE)

        if not authorized:
            await watchdog_queue.put("Prompt before auth")
            user = await authorise(reader, writer, token.value)

        await status_queue.put(gui.NicknameReceived(user))
        await watchdog_queue.put("Authorization done")
        status_queue.put_nowait(gui.SendingConnectionStateChanged.ESTABLISHED)

        async with create_handy_nursery() as nursery:
            nursery.start_soon(
                send_message(writer=writer,
                             sending_queue=sending_queue,
                             watchdog_queue=watchdog_queue))
            nursery.start_soon(ping_pong(reader, writer, watchdog_queue))
示例#4
0
async def handle_connection(queues, account_hash):
    while True:
        queues['watchdog'].put_nowait('Connection is alive. Source: Prompt before auth')

        async with open_asyncio_connection(HOST, WRITE_PORT) as rw_descriptor:

            reader, writer = rw_descriptor

            await reader.readline()

            try:
                account_dict = await authorise(reader, writer, account_hash)
            except InvalidToken:
                messagebox.showinfo("Ошибка авторизации", "Проверьте токен, сервер его не узнал.")

        queues['watchdog'].put_nowait('Connection is alive. Source: Authorization done')

        queues['messages'].put_nowait('Выполнена авторизация. Пользователь {}.\n'.format(account_dict['nickname']))

        loaded_messages = read_file(HISTORY_FILE)
        queues['messages'].put_nowait(loaded_messages)

        nickname = gui.NicknameReceived(account_dict['nickname'])
        queues['status_updates'].put_nowait(nickname)

        async with anyio.create_task_group() as tg:

            await tg.spawn(read_msgs, HOST, READ_PORT, queues)
            await tg.spawn(save_messages, HISTORY_FILE, queues['saving'])
            await tg.spawn(send_msgs, HOST, WRITE_PORT, queues, account_hash)
            await tg.spawn(watch_for_connection, queues['watchdog'])
            await tg.spawn(ping_pong, reader, writer)
async def handle_connection(host, ports, history, token, queues):
    read_port, write_port = ports
    while True:  # infinite loop to reconnect when ConnectionError occurred
        try:
            async with get_connection(host, write_port, queues) as streams:
                # set timeout for authorise/register procedure
                async with timeout(WATCH_CONNECTION_TIMEOUT):
                    token_is_valid, username = await authorise(*streams, token)
                    if not token_is_valid:
                        username = gui.msg_box(
                            "Invalid token",
                            "If you're registered user, please click "
                            '"Cancel" and check your .env file.\nIf you are the'
                            ' new one, enter yor name below and click "OK"',
                        )

                        if username == "":
                            main_logger.info("User left 'username' empty")
                            messagebox.showinfo(
                                "Invalid username",
                                "You entered empty 'username'. This is not "
                                "allowed. Program is going to terminate.",
                            )
                            raise UserInterrupt()

                        if username is None:
                            main_logger.info("User canceled 'username' input")
                            raise UserInterrupt()

                        await register(*streams, username)

                # Show received username in GUI
                queues["statuses"].put_nowait(gui.NicknameReceived(username))

                async with create_handy_nursery() as nursery:
                    nursery.start_soon(
                        read_messages(host, read_port, history, queues))

                    nursery.start_soon(send_messages(*streams, queues))

                    nursery.start_soon(watch_for_connection(
                        queues["watchdog"]))

                    nursery.start_soon(ping_pong(*streams, queues["watchdog"]))

        except (
                ConnectionRefusedError,
                ConnectionResetError,
                ConnectionError,
                asyncio.TimeoutError,
        ):
            # allow auto reconnection when ConnectionError or TimeoutError
            continue
        else:
            break
async def authorise(connection, token, watchdog_queue, status_updates_queue):
    await readline(connection.reader, watchdog_queue, 'Prompt before auth')
    await submit_message(connection.writer, token, watchdog_queue,
                         'Authorization token sent')
    text = await readline(connection.reader, watchdog_queue,
                          'Authorization done')
    json_data = json.loads(text)
    if not json_data:
        raise InvalidToken
    nickname = json_data['nickname']
    event = gui.NicknameReceived(nickname)
    status_updates_queue.put_nowait(event)
示例#7
0
async def authorize_and_send_msgs(host, port, token, sending_queue,
                                  status_updates_queue, watchdog_queue,
                                  ping_interval):
    reader, writer, json_answer = await authorize(host, port, token,
                                                  status_updates_queue,
                                                  watchdog_queue)
    nickname_update = gui.NicknameReceived(json_answer['nickname'])
    status_updates_queue.put_nowait(nickname_update)
    sender_lock = asyncio.Lock()
    async with create_handy_nursery() as nursery:
        nursery.start_soon(
            send_msgs(reader, writer, sending_queue, watchdog_queue,
                      sender_lock))
        nursery.start_soon(
            ping(reader, writer, ping_interval, watchdog_queue, sender_lock))
async def start_chat_process(stream_for_read, stream_for_write, token):
    authorisation_data = await authorise(stream_for_write, token)
    if not authorisation_data:
        broadcast_logger.info(f'NOT AUTORIZED WITH TOKEN "{token}"')
        raise InvalidTokenError
    _, _, nickname = authorisation_data
    event = gui.NicknameReceived(nickname)
    for _history in await load_log_from_file('chat_logs'):
        async_queues["messages_queue"].put_nowait(_history.strip())
    async_queues["status_updates_queue"].put_nowait(event)
    async_queues["watchdog_queue"].put_nowait(f"Connection is alive. Source: "
                                              f"Authorisation as {nickname}")
    async with create_handy_nursery() as nursery:
        nursery.start_soon(broadcast_chat(stream_for_read, stream_for_write))
        nursery.start_soon(send_message(stream_for_write))
        nursery.start_soon(save_history())
示例#9
0
async def authorise(token, reader, writer,
                    status_updates_queue: asyncio.Queue):
    logging.debug(decode_message(await reader.readline()))
    writer.write(f"{token}\n".encode())
    await writer.drain()
    response = json.loads(await reader.readline())
    if not response:
        logging.error("Unknown token. Check it, or register new user")
        return False
    logging.debug(response)
    nickname = response.get('nickname')
    if nickname:
        status_updates_queue.put_nowait(
            gui.NicknameReceived(response.get('nickname')))
    logging.debug(f"Выполнена авторизация. Пользователь {nickname}.")

    return True
示例#10
0
async def open_writer(host, port, token, sending_queue, status_updates_queue):
    while True:
        try:
            reader, writer = await asyncio.open_connection(host, port)
            status_updates_queue.put_nowait(
                gui.SendingConnectionStateChanged.ESTABLISHED)
            if await reader.readline():
                if token:
                    account_info = await authorize(reader, writer, token)
                    status_updates_queue.put_nowait(
                        gui.NicknameReceived(account_info['nickname']))
                await send_msgs(writer, sending_queue)
        except (asyncio.TimeoutError, ConnectionRefusedError, socket.gaierror):
            status_updates_queue.put_nowait(
                gui.SendingConnectionStateChanged.INITIATED)
            continue
        finally:
            writer.close()
示例#11
0
async def connect_to_receiver(host, port, status_updates_queue, user, token_file, token):
    logger = logging.getLogger('connect_to_receiver_logger')
    while True:
        try:
            reader, writer = await asyncio.open_connection(host=host, port=port)
            temp = await reader.readline()
            logger.debug(temp.decode("utf-8"))
            if not token:
                writer.write('\n'.encode())
                nickname = await register(reader, writer, user, token_file)
            else:
                nickname = await authorise(reader, writer, token)
            status_updates_queue.put_nowait(gui.SendingConnectionStateChanged.ESTABLISHED)
            status_updates_queue.put_nowait(gui.NicknameReceived(nickname))
            return writer
        except InvalidToken:
            logger.error('invalid token')
            messagebox.showinfo("Invalid token", "Please, check your token, or remove it, to get another one")
            raise
示例#12
0
 async def inner(host, port, account_hash, queue):
     status_queue = context[queues]['status_updates_queue']
     status_queue.put_nowait(gui.ReadConnectionStateChanged.INITIATED)
     status_queue.put_nowait(
         gui.SendingConnectionStateChanged.INITIATED)
     async with open_socket(host, int(port)) as socket_connection:
         if need_autorise:
             sending_queue = context[queues]['sending_queue']
             watchdog_queue = context[queues]['watchdog_queue']
             user_name = await autorise(socket_connection, account_hash)
             sending_queue.put_nowait(
                 f'Выполнена авторизация. Пользователь {user_name}.')
             status_queue.put_nowait(gui.NicknameReceived(user_name))
             status_queue.put_nowait(
                 gui.SendingConnectionStateChanged.ESTABLISHED)
             watchdog_queue.put_nowait('Authorization done')
         else:
             status_queue.put_nowait(
                 gui.ReadConnectionStateChanged.ESTABLISHED)
         await handle_msgs(socket_connection, queue)
示例#13
0
async def authorize_writer(token, reader, writer, status_updates_queue, watchdog_queue):
    """Proceed login dialog on server over reader, writer.

    And report statuses to status_updates_queue and watchdog_queue.
    """
    line = await reader.readline()
    decoded_line = line.decode()
    logger.debug('> %r', line)
    if not decoded_line.startswith(
            'Hello %username%! Enter your personal hash or leave it empty to create new account.\n'):
        raise utils.ProtocolError(f'wrong hello message {line!r}')

    watchdog_queue.put_nowait('Prompt before auth')

    token_message = f'{token}\n'
    logger.debug('< %r', token_message)
    writer.write(token_message.encode())
    await writer.drain()

    line = await reader.readline()
    login_response_json = line.decode()
    logger.debug('> %r', line)
    if not login_response_json.startswith('{') or token not in login_response_json:
        raise utils.WrongToken(f'cant login {line!r}')

    login_response = json.loads(login_response_json)

    line = await reader.readline()
    decoded_line = line.decode()
    logger.debug('> %r', decoded_line)
    if not decoded_line.startswith('Welcome to chat! Post your message below. End it with an empty line.\n'):
        raise utils.ProtocolError(f'wrong welcome message {line!r}')

    if login_response:
        nickname = login_response.get('nickname')
        logger.debug('Выполнена авторизация. Пользователь %r.', nickname)
        status_updates_queue.put_nowait(gui.NicknameReceived(nickname))
        watchdog_queue.put_nowait('Authorization done')
示例#14
0
async def handle_connection(host, port_to_read, port_to_write, token, filepath, queues):
    while True:
        # Open new stream.
        async with get_stream(host, port_to_write, queues, gui.SendingConnectionStateChanged.CLOSED) as (reader, writer):
            queues['watchdog'].put_nowait('Connection is alive. Prompt before auth')
            # Authorization.
            nickname = await auth(reader, writer, token, queues)
            queues['statuses'].put_nowait(gui.NicknameReceived(nickname))
            queues['messages'].put_nowait(
                'WELCOME BACK {}!\nLoading chat history and connectiong to chat '
                'in {} seconds...\n'.format(nickname, DELAY_TO_LOAD_HISTORY))
            await asyncio.sleep(DELAY_TO_LOAD_HISTORY)
            # Read chat history.
            async with AIOFile(filepath, 'a+') as afp:
                history = await afp.read()
                if history:
                    queues['messages'].put_nowait('*** CHAT HISTORY\n{}***\n'.format(history))
            # Run grandchildren tasks.
            async with create_handy_nursery() as nursery:
                nursery.start_soon(log_msgs(filepath, queues))
                nursery.start_soon(read_msgs(host, port_to_read, queues))
                nursery.start_soon(send_msgs(writer, queues))
                nursery.start_soon(watch_for_connection(queues))
                nursery.start_soon(ping_pong(reader, writer))