This commit is contained in:
emdee 2022-11-05 01:16:25 +00:00
parent a073dd9bc9
commit 1b8b26eafc
13 changed files with 152 additions and 65 deletions

View File

@ -48,7 +48,7 @@ Toxygen is powerful cross-platform [Tox](https://tox.chat/) client written in pu
This hard-forked from https://github.com/toxygen-project/toxygen This hard-forked from https://github.com/toxygen-project/toxygen
```next_gen``` branch. ```next_gen``` branch.
https://git.plastiras.org/emdee/toxygen_wrapper needs packaging https://git.plastiras.org/emdee/toxygen_wrapper needs packaging
is making a dependency. Just download it and copy the two directories is making a dependency. Just download it and copy the two directories
```wrapper``` and ```wrapper_tests``` into ```toxygen/toxygen```. ```wrapper``` and ```wrapper_tests``` into ```toxygen/toxygen```.
@ -56,4 +56,4 @@ is making a dependency. Just download it and copy the two directories
See ToDo.md to the current ToDo list. See ToDo.md to the current ToDo list.
Work on this project is suspended until the Work on this project is suspended until the
[MultiDevice](https://git.plastiras.org/emdee/tox_profile/wiki/MultiDevice-Announcements-POC) problem is solved. Fork me! [MultiDevice](https://git.plastiras.org/emdee/tox_profile/wiki/MultiDevice-Announcements-POC) problem is solved. Fork me!

View File

@ -903,13 +903,14 @@ class App:
while i < iMax: while i < iMax:
# if oThread and oThread._stop_thread: return # if oThread and oThread._stop_thread: return
i = i + 1 i = i + 1
LOG.debug(f"bootstrapping status # {i}") LOG.debug(f"bootstrapping status proxy={self._oArgs.proxy_type} # {i}")
self._test_bootstrap(lUdpElts) if self._oArgs.proxy_type == 0:
if hasattr(self._oArgs, 'proxy_type') and self._oArgs.proxy_type > 0: self._test_bootstrap(lUdpElts)
else:
self._test_bootstrap([lUdpElts[0]])
LOG.debug(f"relaying status # {i}") LOG.debug(f"relaying status # {i}")
self._test_relays(self._settings['current_nodes_tcp']) self._test_relays(self._settings['current_nodes_tcp'])
status = self._tox.self_get_connection_status() status = self._tox.self_get_connection_status()
LOG.debug(f"connecting status # {i}" +' : ' +repr(status))
if status > 0: if status > 0:
LOG.info(f"Connected # {i}" +' : ' +repr(status)) LOG.info(f"Connected # {i}" +' : ' +repr(status))
break break
@ -956,8 +957,8 @@ class App:
LOG.debug(f"_test_relays {len(lElts)}") LOG.debug(f"_test_relays {len(lElts)}")
ts.bootstrap_tcp(lElts[:iNODES], [self._tox]) ts.bootstrap_tcp(lElts[:iNODES], [self._tox])
def _test_socks(self, lElts=None): def _test_nmap(self, lElts=None):
LOG.debug("_test_socks") LOG.debug("_test_nmap")
if not self._tox: return if not self._tox: return
title = 'Extended Test Suite' title = 'Extended Test Suite'
text = 'Run the Extended Test Suite?\nThe program may freeze for 1-10 minutes.' text = 'Run the Extended Test Suite?\nThe program may freeze for 1-10 minutes.'
@ -968,14 +969,19 @@ class App:
if not reply: return if not reply: return
if lElts is None: if lElts is None:
lElts = self._settings['current_nodes_tcp'] if self._oArgs.proxy_type == 0:
sProt = "udp4"
lElts = self._settings['current_nodes_tcp']
else:
sProt = "tcp4"
lElts = self._settings['current_nodes_tcp']
shuffle(lElts) shuffle(lElts)
try: try:
bootstrap_iNodeInfo(lElts) ts.bootstrap_iNmapInfo(lElts, self._oArgs, sProt)
self._ms.log_console()
except Exception as e: except Exception as e:
# json.decoder.JSONDecodeError LOG.error(f"test_nmap ' +' : {e}")
LOG.error(f"test_tox ' +' : {e}") LOG.error('_test_nmap(): ' \
LOG.error('_test_tox(): ' \
+'\n' + traceback.format_exc()) +'\n' + traceback.format_exc())
title = 'Test Suite Error' title = 'Test Suite Error'
text = 'Error: ' + str(e) text = 'Error: ' + str(e)
@ -986,7 +992,7 @@ class App:
def _test_main(self): def _test_main(self):
from tests.tests_socks import main as tests_main from tests.tests_socks import main as tests_main
LOG.debug("_test_socks") LOG.debug("_test_main")
if not self._tox: return if not self._tox: return
title = 'Extended Test Suite' title = 'Extended Test Suite'
text = 'Run the Extended Test Suite?\nThe program may freeze for 20-60 minutes.' text = 'Run the Extended Test Suite?\nThe program may freeze for 20-60 minutes.'

View File

@ -299,6 +299,7 @@ class AV(common.tox_save.ToxAvSave):
self._video_width = s['video']['width'] self._video_width = s['video']['width']
self._video_height = s['video']['height'] self._video_height = s['video']['height']
# dunno
if True or s['video']['device'] == -1: if True or s['video']['device'] == -1:
self._video = screen_sharing.DesktopGrabber(s['video']['x'], self._video = screen_sharing.DesktopGrabber(s['video']['x'],
s['video']['y'], s['video']['y'],
@ -404,6 +405,7 @@ class AV(common.tox_save.ToxAvSave):
if self._calls[friend_num].out_audio: if self._calls[friend_num].out_audio:
try: try:
# app.av.calls ERROR Error send_audio: One of the frame parameters was invalid. E.g. the resolution may be too small or too large, or the audio sampling rate may be unsupported # app.av.calls ERROR Error send_audio: One of the frame parameters was invalid. E.g. the resolution may be too small or too large, or the audio sampling rate may be unsupported
# app.av.calls ERROR Error send_audio audio_send_frame: This client is currently not in a call with the friend.
self._toxav.audio_send_frame(friend_num, self._toxav.audio_send_frame(friend_num,
pcm, pcm,
count, count,
@ -412,9 +414,9 @@ class AV(common.tox_save.ToxAvSave):
except Exception as e: except Exception as e:
LOG.error(f"Error send_audio audio_send_frame: {e}") LOG.error(f"Error send_audio audio_send_frame: {e}")
LOG.debug(f"send_audio self._audio_rate_tox={self._audio_rate_tox} self._audio_channels={self._audio_channels}") LOG.debug(f"send_audio self._audio_rate_tox={self._audio_rate_tox} self._audio_channels={self._audio_channels}")
invoke_in_main_thread(util_ui.message_box, # invoke_in_main_thread(util_ui.message_box,
str(e), # str(e),
util_ui.tr("Error send_audio audio_send_frame")) # util_ui.tr("Error send_audio audio_send_frame"))
pass pass
def send_audio(self): def send_audio(self):
@ -432,9 +434,10 @@ class AV(common.tox_save.ToxAvSave):
else: else:
self.send_audio_data(pcm, count) self.send_audio_data(pcm, count)
except: except:
pass LOG_DEBUG(f"error send_audio {i}")
else:
LOG_TRACE(f"send_audio {i}")
i += 1 i += 1
LOG.debug(f"send_audio {i}")
sleep(0.01) sleep(0.01)
def send_video(self): def send_video(self):
@ -454,7 +457,7 @@ class AV(common.tox_save.ToxAvSave):
LOG.warn(f"send_video video_send_frame _video.read result={result} frame={frame}") LOG.warn(f"send_video video_send_frame _video.read result={result} frame={frame}")
continue continue
else: else:
LOG.debug(f"send_video video_send_frame _video.read result={result}") LOG_TRACE(f"send_video video_send_frame _video.read result={result}")
height, width, channels = frame.shape height, width, channels = frame.shape
friends = [] friends = []
for friend_num in self._calls: for friend_num in self._calls:
@ -463,7 +466,7 @@ class AV(common.tox_save.ToxAvSave):
if len(friends) == 0: if len(friends) == 0:
LOG.warn(f"send_video video_send_frame no friends") LOG.warn(f"send_video video_send_frame no friends")
else: else:
LOG.debug(f"send_video video_send_frame {friends}") LOG_TRACE(f"send_video video_send_frame {friends}")
friend_num = friends[0] friend_num = friends[0]
try: try:
y, u, v = self.convert_bgr_to_yuv(frame) y, u, v = self.convert_bgr_to_yuv(frame)

View File

@ -141,11 +141,14 @@ class Contact(basecontact.BaseContact):
return list(messages) return list(messages)
def mark_as_sent(self, tox_message_id): def mark_as_sent(self, tox_message_id):
message = list(filter(lambda m: m.author is not None
and m.author.type == MESSAGE_AUTHOR['NOT_SENT']
and m.tox_message_id == tox_message_id,
self._corr))[0]
try: try:
message = list(filter(lambda m: m.author is not None and m.author.type == MESSAGE_AUTHOR['NOT_SENT']
and m.tox_message_id == tox_message_id, self._corr))[0]
message.mark_as_sent() message.mark_as_sent()
except Exception as ex: except Exception as ex:
# wrapped C/C++ object of type QLabel has been deleted
LOG.error(f"Mark as sent: {ex!s}") LOG.error(f"Mark as sent: {ex!s}")
# ----------------------------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------------------------

View File

@ -6,6 +6,18 @@ global LOG
import logging import logging
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
# callbacks can be called in any thread so were being careful
def LOG_ERROR(l): print('EROR< '+l)
def LOG_WARN(l): print('WARN< '+l)
def LOG_INFO(l):
bIsVerbose = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 20-1
if bIsVerbose: print('INFO< '+l)
def LOG_DEBUG(l):
bIsVerbose = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 10-1
if bIsVerbose: print('DBUG< '+l)
def LOG_TRACE(l):
bIsVerbose = hasattr(__builtins__, 'app') and app.oArgs.loglevel < 10-1
pass # print('TRACE+ '+l)
class ContactProvider(tox_save.ToxSave): class ContactProvider(tox_save.ToxSave):
@ -24,6 +36,7 @@ class ContactProvider(tox_save.ToxSave):
try: try:
public_key = self._tox.friend_get_public_key(friend_number) public_key = self._tox.friend_get_public_key(friend_number)
except Exception as e: except Exception as e:
LOG_WARN(f"get_friend_by_number NO {friend_number} {e} ")
return None return None
return self.get_friend_by_public_key(public_key) return self.get_friend_by_public_key(public_key)
@ -33,6 +46,7 @@ class ContactProvider(tox_save.ToxSave):
return friend return friend
friend = self._friend_factory.create_friend_by_public_key(public_key) friend = self._friend_factory.create_friend_by_public_key(public_key)
self._add_to_cache(public_key, friend) self._add_to_cache(public_key, friend)
LOG_INFO(f"get_friend_by_public_key ADDED {friend} ")
return friend return friend
@ -40,6 +54,7 @@ class ContactProvider(tox_save.ToxSave):
try: try:
friend_numbers = self._tox.self_get_friend_list() friend_numbers = self._tox.self_get_friend_list()
except Exception as e: except Exception as e:
LOG_WARN(f"get_all_friends NO {friend_numbers} {e} ")
return None return None
friends = map(lambda n: self.get_friend_by_number(n), friend_numbers) friends = map(lambda n: self.get_friend_by_number(n), friend_numbers)
@ -50,38 +65,70 @@ class ContactProvider(tox_save.ToxSave):
# ----------------------------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------------------------
def get_all_groups(self): def get_all_groups(self):
"""from callbacks"""
try: try:
group_numbers = range(self._tox.group_get_number_groups()) len_groups = self._tox.group_get_number_groups()
group_numbers = range(len_groups)
except Exception as e: except Exception as e:
return None return None
groups = map(lambda n: self.get_group_by_number(n), group_numbers) groups = list(map(lambda n: self.get_group_by_number(n), group_numbers))
# failsafe in case there are bogus None groups?
return list(groups) fgroups = list(filter(lambda x: x, groups))
if len(fgroups) != len_groups:
LOG_WARN(f"are there are bogus None groups in libtoxcore? {len(fgroups)} != {len_groups}")
for group_num in group_numbers:
group = self.get_group_by_number(group_num)
if group is None:
LOG_ERROR(f"there are bogus None groups in libtoxcore {group_num}!")
# fixme: do something
groups = fgroups
return groups
def get_group_by_number(self, group_number): def get_group_by_number(self, group_number):
group = None
try: try:
if True: LOG_INFO(f"group_get_number {group_number} ")
# original code # original code
public_key = self._tox.group_get_chat_id(group_number) chat_id = self._tox.group_get_chat_id(group_number)
# LOG.info(f"group_get_chat_id {group_number} {public_key}") if not chat_id:
return self.get_group_by_public_key(public_key) LOG_ERROR(f"get_group_by_number NULL number ({group_number})")
else: else:
# guessing LOG_INFO(f"group_get_number {group_number} {chat_id}")
chat_id = self._tox.group_get_chat_id(group_number) group = self.get_group_by_chat_id(chat_id)
# LOG.info(f"group_get_chat_id {group_number} {chat_id}") if not group:
group = self.get_contact_by_tox_id(chat_id) LOG_ERROR(f"get_group_by_number NULL group ({chat_id})")
return group if group is None:
LOG_WARN(f"get_group_by_number leaving ({group_number})")
#? iRet = self._tox.group_leave(group_number)
# invoke in main thread?
# self._contacts_manager.delete_group(group_number)
return group
except Exception as e: except Exception as e:
LOG.warn(f"group_get_chat_id {group_number} {e}") LOG_WARN(f"group_get_number {group_number} {e}")
return None return None
def get_group_by_chat_id(self, chat_id):
group = self._get_contact_from_cache(chat_id)
if group is not None:
return group
group = self._group_factory.create_group_by_chat_id(chat_id)
if group is None:
LOG_ERROR(f"get_group_by_chat_id NULL chat_id={chat_id}")
else:
self._add_to_cache(chat_id, group)
return group
def get_group_by_public_key(self, public_key): def get_group_by_public_key(self, public_key):
group = self._get_contact_from_cache(public_key) group = self._get_contact_from_cache(public_key)
if group is not None: if group is not None:
return group return group
group = self._group_factory.create_group_by_public_key(public_key) group = self._group_factory.create_group_by_public_key(public_key)
self._add_to_cache(public_key, group) if group is None:
LOG_ERROR(f"get_group_by_public_key NULL group public_key={get_group_by_chat_id}")
else:
self._add_to_cache(public_key, group)
return group return group

View File

@ -54,7 +54,8 @@ class ContactsManager(ToxSave):
self._tox_dns = tox_dns self._tox_dns = tox_dns
self._messages_items_factory = messages_items_factory self._messages_items_factory = messages_items_factory
self._messages = screen.messages self._messages = screen.messages
self._contacts, self._active_contact = [], -1 self._contacts = []
self._active_contact = -1
self._active_contact_changed = Event() self._active_contact_changed = Event()
self._sorting = settings['sorting'] self._sorting = settings['sorting']
self._filter_string = '' self._filter_string = ''
@ -92,17 +93,16 @@ class ContactsManager(ToxSave):
return self.get_curr_contact().number == group_number return self.get_curr_contact().number == group_number
def is_contact_active(self, contact): def is_contact_active(self, contact):
if not self._active_contact: if self._active_contact == -1:
# LOG.debug("No self._active_contact") # LOG.debug("No self._active_contact")
return False return False
if self._active_contact not in self._contacts: if self._active_contact >= len(self._contacts):
LOG.warn(f"_active_contact={self._active_contact} not in contacts len={len(self._contacts)}") LOG.warn(f"ERROR _active_contact={self._active_contact} >= contacts len={len(self._contacts)}")
return False return False
if not self._contacts[self._active_contact]: if not self._contacts[self._active_contact]:
LOG.debug(f"{self._contacts[self._active_contact]} {contact.tox_id}") LOG.warn(f"ERROR NULL {self._contacts[self._active_contact]} {contact.tox_id}")
return False return False
LOG.debug(f"{self._contacts[self._active_contact].tox_id} == {contact.tox_id}")
return self._contacts[self._active_contact].tox_id == contact.tox_id return self._contacts[self._active_contact].tox_id == contact.tox_id
# ----------------------------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------------------------
@ -145,7 +145,7 @@ class ContactsManager(ToxSave):
current_contact.remove_messages_widgets() # TODO: if required current_contact.remove_messages_widgets() # TODO: if required
self._unsubscribe_from_events(current_contact) self._unsubscribe_from_events(current_contact)
if self._active_contact + 1 and self._active_contact != value: if self._active_contact >= 0 and self._active_contact != value:
try: try:
current_contact.curr_text = self._screen.messageEdit.toPlainText() current_contact.curr_text = self._screen.messageEdit.toPlainText()
except: except:
@ -180,7 +180,7 @@ class ContactsManager(ToxSave):
self._set_current_contact_data(contact) self._set_current_contact_data(contact)
self._active_contact_changed(contact) self._active_contact_changed(contact)
except Exception as ex: # no friend found. ignore except Exception as ex: # no friend found. ignore
LOG.warn(f"no friend found. Friend value: {value!s}") LOG.warn(f"no friend found. Friend value: {value!s}")
LOG.error('in set active: ' + str(ex)) LOG.error('in set active: ' + str(ex))
# gulp raise # gulp raise
@ -368,7 +368,10 @@ class ContactsManager(ToxSave):
""" """
friend = self._contacts[num] friend = self._contacts[num]
self._cleanup_contact_data(friend) self._cleanup_contact_data(friend)
self._tox.friend_delete(friend.number) try:
self._tox.friend_delete(friend.number)
except Exception as e:
LOG.warn(f"'There was no friend with the given friend number {e}")
self._delete_contact(num) self._delete_contact(num)
def add_friend(self, tox_id): def add_friend(self, tox_id):
@ -418,7 +421,8 @@ class ContactsManager(ToxSave):
def add_group(self, group_number): def add_group(self, group_number):
index = len(self._contacts) index = len(self._contacts)
group = self._contact_provider.get_group_by_number(group_number) group = self._contact_provider.get_group_by_number(group_number)
if not group: # group num >= 0?
if group is None:
LOG.warn(f"CM.add_group: NO group {group_number}") LOG.warn(f"CM.add_group: NO group {group_number}")
else: else:
LOG.info(f"CM.add_group: Adding group {group._name}") LOG.info(f"CM.add_group: Adding group {group._name}")
@ -517,7 +521,8 @@ class ContactsManager(ToxSave):
title = 'Friend add exception' title = 'Friend add exception'
text = 'Friend request exception with ' + str(ex) text = 'Friend request exception with ' + str(ex)
self._log(text) self._log(text)
LOG.error(traceback.format_exc()) LOG.exception(text)
LOG.warn(f"DELETE {sToxPkOrId} ?")
retval = str(ex) retval = str(ex)
title = util_ui.tr(title) title = util_ui.tr(title)
text = util_ui.tr(text) text = util_ui.tr(text)
@ -586,9 +591,11 @@ class ContactsManager(ToxSave):
self.set_active(0) self.set_active(0)
# filter(lambda c: not c.has_avatar(), self._contacts) # filter(lambda c: not c.has_avatar(), self._contacts)
for (i, contact) in enumerate(self._contacts): for (i, contact) in enumerate(self._contacts):
if not contact: if contact is None:
LOG.warn("_load_contacts NULL contact {i}") LOG.warn(f"_load_contacts NULL contact {i}")
LOG.info(f"_load_contacts deleting NULL {self._contacts[i]}")
del self._contacts[i] del self._contacts[i]
#? self.save_profile()
continue continue
if contact.has_avatar(): continue if contact.has_avatar(): continue
contact.reset_avatar(self._settings['identicons']) contact.reset_avatar(self._settings['identicons'])

View File

@ -17,9 +17,11 @@ class GroupFactory(ToxSave):
self._db = db self._db = db
self._items_factory = items_factory self._items_factory = items_factory
def create_group_by_chat_id(self, chat_id):
return self.create_group_by_public_key(chat_id)
def create_group_by_public_key(self, public_key): def create_group_by_public_key(self, public_key):
group_number = self._get_group_number_by_chat_id(public_key) group_number = self._get_group_number_by_chat_id(public_key)
return self.create_group_by_number(group_number) return self.create_group_by_number(group_number)
def create_group_by_number(self, group_number): def create_group_by_number(self, group_number):

View File

@ -281,14 +281,16 @@ class GroupsService(tox_save.ToxSave):
if invite in self._group_invites: if invite in self._group_invites:
self._group_invites.remove(invite) self._group_invites.remove(invite)
def _join_gc_via_invite(self, invite_data, friend_number, nick, status, password): # status should be dropped
def _join_gc_via_invite(self, invite_data, friend_number, nick, status='', password=''):
LOG.debug(f"_join_gc_via_invite friend_number={friend_number} nick={nick} datalen={len(invite_data)}") LOG.debug(f"_join_gc_via_invite friend_number={friend_number} nick={nick} datalen={len(invite_data)}")
if nick is None: if nick is None:
nick = '' nick = ''
if invite_data is None: if invite_data is None:
invite_data = b'' invite_data = b''
try: try:
group_number = self._tox.group_invite_accept(invite_data, friend_number, nick, status, password) # status should be dropped
group_number = self._tox.group_invite_accept(invite_data, friend_number, nick, password=password)
except Exception as e: except Exception as e:
LOG.error(f"_join_gc_via_invite ERROR {e}") LOG.error(f"_join_gc_via_invite ERROR {e}")
return return

View File

@ -76,7 +76,7 @@ class Messenger(tox_save.ToxSave):
if self._contacts_manager.is_active_a_friend(): if self._contacts_manager.is_active_a_friend():
self.send_message_to_friend(text, message_type) self.send_message_to_friend(text, message_type)
elif self._contacts_manager.is_active_a_group(): elif self._contacts_manager.is_active_a_group():
self.send_message_to_group(text, message_type) self.send_message_to_group('~'+text, message_type)
elif self._contacts_manager.is_active_a_group_chat_peer(): elif self._contacts_manager.is_active_a_group_chat_peer():
self.send_message_to_group_peer(text, message_type) self.send_message_to_group_peer(text, message_type)
else: else:
@ -353,11 +353,12 @@ class Messenger(tox_save.ToxSave):
LOG.warn("_add_message null contact") LOG.warn("_add_message null contact")
return return
if self._contacts_manager.is_contact_active(contact): # add message to list if self._contacts_manager.is_contact_active(contact): # add message to list
# LOG.debug("_add_message is_contact_active(contact)")
self._create_message_item(text_message) self._create_message_item(text_message)
self._screen.messages.scrollToBottom() self._screen.messages.scrollToBottom()
self._contacts_manager.get_curr_contact().append_message(text_message) self._contacts_manager.get_curr_contact().append_message(text_message)
else: else:
LOG.debug("_add_message not is_contact_active(contact)") # LOG.debug("_add_message not is_contact_active(contact)")
contact.inc_messages() contact.inc_messages()
contact.append_message(text_message) contact.append_message(text_message)
if not contact.visibility: if not contact.visibility:

View File

@ -529,27 +529,35 @@ def group_invite(window, settings, tray, profile, groups_service, contacts_provi
def group_self_join(contacts_provider, contacts_manager, groups_service): def group_self_join(contacts_provider, contacts_manager, groups_service):
sSlot = 'group_self_join' sSlot = 'group_self_join'
def wrapped(tox, group_number, user_data): def wrapped(tox, group_number, user_data):
if group_number is None:
LOG_ERROR(f"group_self_join NULL group_number #{group_number}")
return
LOG_DEBUG(f"group_self_join #{group_number}")
key = f"group_number {group_number}" key = f"group_number {group_number}"
if bTooSoon(key, sSlot, 10): return if bTooSoon(key, sSlot, 10): return
LOG_DEBUG(f"group_self_join #{group_number}")
group = contacts_provider.get_group_by_number(group_number) group = contacts_provider.get_group_by_number(group_number)
if group is None:
LOG_ERROR(f"group_self_join NULL group #{group}")
return
invoke_in_main_thread(group.set_status, TOX_USER_STATUS['NONE']) invoke_in_main_thread(group.set_status, TOX_USER_STATUS['NONE'])
invoke_in_main_thread(groups_service.update_group_info, group) invoke_in_main_thread(groups_service.update_group_info, group)
invoke_in_main_thread(contacts_manager.update_filtration) invoke_in_main_thread(contacts_manager.update_filtration)
return wrapped return wrapped
def group_peer_join(contacts_provider, groups_service): def group_peer_join(contacts_provider, groups_service):
sSlot = "group_peer_join" sSlot = "group_peer_join"
def wrapped(tox, group_number, peer_id, user_data): def wrapped(tox, group_number, peer_id, user_data):
key = f"group_peer_join #{group_number} peer_id={peer_id}" key = f"group_peer_join #{group_number} peer_id={peer_id}"
if bTooSoon(key, sSlot, 20): return if bTooSoon(key, sSlot, 20): return
group = contacts_provider.get_group_by_number(group_number) group = contacts_provider.get_group_by_number(group_number)
if group is None:
LOG_ERROR(f"group_peer_join NULL group #{group} group_number={group_number}")
return
if peer_id > group._peers_limit: if peer_id > group._peers_limit:
LOG_ERROR(key +f" {peer_id} > {group._peers_limit}") LOG_ERROR(key +f" {peer_id} > {group._peers_limit}")
return return
LOG_DEBUG(key) LOG_DEBUG(f"group_peer_join group={group}")
group.add_peer(peer_id) group.add_peer(peer_id)
invoke_in_main_thread(groups_service.generate_peers_list) invoke_in_main_thread(groups_service.generate_peers_list)
invoke_in_main_thread(groups_service.update_group_info, group) invoke_in_main_thread(groups_service.update_group_info, group)

View File

@ -63,7 +63,7 @@ class IncomingCallWidget(widgets.CenteredWidget):
self.accept_video.clicked.connect(self.accept_call_with_video) self.accept_video.clicked.connect(self.accept_call_with_video)
self.decline.clicked.connect(self.decline_call) self.decline.clicked.connect(self.decline_call)
output_device_index = self._settings._args.audio['output'] output_device_index = self._settings._oArgs.audio['output']
if False and self._settings['calls_sound']: if False and self._settings['calls_sound']:
class SoundPlay(QtCore.QThread): class SoundPlay(QtCore.QThread):

View File

@ -3,6 +3,9 @@ from PyQt5 import QtCore, QtGui, QtWidgets
import utils.ui as util_ui import utils.ui as util_ui
import logging import logging
global LOG
LOG = logging.getLogger('app')
class DataLabel(QtWidgets.QLabel): class DataLabel(QtWidgets.QLabel):
""" """
Label with elided text Label with elided text
@ -11,13 +14,17 @@ class DataLabel(QtWidgets.QLabel):
try: try:
text = ''.join('\u25AF' if len(bytes(str(c), 'utf-8')) >= 4 else c for c in str(text)) text = ''.join('\u25AF' if len(bytes(str(c), 'utf-8')) >= 4 else c for c in str(text))
except Exception as e: except Exception as e:
logging.error(f"DataLabel::setText: {e}") LOG.error(f"DataLabel::setText: {e}")
return return
metrics = QtGui.QFontMetrics(self.font()) try:
text = metrics.elidedText(str(text), QtCore.Qt.ElideRight, self.width()) metrics = QtGui.QFontMetrics(self.font())
super().setText(text) text = metrics.elidedText(str(text), QtCore.Qt.ElideRight, self.width())
except Exception as e:
# RuntimeError: wrapped C/C++ object of type DataLabel has been deleted
text = str(text)
super().setText(text)
class ComboBox(QtWidgets.QComboBox): class ComboBox(QtWidgets.QComboBox):

View File

@ -138,6 +138,7 @@ class Settings(dict):
self._profile_path = path.replace('.json', '.tox') self._profile_path = path.replace('.json', '.tox')
self._toxes = toxes self._toxes = toxes
self._app = app self._app = app
self._args = app._oArgs
self._oArgs = app._oArgs self._oArgs = app._oArgs
self._log = lambda l: LOG.log(self._oArgs.loglevel, l) self._log = lambda l: LOG.log(self._oArgs.loglevel, l)