Exemple #1
0
 def main_loop(self):
     presence_msg = JimMessage(action=PRESENCE, time=time.time())
     self.socket.send(bytes(presence_msg))
     presence_response_bytes = self.socket.recv(1024)
     presence_response = JimResponse.create_from_bytes(
         presence_response_bytes)
     if presence_response.response == OK:
         print('Связь с сервером установлена')
         if self.mode == 'r':
             while True:
                 message_bytes = self.socket.recv(1024)
                 jimmsg = JimMessage.create_from_bytes(message_bytes)
                 print(
                     'Вы получили от {} {} сообщеие'.format(
                         self.socket.fileno(), self.socket.getpeername()),
                     jimmsg.message)
         elif self.mode == 'w':
             while True:
                 message = input('Пошлите сообщение в никуда =')
                 msg = JimMessage(action=MSG,
                                  time=time.time(),
                                  encoding='utf-8',
                                  message=message)
                 self.socket.send(bytes(msg))
         else:
             raise WrongModeError(mode)
     elif presence_response.response == SERVER_ERROR:
         print('Ошибка сервера')
     elif presence_response.response == WRONG_REQUEST:
         print('Неверный запрос на сервер')
     else:
         print('Неверный код ответа от сервера')
Exemple #2
0
    def get_connection(self):
        try:
            conn, addr = self.socket.accept()
            presence_msg_bytes = conn.recv(1024)
            presence_msg = JimMessage.create_from_bytes(presence_msg_bytes)
            if presence_msg.action == PRESENCE:
                presence_response = JimResponse(**{RESPONSE: OK})
                conn.send(bytes(presence_response))
            else:
                presence_response = JimResponse(**{RESPONSE: WRONG_REQUEST})
                conn.send(bytes(presence_response))
        except OSError as e:
            pass
        else:
            print("Получен запрос на соединение от {}".format(str(addr)))
            self.clients.append(conn)
        finally:
            wait = 0
            read = []
            write = []
            try:
                read, write, e = select.select(self.clients, self.clients, [], wait)
            except:
                pass

            requests = self.read_requests(read)
            self.write_responses(requests, write)
Exemple #3
0
 def read_requests(self, read_clients):
     all_messages = []
     for sock in read_clients:
         try:
             bytemsg = sock.recv(1024)
             jimmsg = JimMessage.create_from_bytes(bytemsg)
             all_messages.append(jimmsg)
         except:
             print('Клиент {} {} отключился'.format(sock.fileno(), sock.getpeername()))
             self.clients.remove(sock)
     return all_messages
Exemple #4
0
 def send_message(self, to, text):
     # формируем сообщение
     message = JimMessage(**{
         ACTION: MSG,
         TO: to,
         FROM: self.name,
         MESSAGE: text,
         TIME: time.time()
     })
     # отправляем
     self.socket.send(bytes(message))
Exemple #5
0
    def send_presence(self):
        """Отправить сообщение о присутствии"""
        presence_msg = JimMessage(action=PRESENCE,
                                  time=time.time(),
                                  user={ACCOUNT_NAME: self.name})
        # переводим в байты и отправляем
        self.socket.send(bytes(presence_msg))

        # получаем ответ в байтах
        presence_response_bytes = self.socket.recv(1024)
        # создаем ответ из байт
        presence_response = JimResponse.create_from_bytes(
            presence_response_bytes)
        return presence_response
Exemple #6
0
 def del_contact(self, username):
     # формируем сообщение на добавления контакта
     message = JimMessage(action=DEL_CONATCT,
                          user_id=username,
                          time=time.time(),
                          user=self.name)
     # отправляем сообщение на сервер
     self.socket.send(bytes(message))
     # получаем ответ от сервера
     # получаем ответ из очереди
     # Формируем сообщение из байт
     jm = self.request_queue.get()
     if jm.response == OK:
         print('Контакт {} успешно удален'.format(username))
         # удаляем контакт из своей базы
         self.repo.del_contact(username)
         self.repo.commit()
