Beispiel #1
0
    def thread_receiver_handle(self, dict_):
        try:
            action_ = dict_.get(ACTION)
            if action_ == MSG:
                chat_name = dict_[FROM]
                doc = dict_[MESSAGE]
                if self.selected_item_text == chat_name:
                    self.append_to_text(chat_name=chat_name, doc=doc)
                client.client_db.session.rollback()
                client.client_db.add_to_history(chat_name, time.ctime(), doc,
                                                False)
            elif action_ == IMG or action_ == IMG_PARTS:
                # print('Получили изображение')
                # print(dict_)
                img_msg = JIMMessage(dict_)
                img_worker = ImageWorker(client.sock, img_msg,
                                         client.img_parts)
                img_worker.handle(action_)
                if img_worker.whole_received_img and \
                   self.selected_item_text == img_worker.whole_received_img.get(USER_ID):

                    pixmap = self.image_out_of_byte(
                        PictureImage.base64_decode(
                            img_worker.whole_received_img.get(IMG)))
                    self.label.setPixmap(pixmap)
            elif action_ == PROBE:
                mute_.lock()
                client.m.create_presence_message(self.auth.user)
                client.m.send_rcv_message(client.sock)
                mute_.unlock()
        except Exception as e:
            print(e)
Beispiel #2
0
 def handle_request(self):
     if self.action == AUTH:
         self._auth_handle()
     elif self.action == MSG:
         self._msg_handle()
     elif self.action == PRESENCE:
         self._presence_handle()
     elif self.action == GET_CONTACTS:
         self._get_contacts_handle()
     elif self.action == GET_CONTACT_IMG:
         print('Запрос изображений')
         self._get_contact_img_handle()
     elif self.action == ADD_CONTACT:
         self._add_del_contact_handle()
     elif self.action == DEL_CONTACT:
         self._add_del_contact_handle(False)
     elif self.action == JOIN:
         self._join_handle()
     elif self.action == LEAVE:
         self._leave_handle()
     elif self.action == REGISTER:
         self._register_handle()
     elif self.action == IMG or self.action == IMG_PARTS:
         img_worker = ImageWorker(self.socket, self.message, self.img_parts)
         img_worker.handle(self.action)
         self._whole_message_check(img_worker)
     else:
         self.message.response_message_create(code=WRONG_REQUEST,
                                              send_message=False)
         self.transport.write(self.message.encoded_message)
Beispiel #3
0
 def _get_contact_img_handle(self):
     contact_name = self.message.dict_message[USER_ID]
     client = self.server_db.request_client(contact_name)
     if client:
         img = self.server_db.get_client_img(contact_name)
         img_message = JIMMessage()
         img_sender = ImageWorker(self.socket, img_message, self.img_parts)
         img_sender.img_send(img.img_base64, contact_name)
Beispiel #4
0
 def received_message_handle(self):
     if self.m_r.dict_message[ACTION] == MSG:
         self.client_db.session.rollback()
         self.client_db.add_to_history(self.m_r.dict_message[FROM], time.ctime(),
                                       self.m_r.dict_message[MESSAGE], False)
         print(self.m_r.dict_message)
         # queue.put(self.m_r.dict_message)
         self.m_r.clean_buffer()
     elif self.m_r.dict_message[ACTION] == IMG or self.m_r.dict_message[ACTION] == IMG_PARTS:
         img_receiver = ImageWorker(self.sock, self.m_r, self.img_parts)
         img_receiver.handle(self.m_r.dict_message[ACTION])
Beispiel #5
0
 def __init__(self, hostname='localhost', port=7777):
     self.def_hostname = hostname
     self.def_port = port
     # read_ и write_ нужны для проверки, если клиент был запущен из консоли только в одном режиме
     self._read = False
     self._write = False
     self.alive = True
     self.hostname, self.port = self._cli_param_get()
     self.username = ''
     self.client_db = None
     self.img_parts = {}
     self.m = JIMMessage()
     self.m_r = JIMResponse()
     self.sock = self.open_client_socket()
     self.img_sender = ImageWorker(self.sock, self.m, self.img_parts)
