Added type field in user list entries

This commit is contained in:
emdee 2022-10-11 09:32:39 +00:00
parent f7c0e7ce23
commit b75aafe638
10 changed files with 109 additions and 65 deletions

View file

@ -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()))

View file

@ -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()

View file

@ -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
# -----------------------------------------------------------------------------------------------------------------
@ -179,13 +203,17 @@ class ContactsManager(ToxSave):
"""
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'

View file

@ -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

View file

@ -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),

View file

@ -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

View file

@ -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):
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

View file

@ -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()

View file

@ -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)

View file

@ -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)