Exemple #7
0
 def add_contact(self, username):
     # формируем сообщение на добавления контакта
     add_message = JimMessage(action=ADD_CONTACT,
                              user_id=username,
                              time=time.time(),
                              user=self.name)
     # отправляем сообщение на сервер
     self.socket.send(bytes(add_message))
     # получаем ответ от сервера
     # ответ получает слушатель, мы его получаем через очередь
     jm = self.request_queue.get()
     # Формируем сообщение из байт
     if jm.response == OK:
         print('Новый контакт {} успешно добавлен'.format(username))
         # Добавляем в свою базу контактов
         self.repo.add_contact(username)
         self.repo.commit()
Exemple #8
0
 def _get_connection(self):
     try:
         conn, addr = self.socket.accept()  # Проверка подключений
         # Должно прийти сообщение о присутствии
         presence_msg_bytes = conn.recv(1024)
         presence_msg = JimMessage.create_from_bytes(presence_msg_bytes)
         if presence_msg.action == PRESENCE:
             # Получаем имя пользователя
             client_name = presence_msg.user[ACCOUNT_NAME]
             print('К нам подключился {}'.format(client_name))
             # если клиента нету в базе
             if not self.repo.client_exists(client_name):
                 # мы его добавляем
                 print('Добавляем клиента')
                 self.repo.add_client(client_name)
                 print('Сохраняем')
                 self.repo.commit()
             # добавляем историю подключения
             self.repo.add_history(client_name, addr[0])
             self.repo.commit()
             # отправляем ответ
             presence_response = JimResponse(**{RESPONSE: OK})
             conn.sendall(bytes(presence_response))
         else:
             presence_response = JimResponse(**{RESPONSE: WRONG_REQUEST})
             conn.sendall(bytes(presence_response))
     except OSError as e:
         pass  # timeout вышел
     else:
         print("Получен запрос на соединение от %s" % str(addr))
         # Добавляем клиента в список
         self._clients.append(conn)
         # Добавляем в словарь имя клиента и соответствующий ему сокет
         # Мы это делаем, чтобы знать в будующем кому пересылать сообщение
         self.names[client_name] = conn
     finally:
         # Проверить наличие событий ввода-вывода
         wait = 0
         try:
             r, w, e = select.select(self._clients, self._clients, [], wait)
             requests = self._read_requests(r)  # Получаем входные сообщения
             self._write_responses(
                 requests)  # Выполним отправку входящих сообщений
         except:
             pass
Exemple #9
0
 def get_contacts(self):
     """Получить список контактов"""
     # формируем сообщение
     list_message = JimMessage(action=GET_CONTACTS,
                               time=time.time(),
                               user=self.name)
     # отправляем
     self.socket.send(bytes(list_message))
     # дальше слушатель получит ответ, который мы получим из очереди
     jm = self.request_queue.get()
     # если там правильный ответ
     if jm.response == ACCEPTED:
         # получаем следующее сообщение из очереди, там должен быть список контактов
         jm = self.request_queue.get()
         contact_list = jm.action
         # обновим контакты в базе
         self.repo.clear_contacts()
         for contact in contact_list:
             self.repo.add_contact(contact)
         self.repo.commit()
         return contact_list
Exemple #10
0
    def _read_requests(self, r_clients):
        """
        Чтение сообщений, которые будут посылать клиенты
        :param r_clients: клиенты которые могут отправлять сообщения
        :return: список сообщений
        """
        # Список входящих сообщений
        messages = []

        for sock in r_clients:
            # Получаем входящие сообщения
            bdata = sock.recv(2**20)
            if bdata:
                jm = JimMessage.create_from_bytes(bdata)
                # Добавляем в список пару сообщение и сокет который его прислал
                messages.append((jm, sock))
            else:
                print("Клиент отключился")
                sock.close()
                self._clients.remove(sock)

        # Возвращаем словарь сообщений
        return messages