Beispiel #6
0
class Handler(Thread):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print('Инициализация')
        self.queue = input_q
        self.message = None
        self.action = None
        self.sock = None
        self.clients = None
        self.active = True
        self.img_worker = None
        self.img_parts = {}

    def _get_from_queue(self):
        item = self.queue.get()
        self.message = JIMResponse(item['text'])
        self.action = item['action']
        self.sock = item['sock']
        self.clients = item['clients']

    def handling_action(self):
        if self.action == PRESENCE:
            self._presence_handle()
        elif self.action == MSG:
            self._msg_handle()
        elif self.action == GET_CONTACTS:
            self._get_contacts_handle()
        elif self.action == GET_CONTACT_IMG:
            print('Запрос изображений')
        elif self.action == ADD_CONTACT:
            self._add_del_contact_handle()
        elif self.action == DEL_CONTACT:
            self._add_del_contact_handle(False)
        elif self.action == JOIN:
            self._join_handle()
        elif self.action == LEAVE:
            self._leave_handle()
        elif self.action == AUTH:
            self._auth_handle()
        elif self.action == REGISTER:
            self._register_handle()
        elif self.action == IMG or self.action == IMG_PARTS:
            self.img_worker = ImageWorker(self.sock, self.message, self.img_parts)
            self.img_worker.handle(self.action)
            self._whole_message_check()
        else:
            self.message.response_message_create(self.sock, WRONG_REQUEST)

    # TODO сделать проще... как можно восстановить сокет из fd?
    def _msg_handle(self):
        if '#' in self.message.dict_message[TO]:
            # print('chat')
            room = self.message.dict_message[TO][1:]
            contacts = server_db.get_room_members(room)
            for contact in contacts:
                if contact != self.message.dict_message[FROM]:
                    sockets = server_db.get_client_sockets(contact)
                    for sock_ in sockets:
                        for sock_online in self.clients:
                            if sock_ == sock_online.fileno():
                                self.message.send_message(sock_online)
        else:
            print(self.message.dict_message)
            sockets = server_db.get_client_sockets(self.message.dict_message[TO])
            for sock_ in sockets:
                for sock_online in self.clients:
                    if sock_ == sock_online.fileno():
                        self.message.send_message(sock_online)
                        print('Сообщение отправлено!')
            self.message.response_message_create(self.sock, OK)

    def _auth_handle(self):
        client_name = self.message.dict_message[USER][ACCOUNT_NAME]
        client = server_db.request_client(client_name)
        if client is None:
            self.message.response_message_create(self.sock, NOT_FOUND, message_text="Пользователь не существует")
        else:
            client_hash = self.message.dict_message[USER][PASSWORD]
            if client.hash[0].hashpass == client_hash:
                print('{} авторизован'.format(client_name))
                self.message.response_message_create(self.sock, OK)
            else:
                print('{} не авторизован'.format(client_name))
                self.message.response_message_create(self.sock, WRONG_COMBINATION, message_text='')

    def _register_handle(self):
        client_name = self.message.dict_message[USER][ACCOUNT_NAME]
        pswd = self.message.dict_message[USER][PASSWORD]
        # проверяем, если клиент с таким именем уже не зарегистрирован в нашем мессенджере
        client = server_db.request_client(client_name)
        if client is None:
            server_db.add_client(client_name, "Yep, i'm here")
            hash_ = get_safe_hash(pswd, SALT)
            print(hash_)
            server_db.register_new_hash(client_login=client_name, hash_=hash_)
            self.message.response_message_create(self.sock, OK)
        else:
            self.message.response_message_create(self.sock, code=CONFLICT, with_message=True,
                                                 message_text="Account is in use", send_message=True)

    def _leave_handle(self):
        room_name = self.message.dict_message[ROOM]
        client = server_db.ident_client_by_sockets(self.sock.fileno())
        room = server_db.request_room(room_name)
        if room and client:
            server_db.join_leave_room(room_name, client)
            self.message.response_message_create(self.sock, 200, True, 'Вы покинули чат')
        else:
            # print('Данной комнаты не существует')
            self.message.response_message_create(self.sock, 400, True, 'Данной комнаты не существует')

    def _join_handle(self):
        room_name = self.message.dict_message[ROOM]
        client = server_db.ident_client_by_sockets(self.sock.fileno())
        room = None
        while not room:
            room = server_db.request_room(room_name)
            if room:
                server_db.join_leave_room(room_name, client)
                self.message.response_message_create(self.sock, 200, True, 'Вы успешно присоединились к чату')
            else:
                server_db.add_room(room_name)

    def _presence_handle(self):
        username = self.message.dict_message[USER][ACCOUNT_NAME]
        client = server_db.request_client(username)
        if client is None:
            self.message.response_message_create(self.sock, NOT_FOUND, message_text='Пользователь не найден')
        else:
            server_db.add_to_history(username,
                                     self.message.dict_message[TIME],
                                     self.sock.getpeername()[0])
            server_db.add_online_client(username, self.sock.fileno())
            self.message.response_message_create(self.sock, OK)

    def _get_contacts_handle(self):
        client = server_db.ident_client_by_sockets(self.sock.fileno())
        # print (client)
        contacts_quantity = server_db.count_contacts(client)
        contacts = server_db.get_all_contacts(client)
        self.message.response_message_create(sock=self.sock, code=ACCEPTED,
                                             quantity=contacts_quantity)
        contact_info_message = JIMMessage()
        for contact in contacts:
            contact_info_message.create_server_contact_list(contact.login)
            contact_info_message.send_message(self.sock)
            # time.sleep(0.3)

    def _add_del_contact_handle(self, add=True):
        new_user = self.message.dict_message[USER_ID]
        if server_db.request_client(new_user) is None:
            self.message.response_message_create(self.sock, NOT_FOUND, with_message=False)
        else:
            client = server_db.ident_client_by_sockets(self.sock.fileno())
            if client:
                # print(client)
                if new_user not in server_db.get_all_contacts(client):
                    if add:
                        server_db.add_contacts(client, new_user)
                    else:
                        server_db.del_contact(client, new_user)
                    self.message.response_message_create(self.sock, OK, with_message=False)
                else:
                    self.message.response_message_create(self.sock, WRONG_REQUEST, with_message=False)
            else:
                print('Клиента с таким сокетом не существует')
                self.message.response_message_create(self.sock, WRONG_REQUEST,
                                                     message_text='Сокет не зарегистрирован')

    def _whole_message_check(self):
        if self.img_worker.whole_received_img:
            if server_db.get_client_img(self.img_worker.whole_received_img[USER_ID]) is None:
                server_db.write_client_img(self.img_worker.whole_received_img[USER_ID],
                                           self.img_worker.whole_received_img[IMG])
            else:
                server_db.update_client_img(self.img_worker.whole_received_img[USER_ID],
                                            self.img_worker.whole_received_img[IMG])

    def run(self):
        print("i'm running")
        while True:
            if not self.queue.empty():
                self._get_from_queue()
                self.handling_action()
            if not self.active:
                break
        return
