From aae71d081f96a93e52f22ab7a63e06244166dd30 Mon Sep 17 00:00:00 2001 From: ingvar1995 Date: Mon, 17 Jul 2017 01:11:09 +0300 Subject: [PATCH] base backend for gc --- toxygen/callbacks.py | 4 ++ toxygen/group_chat.py | 9 ++-- toxygen/messages.py | 14 +++++- toxygen/profile.py | 67 ++++++++++++++++++++++++++++- toxygen/tox.py | 8 ++-- toxygen/toxcore_enums_and_consts.py | 5 +++ 6 files changed, 96 insertions(+), 11 deletions(-) diff --git a/toxygen/callbacks.py b/toxygen/callbacks.py index 31b50bd..7028f97 100644 --- a/toxygen/callbacks.py +++ b/toxygen/callbacks.py @@ -397,6 +397,10 @@ def group_title(tox, group_number, peer_number, title, length, user_data): invoke_in_main_thread(Profile.get_instance().new_gc_title, group_number, title[:length]) + +def group_namelist_change(tox, group_number, peer_number, change, user_data): + invoke_in_main_thread(Profile.get_instance().update_gc, group_number) + # ----------------------------------------------------------------------------------------------------------------- # Callbacks - initialization # ----------------------------------------------------------------------------------------------------------------- diff --git a/toxygen/group_chat.py b/toxygen/group_chat.py index acf84e8..563d494 100644 --- a/toxygen/group_chat.py +++ b/toxygen/group_chat.py @@ -1,11 +1,10 @@ -import basecontact +import contact -class GroupChat(basecontact.BaseContact): +class GroupChat(contact.Contact): def __init__(self, name, status_message, widget, tox, group_number): - super().__init__(name, status_message, widget, None) - self._number = group_number + super().__init__(None, group_number, name, status_message, widget, None) self._tox = tox def set_name(self, name): @@ -16,4 +15,4 @@ class GroupChat(basecontact.BaseContact): self._tox.group_message_send(self._number, message.encode('utf-8')) def new_title(self, title): - self._name = title + super().set_name(title) diff --git a/toxygen/messages.py b/toxygen/messages.py index 87a1cc2..8d9f4a3 100644 --- a/toxygen/messages.py +++ b/toxygen/messages.py @@ -5,7 +5,9 @@ MESSAGE_TYPE = { 'ACTION': 1, 'FILE_TRANSFER': 2, 'INLINE': 3, - 'INFO_MESSAGE': 4 + 'INFO_MESSAGE': 4, + 'GC_TEXT': 5, + 'GC_ACTION': 6 } @@ -39,6 +41,16 @@ class TextMessage(Message): return self._message, self._owner, self._time, self._type +class GroupChatMessage(TextMessage): + + def __init__(self, message, owner, time, message_type, name): + super().__init__(message, owner, time, message_type) + self._user_name = name + + def get_data(self): + return self._message, self._owner, self._time, self._type, self._user_name + + class TransferMessage(Message): """ Message with info about file transfer diff --git a/toxygen/profile.py b/toxygen/profile.py index 1d744db..a0870d8 100644 --- a/toxygen/profile.py +++ b/toxygen/profile.py @@ -16,6 +16,7 @@ import basecontact import items_factory import cv2 import threading +from group_chat import * class Profile(basecontact.BaseContact, Singleton): @@ -177,7 +178,7 @@ class Profile(basecontact.BaseContact, Singleton): # ----------------------------------------------------------------------------------------------------------------- def get_friend_by_number(self, num): - return list(filter(lambda x: x.number == num, self._contacts))[0] + return list(filter(lambda x: x.number == num and type(x) is Friend, self._contacts))[0] def get_friend(self, num): if num < 0 or num >= len(self._contacts): @@ -636,6 +637,16 @@ class Profile(basecontact.BaseContact, Singleton): return self._factory.message_item(text, time, name, owner != MESSAGE_OWNER['NOT_SENT'], message_type, append, pixmap) + def create_gc_message_item(self, text, time, owner, name, message_type, append=True): + pixmap = None + if self._show_avatars: + if owner == MESSAGE_OWNER['FRIEND']: + pixmap = self.get_curr_friend().get_pixmap() + else: + pixmap = self.get_pixmap() + return self._factory.message_item(text, time, name, True, + message_type, append, pixmap) + def create_file_transfer_item(self, tm, append=True): data = list(tm.get_data()) data[3] = self.get_friend_by_number(data[4]).name if data[3] else self._name @@ -1265,6 +1276,60 @@ class Profile(basecontact.BaseContact, Singleton): self.create_message_item(text, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE']) self._messages.scrollToBottom() + # ----------------------------------------------------------------------------------------------------------------- + # GC support + # ----------------------------------------------------------------------------------------------------------------- + + def is_active_a_friend(self): + return type(self.get_curr_friend()) is Friend + + def get_group_by_number(self, number): + groups = filter(lambda x: type(x) is GroupChat and x.number == number, self._contacts) + return list(groups)[0] + + def add_gc(self, number): + widget = self.create_friend_item() + gc = GroupChat('', '', widget, self._tox, number) + self._contacts.append(gc) + + def create_group_chat(self): + number = self._tox.add_av_groupchat() + self.add_gc(number) + + def group_invite(self, friend_number, gc_type, data): + text = QtWidgets.QApplication.translate('MainWindow', 'User {} invites you to group chat. Accept?') + title = QtWidgets.QApplication.translate('MainWindow', 'Group chat invite') + reply = QtWidgets.QMessageBox.question(None, title, text, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) + if reply == QtWidgets.QMessageBox.Yes: # accepted + if gc_type == TOX_GROUPCHAT_TYPE['TEXT']: + number = self._tox.join_groupchat(friend_number, data) + else: + number = self._tox.join_av_groupchat(friend_number, data) + self.add_gc(number) + + def new_gc_message(self, group_number, peer_number, message_type, message): + name = self._tox.group_peername(group_number, peer_number) + if group_number == self.get_active_number() and not self.is_active_a_friend(): # add message to list + t = time.time() + self.create_gc_message_item(message, t, MESSAGE_OWNER['FRIEND'], name, message_type) + self._messages.scrollToBottom() + self.get_curr_friend().append_message( + GroupChatMessage(message, MESSAGE_OWNER['FRIEND'], t, message_type. name)) + else: + gc = self.get_group_by_number(group_number) + gc.inc_messages() + gc.append_message( + GroupChatMessage(message, MESSAGE_OWNER['FRIEND'], time.time(), message_type, name)) + if not gc.visibility: + self.update_filtration() + + def new_gc_title(self, group_number, title): + gc = self.get_group_by_number(group_number) + gc.new_title(title) + + def update_gc(self, group_number): + pass + def tox_factory(data=None, settings=None): """ diff --git a/toxygen/tox.py b/toxygen/tox.py index f36ea37..0d06f5b 100644 --- a/toxygen/tox.py +++ b/toxygen/tox.py @@ -1528,9 +1528,9 @@ class Tox: c_int(groupnumber), None) return result - def join_groupchat(self, friendnumber, data, length): + def join_groupchat(self, friendnumber, data): result = Tox.libtoxcore.tox_join_groupchat(self._tox_pointer, - c_int(friendnumber), c_char_p(data), c_uint16(length), None) + c_int(friendnumber), c_char_p(data), c_uint16(len(data)), None) return result def group_message_send(self, groupnumber, message): @@ -1569,9 +1569,9 @@ class Tox: result = Tox.libtoxcore.tox_add_av_groupchat(self._tox_pointer, None, None, None) return result - def join_av_groupchat(self, friendnumber, data, length): + def join_av_groupchat(self, friendnumber, data): result = Tox.libtoxcore.tox_join_av_groupchat(self._tox_pointer, c_int(friendnumber), - c_char_p(data), c_uint16(length), None, None, None) + c_char_p(data), c_uint16(len(data)), None, None, None) return result def callback_group_invite(self, callback, user_data=None): diff --git a/toxygen/toxcore_enums_and_consts.py b/toxygen/toxcore_enums_and_consts.py index fc8941b..a17d93e 100644 --- a/toxygen/toxcore_enums_and_consts.py +++ b/toxygen/toxcore_enums_and_consts.py @@ -194,6 +194,11 @@ TOX_CHAT_CHANGE = { 'PEER_NAME': 2 } +TOX_GROUPCHAT_TYPE = { + 'TEXT': 0, + 'AV': 1 +} + TOX_PUBLIC_KEY_SIZE = 32 TOX_ADDRESS_SIZE = TOX_PUBLIC_KEY_SIZE + 6