Exemple #11
0
 def poll(self):
     self.is_alive = True
     while True:
         if not self.is_alive:
             break
         data = self.sock.recv(2**20)
         if data:
             try:
                 # Если нам пришло сообщение
                 jm = JimMessage.create_from_bytes(data)
                 # Если это message
                 if MESSAGE in jm:
                     # Печатаем в нормальном виде
                     self.process_message(jm)
                 else:
                     # Добавляем сообщение в очередь т.к. это серверное сообщение
                     self.request_queue.put(jm)
             except MandatoryKeyError:
                 # Если нам пришел ответ от сервера мы его добавляем в очередь для дальнейшей обработки
                 jr = JimResponse.create_from_bytes(data)
                 # При этом поток приостанавливается
                 self.request_queue.put(jr)
         else:
             break
Exemple #12
0
    def _write_responses(self, messages):
        """
        Теперь будем отправлять сообщения только конкретному пользователю
        """

        for message, sender in messages:
            # Теперь клиенты отправляют сообщения с разными ключами
            if message.action == ADD_CONTACT:
                # нужно добавить контакт клиенту
                # имя клиента
                client_username = message.user
                # имя контакта
                contact_username = message.user_id
                # сохраняем данные в базу
                try:
                    self.repo.add_contact(client_username, contact_username)
                    self.repo.commit()
                    response = JimResponse(**{RESPONSE: OK})
                except NoneClientError as e:
                    print('Такой клиент не найден')
                    response = JimResponse(**{RESPONSE: WRONG_REQUEST})
                finally:
                    # отправляем пока ответ всем
                    sender.sendall(bytes(response))
            elif message.action == DEL_CONTACT:
                # нужно добавить контакт клиенту
                # имя клиента
                client_username = message.user
                # имя контакта
                contact_username = message.user_id
                # сохраняем данные в базу
                self.repo.del_contact(client_username, contact_username)
                self.repo.commit()
                response = JimResponse(**{RESPONSE: OK})
                # отправляем пока ответ всем
                sender.sendall(bytes(response))
            elif message.action == GET_CONTACTS:
                # отдаем список контактов клиенту
                client_username = message.user
                # получаем список контактов
                contact_list = self.repo.get_contacts(client_username)
                # отправляем ответ что всё ок
                response = JimResponse(**{
                    RESPONSE: ACCEPTED,
                    QUANTITY: len(contact_list)
                })
                # отправляем пока ответ всем
                sender.sendall(bytes(response))
                # формируем второе сообщение со списком
                jm = JimMessage(action=contact_list, time=time.time())
                sender.sendall(bytes(jm))
            elif message.action == MSG:
                # получаем кому отправить сообщение
                to = message.to
                # на надо только переслать сообщение этому пользователю
                # получаем сокет по имени
                # можно даже обойти тут список контактов и отправлять напрямую
                sock = self.names[to]
                sock.sendall(bytes(message))
                # отвечам тому кто прислал сообщение что все хорошо
                sender.sendall(bytes(JimResponse(**{RESPONSE: ACCEPTED})))
            elif message.action == ADD_AVATAR:
                avatar_data = JimMessage.base64str_to_bytes(
                    message.avatar_data)
                self.repo.add_avatar(message.user, avatar_data)
                self.repo.commit()
                sender.sendall(bytes(JimResponse(**{RESPONSE: ACCEPTED})))
            elif message.action == GET_AVATAR:
                # отдаем список контактов клиенту
                client_username = message.user
                # получаем список контактов
                try:
                    avatar = self.repo.get_avatar(client_username)
                except NoneAvatarError:
                    # отправляем ответ что всё не ок
                    response = JimResponse(**{RESPONSE: WRONG_REQUEST})
                    sender.sendall(bytes(response))
                else:
                    response = JimResponse(**{RESPONSE: ACCEPTED})
                    # отправляем пока ответ всем
                    sender.sendall(bytes(response))
                    # формируем второе сообщение с аватаром
                    jm = JimMessage(
                        action=JimMessage.bytes_to_base64str(avatar),
                        time=time.time())
                    sender.sendall(bytes(jm))