Beispiel #7
0
class Client(metaclass=ClientVerifier):
    """
    Класс представлен необходимыми методами и свойствами для работы клиента.
    Метаклассом для этого класса послужил ClientVerifier, выполняющий функцию проверки
    используемых методов в данном классе.
    При инициализации экземпляра класса, передаются значения удалённого хоста и порт сервера,
    с которым будет осуществлять взаимодействия
    """
    def __init__(self, hostname='localhost', port=7777):
        self.def_hostname = hostname
        self.def_port = port
        # read_ и write_ нужны для проверки, если клиент был запущен из консоли только в одном режиме
        self._read = False
        self._write = False
        self.alive = True
        self.hostname, self.port = self._cli_param_get()
        self.username = ''
        self.client_db = None
        self.img_parts = {}
        self.m = JIMMessage()
        self.m_r = JIMResponse()
        self.sock = self.open_client_socket()
        self.img_sender = ImageWorker(self.sock, self.m, self.img_parts)

    def _cli_param_get(self):
        """
        Установить значение порта и адреса исходя из переданных данных, при запуске через командную строку
        :return:
        """
        try:
            port = int(find_cli_key_and_argument('-p', self.def_port))
        except ValueError:
            raise WrongPortError
        addr = find_cli_key_and_argument('-a', self.def_hostname)
        self._read = '-r' in sys.argv
        self._write = '-w' in sys.argv
        return addr, port

    def open_client_socket(self):
        """
        Создаёт экземпляр класса socket для клиентского приложения
        """
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((self.hostname, self.port))
        except ConnectionRefusedError:
            raise ConnectionRefusedError("Соединение по {}:{} не возможно".format(self.hostname, self.port))
        return sock

    @staticmethod
    def user_credentials_req():
        usr = input('Имя пользователя: ')
        pswd = input('Пароль: ')
        return usr, pswd

    def authorization(self, usr='', pswd=''):
        pswd_hash = get_safe_hash(pswd, SALT)
        self.m.create_auth_reg_message(usr, pswd_hash)
        self.m.send_rcv_message(self.sock)
        resp = self.m.dict_message[RESPONSE]
        # print(resp)
        if resp == OK:
            print("{} авторизован, приятного пользования".format(usr))
            auth_confirm = True
            # return "{} авторизован, приятного пользования".format(usr)
        elif resp == WRONG_COMBINATION:
            print("Не верный логин или пароль")
            auth_confirm = False
            # return "Не верный логин или пароль"
        else:
            print("Пользователя не существует")
            auth_confirm = False
        if not auth_confirm:
            print('Попробуйте ещё раз')
        return auth_confirm

    def registration(self, usr='', pswd=''):
        self.m.create_auth_reg_message(usr, pswd, registration=True)
        self.m.send_rcv_message(self.sock)
        resp = self.m.dict_message[RESPONSE]
        if resp == OK:
            print('Вы зарегистрировались, приятного пользования')
            reg = True
        elif resp == CONFLICT:
            print('Пользователь с такими именем уже существует')
            reg = False
        else:
            print('Регистрация не удалась')
            reg = False
        if not reg:
            print('Попробуйте ещё раз')
        return reg

    def start_client(self, usr="", pswd="", status="I'm here"):
        if not usr:
            reg = False
            while not reg:
                ans = input('Вы зарегистрированны? y/n: ')
                ans = ans.upper()
                if ans == 'N':
                    usr, pswd = self.user_credentials_req()
                    reg = self.registration(usr, pswd)
                elif ans == 'Y':
                    reg = True
            auth = False
            while not auth:
                usr, pswd = self.user_credentials_req()
                auth = self.authorization(usr, pswd)
        self.username = usr
        # получаем доступ к принадлежащй данному клиенту базе данных
        self.client_db = ClientWorker('sqlite:///system/db/{}_client_db.db?check_same_thread=False'.
                                      format(self.username))
        self.m.create_presence_message(usr, status)
        self.m.send_rcv_message(self.sock)
        self.receive_contact_messages()

    def receive_contact_messages(self):
        """
        В связи с тем, что контакт_сообщения могут приходить подряд, в этом случае, они будут декодированы и упакованы
        в список. Поэтому после получения сообщения мы проверяем, если список не пустой, т.о. понимаем, что сообщений
        было несколько.
        """
        message_lock.acquire()
        self.m.create_get_contact_message()
        print(self.m.send_rcv_message(self.sock))
        quantity = self.m.dict_message[QUANTITY]
        rcvd_qtty = 0
        while quantity != rcvd_qtty:
            self.m.rcv_message(self.sock)
            if self.m.list_of_dicts:
                n = len(self.m.list_of_dicts)
                for dict_ in self.m.list_of_dicts:
                    self.add_contact_to_db(dict_)
            else:
                self.add_contact_to_db(self.m.dict_message)
                n = 1
            rcvd_qtty += n
        message_lock.release()

    def add_contact_to_db(self, dict_message):
        try:
            # Contacts(dict_message[USER_ID]).save()
            self.client_db.add_contact(dict_message[USER_ID])
        except sqlalchemy.exc.IntegrityError:
            print('Клиент уже есть')

    def get_all_contacts(self):
        self.client_db.session.rollback()
        return self.client_db.get_all_contacts()

    def get_contact_img(self, contact_name='basic_user'):
        self.m.create_get_contact_img_message(contact_name)
        self.m.send_message(self.sock)
        # self.m.rcv_message(self.sock)

    def change_contact_global(self, username='******', add=True):
        message_lock.acquire()
        self.m.create_change_contact_message(username, add=add)
        self.m.send_rcv_message(self.sock)
        print(self.m.dict_message)
        if self.m.dict_message[RESPONSE] == 200:
            ok = True
        else:
            ok = False
        message_lock.release()
        return ok

    def add_contact_local(self, contact='MUSEUN'):
        self.client_db.add_contact(contact)

    def del_contact_local(self, contact='MUSEUN'):
        self.client_db.del_contact(contact)

    def check_local_contact(self, contact=''):
        if contact in self.client_db.get_all_contacts():
            ok = True
        else:
            ok = False
        return ok

    def send_msg_message(self, to, from_, text):
        message_lock.acquire()
        self.m.create_msg_message(False, to, from_, text)
        self.client_db.add_to_history(to, time.ctime(), text, True)
        self.m.send_rcv_message(self.sock)
        message_lock.release()

    def load_messages_from_history(self, contact=''):
        return self.client_db.get_messages_from_history(contact)

    def cycle_read_messages(self, queue):
        while self.alive:
            wait = 0.5
            r, w, e = select.select([self.sock], [self.sock], [], wait)
            for sock_ in r:
                self.m_r.rcv_message(sock_)
                if self.m_r.list_of_dicts:
                    for dict_ in self.m_r.list_of_dicts:
                        self.m_r.dict_message = dict_
                        self.received_message_handle()
                else:
                    self.received_message_handle()
                    # if self.m_r.dict_message[ACTION] == MSG:
                    #     self.client_db.session.rollback()
                    #     self.client_db.add_to_history(self.m_r.dict_message[FROM], time.ctime(),
                    #                                   self.m_r.dict_message[MESSAGE], False)
                    #     print(self.m_r.dict_message)
                    #     # queue.put(self.m_r.dict_message)
                    #     self.m_r.clean_buffer()
                    # elif self.m_r.dict_message[ACTION] == IMG or self.m_r.dict_message[ACTION] == IMG_PARTS:
                    #     img_receiver = ImageWorker(self.sock, self.m_r, self.img_parts)
                    #     img_receiver.handle(self.m_r.dict_message[ACTION])

    def received_message_handle(self):
        if self.m_r.dict_message[ACTION] == MSG:
            self.client_db.session.rollback()
            self.client_db.add_to_history(self.m_r.dict_message[FROM], time.ctime(),
                                          self.m_r.dict_message[MESSAGE], False)
            print(self.m_r.dict_message)
            # queue.put(self.m_r.dict_message)
            self.m_r.clean_buffer()
        elif self.m_r.dict_message[ACTION] == IMG or self.m_r.dict_message[ACTION] == IMG_PARTS:
            img_receiver = ImageWorker(self.sock, self.m_r, self.img_parts)
            img_receiver.handle(self.m_r.dict_message[ACTION])

    def cli_interact(self):
        while self.alive:
            action = input('>>')
            if action == 'send':
                to_ = input('>>Кому отправить: ')
                text = input('>>Текст сообщения: ')
                self.send_msg_message(to=to_, from_=self.username, text=text)
                pass
            elif action == 'show':
                for i in self.get_all_contacts():
                    print(i)
            elif action == 'add':
                new = input('>>Введите имя контакта: ')
                if not self.check_local_contact(new):
                    if self.change_contact_global(new):
                        self.add_contact_local(new)
                        print('Клиент добавлен')
                    else:
                        print('Не удаётся добавить клиента')
            elif action == 'del':
                del_ = input('>>Введите имя контакта: ')
                if self.check_local_contact(del_):
                    if self.change_contact_global(del_, False):
                        self.del_contact_local(del_)
                        print('Клиент удален')
                else:
                    print('Не удаётся удалить клиента')
            elif action == 'img':
                base64_to_send = input('>>Введите base64 код для отправки: ')
                # img_sender = ImageWorker(self.sock, self.m, self.img_parts)
                self.img_sender.img_send(base64_to_send)
            elif action == 'get_img':
                contact_name = input('>>Введите имя для получения изображения: ')
                self.get_contact_img(contact_name)
            elif action == 'end':
                self.alive = False
                break
            else:
                print('Не верное действие')