From b75aafe638ad4b529b7c2adcfb4e7f7dbb966e12 Mon Sep 17 00:00:00 2001 From: emdee Date: Tue, 11 Oct 2022 09:32:39 +0000 Subject: [PATCH] Added type field in user list entries --- toxygen/app.py | 58 ++++++++-------------------- toxygen/contacts/basecontact.py | 7 +++- toxygen/contacts/contacts_manager.py | 52 ++++++++++++++++++++----- toxygen/contacts/friend_factory.py | 12 +++--- toxygen/contacts/group_chat.py | 3 +- toxygen/contacts/profile.py | 8 ++-- toxygen/groups/groups_service.py | 21 +++++++++- toxygen/messenger/messenger.py | 6 +++ toxygen/ui/contact_items.py | 6 ++- toxygen/ui/main_screen.py | 1 + 10 files changed, 109 insertions(+), 65 deletions(-) diff --git a/toxygen/app.py b/toxygen/app.py index d596d6e..56cacfa 100644 --- a/toxygen/app.py +++ b/toxygen/app.py @@ -80,7 +80,9 @@ from wrapper_tests.tests_wrapper import bootstrap_iNodeInfo global LOG import logging LOG = logging.getLogger('app') + IDLE_PERIOD = 0.10 +iNODES=8 def setup_logging(oArgs): global LOG @@ -100,8 +102,7 @@ def setup_logging(oArgs): if oArgs.logfile: aKw['filename'] = oArgs.logfile logging.basicConfig(**aKw) - - if oArgs.logfile: + if not oArgs.logfile: oHandler = logging.StreamHandler(stream=sys.stdout) LOG.addHandler(oHandler) @@ -814,22 +815,6 @@ class App: LOG.debug("_kill_tox") self._tox.kill() - def _test_relays(self, lElts=None): - env = self._test_env() - if lElts is None: - lElts = self._settings['current_nodes_tcp'] - shuffle(lElts) - LOG.debug(f"_test_relays {len(env['lElts'])}") - for host,port,key in lElts[:10]: - try: - oRet = self._tox.add_tcp_relay(host, port, key) - LOG.debug('add_tcp_relay to ' +host +':' +str(port) \ - +' : ' +str(oRet)) - except Exception as e: - LOG.warn('tox_add_tcp_relay ' +host +' : ' +str(e)) - # LOG.error(traceback.format_exc()) - # LOG.info("Connected status: " +repr(self._tox.self_get_connection_status())) - def loop(self, n): """ Im guessings - there are 3 sleeps - time, tox, and Qt @@ -921,7 +906,6 @@ class App: +_settings['proxy_host'] +':' \ +str(_settings['proxy_port'])) lElts = _settings['current_nodes_tcp'] - env['lElts'] = lElts LOG.debug(f"test_env {len(lElts)}") return env @@ -931,25 +915,16 @@ class App: lElts = self._settings['current_nodes_udp'] shuffle(lElts) LOG.debug(f"_test_bootstrap #Elts={len(lElts)}") - LOG.trace(f"_test_bootstrap lElts={lElts[:8]}") - shuffle(env['lElts']) - for host,port,key in lElts[:8]: - try: - assert len(key) == 64, key - assert len(host) <= 16, host - if type(port) == str: - port = int(port) - oRet = self._tox.bootstrap(host, port, key) - LOG.debug('bootstrap to ' +host +':' +str(port) \ - +' : ' +repr(oRet)) - except Exception as e: - LOG.warn('self._tox.bootstrap host=' +host \ - +' port=' +str(port) \ - +' key=' +key \ - +' : ' +str(e)) - # LOG.error(traceback.format_exc()) + shuffle(lElts) + ts.bootstrap_good(lElts[:iNODES], [self._tox]) + LOG.info("Connected status: " +repr(self._tox.self_get_connection_status())) - LOG.debug("Connected status: " +repr(self._tox.self_get_connection_status())) + def _test_relays(self, lElts=None): + if lElts is None: + lElts = self._settings['current_nodes_tcp'] + shuffle(lElts) + LOG.debug(f"_test_relays {len(lElts)}") + ts.bootstrap_tcp(lElts[:iNODES], [self._tox]) def _test_socks(self, lElts=None): LOG.debug("_test_socks") @@ -962,10 +937,9 @@ class App: reply = util_ui.question(text, title) if not reply: return - env = self._test_env() if lElts is None: - lElts = env['lElts'] - shuffle(env['lElts']) + lElts = self._settings['current_nodes_tcp'] + shuffle(lElts) try: bootstrap_iNodeInfo(lElts) except Exception as e: @@ -973,8 +947,8 @@ class App: LOG.error(f"test_tox ' +' : {e}") LOG.error('_test_tox(): ' \ +'\n' + traceback.format_exc()) - title = 'Extended Test Suite Error' - text = 'Error:' + str(e) + title = 'Test Suite Error' + text = 'Error: ' + str(e) util_ui.message_box(text, title) # LOG.info("Connected status: " +repr(self._tox.self_get_connection_status())) diff --git a/toxygen/contacts/basecontact.py b/toxygen/contacts/basecontact.py index f1ae6bf..9ac6bec 100644 --- a/toxygen/contacts/basecontact.py +++ b/toxygen/contacts/basecontact.py @@ -15,17 +15,20 @@ class BaseContact: Base class for all contacts. """ - def __init__(self, profile_manager, name, status_message, widget, tox_id): + def __init__(self, profile_manager, name, status_message, widget, tox_id, kind=''): """ :param name: name, example: 'Toxygen user' :param status_message: status message, example: 'Toxing on Toxygen' :param widget: ContactItem instance :param tox_id: tox id of contact + :param kind: one of ['bot', 'friend', 'group', 'invite', 'grouppeer', ''] """ self._profile_manager = profile_manager self._name, self._status_message = name, status_message + self._kind = kind self._status, self._widget = None, widget self._tox_id = tox_id + self._name_changed_event = event.Event() self._status_message_changed_event = event.Event() self._status_changed_event = event.Event() @@ -169,6 +172,8 @@ class BaseContact: def init_widget(self): self._widget.name.setText(self._name) self._widget.status_message.setText(self._status_message) + if hasattr(self._widget, 'kind'): + self._widget.kind.setText(self._kind) self._widget.connection_status.update(self._status) self.load_avatar() diff --git a/toxygen/contacts/contacts_manager.py b/toxygen/contacts/contacts_manager.py index 0c56f64..dba6a35 100644 --- a/toxygen/contacts/contacts_manager.py +++ b/toxygen/contacts/contacts_manager.py @@ -7,6 +7,7 @@ from contacts.group_chat import GroupChat from messenger.messages import * from common.tox_save import ToxSave from contacts.group_peer_contact import GroupPeerContact +from groups.group_peer import GroupChatPeer # LOG=util.log global LOG @@ -16,6 +17,21 @@ log = lambda x: LOG.info(x) UINT32_MAX = 2 ** 32 -1 +def set_contact_kind(contact): + bInvite = len(contact.name) == TOX_PUBLIC_KEY_SIZE * 2 and \ + contact.status_message == '' + bBot = not bInvite and contact.name.lower().endswith(' bot') + if type(contact) == Friend and bInvite: + contact._kind = 'invite' + elif type(contact) == Friend and bBot: + contact._kind = 'bot' + elif type(contact) == Friend: + contact._kind = 'friend' + elif type(contact) == GroupChat: + contact._kind = 'group' + elif type(contact) == GroupChatPeer: + contact._kind = 'grouppeer' + class ContactsManager(ToxSave): """ Represents contacts list. @@ -70,6 +86,14 @@ class ContactsManager(ToxSave): return self.get_curr_contact().number == group_number def is_contact_active(self, contact): + if not self._active_contact: + LOG.warn("No self._active_contact") + return False + if self._active_contact not in self._contacts: + return False + if not self._contacts[self._active_contact]: + return False + return self._contacts[self._active_contact].tox_id == contact.tox_id # ----------------------------------------------------------------------------------------------------------------- @@ -174,18 +198,22 @@ class ContactsManager(ToxSave): # ----------------------------------------------------------------------------------------------------------------- # Filtration # ----------------------------------------------------------------------------------------------------------------- - + def filtration_and_sorting(self, sorting=0, filter_str=''): """ Filtration of friends list :param sorting: 0 - no sorting, 1 - online only, 2 - online first, 3 - by name, - 4 - online and by name, 5 - online first and by name + 4 - online and by name, 5 - online first and by name, 6 kind :param filter_str: show contacts which name contains this substring """ filter_str = filter_str.lower() current_contact = self.get_curr_contact() - if sorting > 5 or sorting < 0: + for index, contact in enumerate(self._contacts): + if not contact._kind: + set_contact_kind(contact) + + if sorting > 6 or sorting < 0: sorting = 0 if sorting in (1, 2, 4, 5): # online first @@ -212,9 +240,12 @@ class ContactsManager(ToxSave): groups = filter(lambda c: type(c) is GroupChat, contacts) group_peers = filter(lambda c: type(c) is GroupPeerContact, contacts) self._contacts = list(friends) + list(groups) + list(group_peers) + elif sorting == 6: + self._contacts = sorted(self._contacts, key=lambda x: x._kind) else: self._contacts = sorted(self._contacts, key=lambda x: x.name.lower()) + # change item widgets for index, contact in enumerate(self._contacts): list_item = self._screen.friends_list.item(index) @@ -260,7 +291,7 @@ class ContactsManager(ToxSave): group = self.get_group_by_number(group_number) peer = group.get_peer_by_id(peer_id) if peer: # broken - if hasattr(peer, 'public_key'): + if not hasattr(peer, 'public_key'): LOG.error(f'no peer public_key ' + repr(dir(peer))) else: if not self.check_if_contact_exists(peer.public_key): @@ -404,6 +435,7 @@ class ContactsManager(ToxSave): contact = self._contact_provider.get_group_peer_by_id(group, peer.id) if self.check_if_contact_exists(contact.tox_id): return + contact._kind = 'grouppeer' self._contacts.append(contact) contact.reset_avatar(self._settings['identicons']) self._save_profile() @@ -443,24 +475,24 @@ class ContactsManager(ToxSave): # Friend requests # ----------------------------------------------------------------------------------------------------------------- - def send_friend_request(self, tox_id, message): + def send_friend_request(self, sToxPkOrId, message): """ Function tries to send request to contact with specified id - :param tox_id: id of new contact or tox dns 4 value + :param sToxPkOrId: id of new contact or tox dns 4 value :param message: additional message :return: True on success else error string """ retval = '' try: message = message or 'Hello! Add me to your contact list please' - if len(tox_id) == TOX_PUBLIC_KEY_SIZE * 2: # public key - self.add_friend(tox_id) + if len(sToxPkOrId) == TOX_PUBLIC_KEY_SIZE * 2: # public key + self.add_friend(sToxPkOrId) title = 'Friend added' text = 'Friend added without sending friend request' else: - num = self._tox.friend_add(tox_id, message.encode('utf-8')) + num = self._tox.friend_add(sToxPkOrId, message.encode('utf-8')) if num < UINT32_MAX: - tox_pk = tox_id[:TOX_PUBLIC_KEY_SIZE * 2] + tox_pk = sToxPkOrId[:TOX_PUBLIC_KEY_SIZE * 2] self._add_friend(tox_pk) self.update_filtration() title = 'Friend added' diff --git a/toxygen/contacts/friend_factory.py b/toxygen/contacts/friend_factory.py index 8ebafd6..c996c5c 100644 --- a/toxygen/contacts/friend_factory.py +++ b/toxygen/contacts/friend_factory.py @@ -13,21 +13,21 @@ class FriendFactory(ToxSave): def create_friend_by_public_key(self, public_key): friend_number = self._tox.friend_by_public_key(public_key) - return self.create_friend_by_number(friend_number) def create_friend_by_number(self, friend_number): aliases = self._settings['friends_aliases'] - tox_id = self._tox.friend_get_public_key(friend_number) + sToxPk = self._tox.friend_get_public_key(friend_number) + assert sToxPk, sToxPk try: - alias = list(filter(lambda x: x[0] == tox_id, aliases))[0][1] + alias = list(filter(lambda x: x[0] == sToxPk, aliases))[0][1] except: alias = '' item = self._create_friend_item() - name = alias or self._tox.friend_get_name(friend_number) or tox_id + name = alias or self._tox.friend_get_name(friend_number) or sToxPk status_message = self._tox.friend_get_status_message(friend_number) - message_getter = self._db.messages_getter(tox_id) - friend = Friend(self._profile_manager, message_getter, friend_number, name, status_message, item, tox_id) + message_getter = self._db.messages_getter(sToxPk) + friend = Friend(self._profile_manager, message_getter, friend_number, name, status_message, item, sToxPk) friend.set_alias(alias) return friend diff --git a/toxygen/contacts/group_chat.py b/toxygen/contacts/group_chat.py index 068790e..15aa0ec 100644 --- a/toxygen/contacts/group_chat.py +++ b/toxygen/contacts/group_chat.py @@ -83,11 +83,12 @@ class GroupChat(contact.Contact, ToxSave): return self.get_self_role() == constants.TOX_GROUP_ROLE['FOUNDER'] def add_peer(self, peer_id, is_current_user=False): + "called from callbacks" if peer_id > self._peers_limit: LOG_WARN(f"add_peer id={peer_id} > {self._peers_limit}") return - LOG_INFO(f"add_peer id={peer_id}") + LOG_TRACE(f"add_peer id={peer_id}") peer = GroupChatPeer(peer_id, self._tox.group_peer_get_name(self._number, peer_id), self._tox.group_peer_get_status(self._number, peer_id), diff --git a/toxygen/contacts/profile.py b/toxygen/contacts/profile.py index 097c1fa..ed816d9 100644 --- a/toxygen/contacts/profile.py +++ b/toxygen/contacts/profile.py @@ -5,6 +5,8 @@ import threading import common.tox_save as tox_save from middleware.threads import invoke_in_main_thread +iUMAXINT = 4294967295 + global LOG import logging LOG = logging.getLogger('app.'+__name__) @@ -65,10 +67,10 @@ class Profile(basecontact.BaseContact, tox_save.ToxSave): def set_new_nospam(self): """Sets new nospam part of tox id""" - self._tox.self_set_nospam(random.randint(0, 4294967295)) # no spam - uint32 + self._tox.self_set_nospam(random.randint(0, iUMAXINT)) # no spam - uint32 self._tox_id = self._tox.self_get_address() - - return self._tox_id + self._sToxId = self._tox.self_get_address() + return self._sToxId # ----------------------------------------------------------------------------------------------------------------- # Reset diff --git a/toxygen/groups/groups_service.py b/toxygen/groups/groups_service.py index bf165a9..acf1d51 100644 --- a/toxygen/groups/groups_service.py +++ b/toxygen/groups/groups_service.py @@ -6,6 +6,7 @@ from groups.peers_list import PeersListGenerator from groups.group_invite import GroupInvite import wrapper.toxcore_enums_and_consts as constants from wrapper.toxcore_enums_and_consts import * +from wrapper.tox import UINT32_MAX global LOG import logging @@ -49,11 +50,29 @@ class GroupsService(tox_save.ToxSave): self._contacts_manager.update_filtration() def join_gc_by_id(self, chat_id, password, nick, status): - group_number = self._tox.group_join(chat_id, password, nick, status) + try: + group_number = self._tox.group_join(chat_id, password, nick, status) + assert type(group_number) == int, group_number + assert group_number < UINT32_MAX, group_number + except Exception as e: + # gui + title = f"join_gc_by_id {chat_id}" + util_ui.message_box(title +'\n' +str(e), title) + LOG.error(f"_join_gc_via_id {e}") + return LOG.debug(f"_join_gc_via_id {group_number}") self._add_new_group_by_number(group_number) group = self._get_group_by_number(group_number) + try: + assert group and hasattr(group, 'status') + except Exception as e: + # gui + title = f"join_gc_by_id {chat_id}" + util_ui.message_box(title +'\n' +str(e), title) + LOG.error(f"_join_gc_via_id {e}") + return group.status = constants.TOX_USER_STATUS['NONE'] + self._contacts_manager.update_filtration() # ----------------------------------------------------------------------------------------------------------------- # Groups reconnect and leaving diff --git a/toxygen/messenger/messenger.py b/toxygen/messenger/messenger.py index 5474d55..b235e9e 100644 --- a/toxygen/messenger/messenger.py +++ b/toxygen/messenger/messenger.py @@ -204,6 +204,9 @@ class Messenger(tox_save.ToxSave): text_message = TextMessage(message, MessageAuthor(peer.name, MESSAGE_AUTHOR['GC_PEER']), t, message_type) group_peer_contact = self._contacts_manager.get_or_create_group_peer_contact(group_number, peer_id) + if not group_peer_contact: + LOG.warn('FixMe new_group_private_message group_peer_contact ' + str(peer_id)) + return self._add_message(text_message, group_peer_contact) # ----------------------------------------------------------------------------------------------------------------- @@ -316,6 +319,9 @@ class Messenger(tox_save.ToxSave): def _add_message(self, text_message, contact): assert_main_thread() + if not contact: + LOG.warn("_add_message null contact") + return if self._contacts_manager.is_contact_active(contact): # add message to list self._create_message_item(text_message) self._screen.messages.scrollToBottom() diff --git a/toxygen/ui/contact_items.py b/toxygen/ui/contact_items.py index 7a32284..98a1dcd 100644 --- a/toxygen/ui/contact_items.py +++ b/toxygen/ui/contact_items.py @@ -9,7 +9,7 @@ class ContactItem(QtWidgets.QWidget): Contact in friends list """ - def __init__(self, settings, parent=None): + def __init__(self, settings, parent=None, kind='friend'): QtWidgets.QWidget.__init__(self, parent) mode = settings['compact_mode'] self.setBaseSize(QtCore.QSize(250, 40 if mode else 70)) @@ -30,6 +30,10 @@ class ContactItem(QtWidgets.QWidget): font.setPointSize(10) font.setBold(False) self.status_message.setFont(font) + self.kind = DataLabel(self) + self.kind.setGeometry(QtCore.QRect(50 if mode else 75, 38 if mode else 48, 190, 15 if mode else 20)) + font.setBold(True) + self.kind.setFont(font) self.connection_status = StatusCircle(self) self.connection_status.setGeometry(QtCore.QRect(230, -2 if mode else 5, 32, 32)) self.messages = UnreadMessagesCount(settings, self) diff --git a/toxygen/ui/main_screen.py b/toxygen/ui/main_screen.py index 669aa2d..29082e7 100644 --- a/toxygen/ui/main_screen.py +++ b/toxygen/ui/main_screen.py @@ -342,6 +342,7 @@ class MainWindow(QtWidgets.QMainWindow): self.contactsFilterComboBox.addItem(util_ui.tr("Name")) self.contactsFilterComboBox.addItem(util_ui.tr("Online and by name")) self.contactsFilterComboBox.addItem(util_ui.tr("Online first and by name")) + self.contactsFilterComboBox.addItem(util_ui.tr("Kind")) def setup_right_bottom(self, Form): Form.resize(650, 60)