fixes
This commit is contained in:
parent
9e037f13c0
commit
be6eb0e2a9
18 changed files with 135 additions and 71 deletions
25
ToDo.md
25
ToDo.md
|
@ -16,24 +16,29 @@ The code is in there but it's not working.
|
||||||
I may have broken it trying to wire up the ability to
|
I may have broken it trying to wire up the ability to
|
||||||
set the audio device from the command line.
|
set the audio device from the command line.
|
||||||
|
|
||||||
## Group peer_id
|
## Groups
|
||||||
|
|
||||||
There has been a change of API on a field named group.peer_id
|
1. peer_id There has been a change of API on a field named
|
||||||
The code is broken in places because I have not seen the path
|
```group.peer_id``` The code is broken in places because I have not
|
||||||
to change from the old API ro the new one.
|
seen the path to change from the old API ro the new one.
|
||||||
|
|
||||||
|
2. There is no way to delete a group in the UI
|
||||||
|
|
||||||
|
3. Distinguish between Frieds, Groups and Whispers in the UI.
|
||||||
|
|
||||||
## Plugin system
|
## Plugin system
|
||||||
|
|
||||||
Needs better documentation and checking.
|
1. Needs better documentation and checking.
|
||||||
There's something broken in the way some of them plug into Qt menus.
|
|
||||||
|
|
||||||
Should the plugins be in toxygen or a separate repo?
|
2. There's something broken in the way some of them plug into Qt menus.
|
||||||
|
|
||||||
|
3. Should the plugins be in toxygen or a separate repo?
|
||||||
|
|
||||||
## check toxygen_wrapper
|
## check toxygen_wrapper
|
||||||
|
|
||||||
I've broken out toxygen_wrapper to be standalone,
|
1. I've broken out toxygen_wrapper to be standalone,
|
||||||
https://git.plastiras.org/emdee/toxygen_wrapper
|
https://git.plastiras.org/emdee/toxygen_wrapper but the tox.py
|
||||||
but the tox.py needs each call double checking.
|
needs each call double checking.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ def setup_logging(oArgs):
|
||||||
setattr(oArgs, 'log_oFd', oFd)
|
setattr(oArgs, 'log_oFd', oFd)
|
||||||
aKw['stream'] = oFd
|
aKw['stream'] = oFd
|
||||||
coloredlogs.install(**aKw)
|
coloredlogs.install(**aKw)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
aKw = dict(level=oArgs.loglevel,
|
aKw = dict(level=oArgs.loglevel,
|
||||||
format='%(name)s %(levelname)-4s %(message)s')
|
format='%(name)s %(levelname)-4s %(message)s')
|
||||||
|
@ -162,6 +162,7 @@ class App:
|
||||||
LOG.info("Starting toxygen version " +version)
|
LOG.info("Starting toxygen version " +version)
|
||||||
|
|
||||||
self._version = version
|
self._version = version
|
||||||
|
self._tox = None
|
||||||
self._app = self._settings = self._profile_manager = None
|
self._app = self._settings = self._profile_manager = None
|
||||||
self._plugin_loader = self._messenger = None
|
self._plugin_loader = self._messenger = None
|
||||||
self._tox = self._ms = self._init = self._main_loop = self._av_loop = None
|
self._tox = self._ms = self._init = self._main_loop = self._av_loop = None
|
||||||
|
@ -268,7 +269,7 @@ class App:
|
||||||
if hasattr(oArgs, 'log_oFd'):
|
if hasattr(oArgs, 'log_oFd'):
|
||||||
oArgs.log_oFd.close()
|
oArgs.log_oFd.close()
|
||||||
delattr(oArgs, 'log_oFd')
|
delattr(oArgs, 'log_oFd')
|
||||||
|
|
||||||
# failsafe: segfaults on exit
|
# failsafe: segfaults on exit
|
||||||
if hasattr(self, '_tox'):
|
if hasattr(self, '_tox'):
|
||||||
if self._tox and hasattr(self._tox, 'kill'):
|
if self._tox and hasattr(self._tox, 'kill'):
|
||||||
|
@ -777,6 +778,7 @@ class App:
|
||||||
retval = tox_factory(data=data, settings=settings_,
|
retval = tox_factory(data=data, settings=settings_,
|
||||||
args=self._args, app=self)
|
args=self._args, app=self)
|
||||||
LOG.debug("_create_tox succeeded")
|
LOG.debug("_create_tox succeeded")
|
||||||
|
self._tox = retval
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def _force_exit(self, retval=0):
|
def _force_exit(self, retval=0):
|
||||||
|
@ -925,7 +927,7 @@ class App:
|
||||||
shuffle(lElts)
|
shuffle(lElts)
|
||||||
LOG.debug(f"_test_bootstrap #Elts={len(lElts)}")
|
LOG.debug(f"_test_bootstrap #Elts={len(lElts)}")
|
||||||
LOG.trace(f"_test_bootstrap lElts={lElts[:8]}")
|
LOG.trace(f"_test_bootstrap lElts={lElts[:8]}")
|
||||||
shuffle(env['lElts'])
|
shuffle(env['lElts'])
|
||||||
for host,port,key in lElts[:8]:
|
for host,port,key in lElts[:8]:
|
||||||
try:
|
try:
|
||||||
assert len(key) == 64, key
|
assert len(key) == 64, key
|
||||||
|
|
|
@ -101,7 +101,7 @@ class AV(common.tox_save.ToxAvSave):
|
||||||
def accept_call(self, friend_number, audio_enabled, video_enabled):
|
def accept_call(self, friend_number, audio_enabled, video_enabled):
|
||||||
# obsolete
|
# obsolete
|
||||||
return call_accept_call(self, friend_number, audio_enabled, video_enabled)
|
return call_accept_call(self, friend_number, audio_enabled, video_enabled)
|
||||||
|
|
||||||
def call_accept_call(self, friend_number, audio_enabled, video_enabled):
|
def call_accept_call(self, friend_number, audio_enabled, video_enabled):
|
||||||
LOG.debug(f"call_accept_call from {friend_number} {self._running}" +
|
LOG.debug(f"call_accept_call from {friend_number} {self._running}" +
|
||||||
f"{audio_enabled} {video_enabled}")
|
f"{audio_enabled} {video_enabled}")
|
||||||
|
@ -304,7 +304,7 @@ class AV(common.tox_save.ToxAvSave):
|
||||||
LOG.info("start_video_thread " \
|
LOG.info("start_video_thread " \
|
||||||
+f" device: {s['video']['device']}" \
|
+f" device: {s['video']['device']}" \
|
||||||
+f" supported: {s['video']['width']} {s['video']['height']}")
|
+f" supported: {s['video']['width']} {s['video']['height']}")
|
||||||
|
|
||||||
self._video_running = True
|
self._video_running = True
|
||||||
self._video_thread = BaseThread(target=self.send_video,
|
self._video_thread = BaseThread(target=self.send_video,
|
||||||
name='_video_thread')
|
name='_video_thread')
|
||||||
|
|
|
@ -114,7 +114,7 @@ class CallsManager:
|
||||||
util_ui.tr('ERROR Accepting call from {friend_number}'))
|
util_ui.tr('ERROR Accepting call from {friend_number}'))
|
||||||
else:
|
else:
|
||||||
self._main_screen.active_call()
|
self._main_screen.active_call()
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
# does not terminate call - just the av_widget
|
# does not terminate call - just the av_widget
|
||||||
if friend_number in self._incoming_calls:
|
if friend_number in self._incoming_calls:
|
||||||
|
@ -127,7 +127,7 @@ class CallsManager:
|
||||||
|
|
||||||
pass
|
pass
|
||||||
LOG.debug(f" closed self._call_widgets[{friend_number}]")
|
LOG.debug(f" closed self._call_widgets[{friend_number}]")
|
||||||
|
|
||||||
def stop_call(self, friend_number, by_friend):
|
def stop_call(self, friend_number, by_friend):
|
||||||
"""
|
"""
|
||||||
Stop call with friend
|
Stop call with friend
|
||||||
|
|
|
@ -44,7 +44,7 @@ class ContactsManager(ToxSave):
|
||||||
try:
|
try:
|
||||||
self._ms._log(s)
|
self._ms._log(s)
|
||||||
except: pass
|
except: pass
|
||||||
|
|
||||||
def get_contact(self, num):
|
def get_contact(self, num):
|
||||||
if num < 0 or num >= len(self._contacts):
|
if num < 0 or num >= len(self._contacts):
|
||||||
return None
|
return None
|
||||||
|
@ -254,10 +254,14 @@ class ContactsManager(ToxSave):
|
||||||
group = self.get_group_by_number(group_number)
|
group = self.get_group_by_number(group_number)
|
||||||
peer = group.get_peer_by_id(peer_id)
|
peer = group.get_peer_by_id(peer_id)
|
||||||
if peer: # broken
|
if peer: # broken
|
||||||
if not self.check_if_contact_exists(peer.public_key):
|
if hasattr(peer, 'public_key'):
|
||||||
self.add_group_peer(group, peer)
|
LOG.error(f'no peer public_key ' + repr(dir(peer)))
|
||||||
|
else:
|
||||||
return self.get_contact_by_tox_id(peer.public_key)
|
if not self.check_if_contact_exists(peer.public_key):
|
||||||
|
self.add_group_peer(group, peer)
|
||||||
|
return self.get_contact_by_tox_id(peer.public_key)
|
||||||
|
else:
|
||||||
|
LOG.warn(f'no peer group_number={group_number}')
|
||||||
|
|
||||||
def check_if_contact_exists(self, tox_id):
|
def check_if_contact_exists(self, tox_id):
|
||||||
return any(filter(lambda c: c.tox_id == tox_id, self._contacts))
|
return any(filter(lambda c: c.tox_id == tox_id, self._contacts))
|
||||||
|
@ -455,7 +459,7 @@ class ContactsManager(ToxSave):
|
||||||
title = 'Friend failed'
|
title = 'Friend failed'
|
||||||
text = 'Friend failed sending friend request'
|
text = 'Friend failed sending friend request'
|
||||||
retval = text
|
retval = text
|
||||||
|
|
||||||
except Exception as ex: # wrong data
|
except Exception as ex: # wrong data
|
||||||
title = 'Friend add exception'
|
title = 'Friend add exception'
|
||||||
text = 'Friend request exception with ' + str(ex)
|
text = 'Friend request exception with ' + str(ex)
|
||||||
|
@ -466,7 +470,7 @@ class ContactsManager(ToxSave):
|
||||||
text = util_ui.tr(text)
|
text = util_ui.tr(text)
|
||||||
util_ui.message_box(text, title)
|
util_ui.message_box(text, title)
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def process_friend_request(self, tox_id, message):
|
def process_friend_request(self, tox_id, message):
|
||||||
"""
|
"""
|
||||||
Accept or ignore friend request
|
Accept or ignore friend request
|
||||||
|
|
|
@ -86,7 +86,7 @@ class GroupChat(contact.Contact, ToxSave):
|
||||||
if peer_id > self._peers_limit:
|
if peer_id > self._peers_limit:
|
||||||
LOG_WARN(f"add_peer id={peer_id} > {self._peers_limit}")
|
LOG_WARN(f"add_peer id={peer_id} > {self._peers_limit}")
|
||||||
return
|
return
|
||||||
|
|
||||||
peer = GroupChatPeer(peer_id,
|
peer = GroupChatPeer(peer_id,
|
||||||
self._tox.group_peer_get_name(self._number, peer_id),
|
self._tox.group_peer_get_name(self._number, peer_id),
|
||||||
self._tox.group_peer_get_status(self._number, peer_id),
|
self._tox.group_peer_get_status(self._number, peer_id),
|
||||||
|
|
|
@ -7,6 +7,9 @@ from groups.group_invite import GroupInvite
|
||||||
import wrapper.toxcore_enums_and_consts as constants
|
import wrapper.toxcore_enums_and_consts as constants
|
||||||
from wrapper.toxcore_enums_and_consts import *
|
from wrapper.toxcore_enums_and_consts import *
|
||||||
|
|
||||||
|
global LOG
|
||||||
|
import logging
|
||||||
|
LOG = logging.getLogger('app.'+'gs')
|
||||||
|
|
||||||
class GroupsService(tox_save.ToxSave):
|
class GroupsService(tox_save.ToxSave):
|
||||||
|
|
||||||
|
@ -19,6 +22,8 @@ class GroupsService(tox_save.ToxSave):
|
||||||
self._widgets_factory_provider = widgets_factory_provider
|
self._widgets_factory_provider = widgets_factory_provider
|
||||||
self._group_invites = []
|
self._group_invites = []
|
||||||
self._screen = None
|
self._screen = None
|
||||||
|
# maybe just use self
|
||||||
|
self._tox = tox
|
||||||
|
|
||||||
def set_tox(self, tox):
|
def set_tox(self, tox):
|
||||||
super().set_tox(tox)
|
super().set_tox(tox)
|
||||||
|
@ -30,7 +35,11 @@ class GroupsService(tox_save.ToxSave):
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def create_new_gc(self, name, privacy_state, nick, status):
|
def create_new_gc(self, name, privacy_state, nick, status):
|
||||||
group_number = self._tox.group_new(privacy_state, name, nick, status)
|
try:
|
||||||
|
group_number = self._tox.group_new(privacy_state, name, nick, status)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error(f"create_new_gc {e}")
|
||||||
|
return
|
||||||
if group_number == -1:
|
if group_number == -1:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -48,8 +57,9 @@ class GroupsService(tox_save.ToxSave):
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def leave_group(self, group_number):
|
def leave_group(self, group_number):
|
||||||
self._tox.group_leave(group_number)
|
if type(group_number) == int:
|
||||||
self._contacts_manager.delete_group(group_number)
|
self._tox.group_leave(group_number)
|
||||||
|
self._contacts_manager.delete_group(group_number)
|
||||||
|
|
||||||
def disconnect_from_group(self, group_number):
|
def disconnect_from_group(self, group_number):
|
||||||
self._tox.group_disconnect(group_number)
|
self._tox.group_disconnect(group_number)
|
||||||
|
@ -73,7 +83,7 @@ class GroupsService(tox_save.ToxSave):
|
||||||
e = f"Friend not connected friend_number={friend_number}"
|
e = f"Friend not connected friend_number={friend_number}"
|
||||||
util_ui.message_box(title +'\n' +str(e), title)
|
util_ui.message_box(title +'\n' +str(e), title)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._tox.group_invite_friend(group_number, friend_number)
|
self._tox.group_invite_friend(group_number, friend_number)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -246,8 +256,14 @@ class GroupsService(tox_save.ToxSave):
|
||||||
self._group_invites.remove(invite)
|
self._group_invites.remove(invite)
|
||||||
|
|
||||||
def _join_gc_via_invite(self, invite_data, friend_number, nick, status, password):
|
def _join_gc_via_invite(self, invite_data, friend_number, nick, status, password):
|
||||||
group_number = self._tox.group_invite_accept(invite_data, friend_number, nick, status, password)
|
if nick is None: nick = ''
|
||||||
self._add_new_group_by_number(group_number)
|
if invite_data is None: invite_data = ''
|
||||||
|
try:
|
||||||
|
group_number = self._tox.group_invite_accept(invite_data, friend_number, nick, status, password)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error(f"_join_gc_via_invite {e}")
|
||||||
|
else:
|
||||||
|
self._add_new_group_by_number(group_number)
|
||||||
|
|
||||||
def _update_invites_button_state(self):
|
def _update_invites_button_state(self):
|
||||||
self._main_screen.update_gc_invites_button_state()
|
self._main_screen.update_gc_invites_button_state()
|
||||||
|
|
|
@ -306,13 +306,13 @@ lKEEP_SETTINGS = ['uri',
|
||||||
'loglevel',
|
'loglevel',
|
||||||
'logfile',
|
'logfile',
|
||||||
'mode',
|
'mode',
|
||||||
|
|
||||||
# dunno
|
# dunno
|
||||||
'audio_input',
|
'audio_input',
|
||||||
'audio_output',
|
'audio_output',
|
||||||
'audio',
|
'audio',
|
||||||
'video',
|
'video',
|
||||||
|
|
||||||
'ipv6_enabled',
|
'ipv6_enabled',
|
||||||
'udp_enabled',
|
'udp_enabled',
|
||||||
'local_discovery_enabled',
|
'local_discovery_enabled',
|
||||||
|
@ -378,15 +378,16 @@ def main(lArgs):
|
||||||
#setattr(aArgs, 'video', setup_video(oArgs))
|
#setattr(aArgs, 'video', setup_video(oArgs))
|
||||||
aArgs.video = setup_video(oArgs)
|
aArgs.video = setup_video(oArgs)
|
||||||
assert 'video' in aArgs.__dict__
|
assert 'video' in aArgs.__dict__
|
||||||
|
|
||||||
#setattr(aArgs, 'audio', setup_audio(oArgs))
|
#setattr(aArgs, 'audio', setup_audio(oArgs))
|
||||||
aArgs.audio = setup_audio(oArgs)
|
aArgs.audio = setup_audio(oArgs)
|
||||||
assert 'audio' in aArgs.__dict__
|
assert 'audio' in aArgs.__dict__
|
||||||
oArgs = aArgs
|
oArgs = aArgs
|
||||||
|
|
||||||
toxygen = app.App(__version__, oArgs)
|
toxygen = app.App(__version__, oArgs)
|
||||||
global oAPP
|
global oAPP
|
||||||
oAPP = toxygen
|
oAPP = toxygen
|
||||||
|
__builtins__['app'] = toxygen
|
||||||
i = toxygen.iMain()
|
i = toxygen.iMain()
|
||||||
return i
|
return i
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ def friend_status_message(contacts_manager, messenger):
|
||||||
friend = contacts_manager.get_friend_by_number(friend_number)
|
friend = contacts_manager.get_friend_by_number(friend_number)
|
||||||
key = f"friend_number={friend_number}"
|
key = f"friend_number={friend_number}"
|
||||||
if bTooSoon(key, sSlot, 10): return
|
if bTooSoon(key, sSlot, 10): return
|
||||||
|
|
||||||
invoke_in_main_thread(friend.set_status_message, str(status_message, 'utf-8'))
|
invoke_in_main_thread(friend.set_status_message, str(status_message, 'utf-8'))
|
||||||
LOG_DEBUG(f'User #{friend_number} has new status message')
|
LOG_DEBUG(f'User #{friend_number} has new status message')
|
||||||
invoke_in_main_thread(messenger.send_messages, friend_number)
|
invoke_in_main_thread(messenger.send_messages, friend_number)
|
||||||
|
@ -480,7 +480,7 @@ def group_private_message(window, tray, tox, messenger, settings, profile):
|
||||||
if settings['sound_notifications'] and bl and profile.status != TOX_USER_STATUS['BUSY']:
|
if settings['sound_notifications'] and bl and profile.status != TOX_USER_STATUS['BUSY']:
|
||||||
sound_notification(SOUND_NOTIFICATION['MESSAGE'])
|
sound_notification(SOUND_NOTIFICATION['MESSAGE'])
|
||||||
icon = util.join_path(util.get_images_directory(), 'icon_new_messages.png')
|
icon = util.join_path(util.get_images_directory(), 'icon_new_messages.png')
|
||||||
if tray and hasattr(tray, 'setIcon'):
|
if tray and hasattr(tray, 'setIcon'):
|
||||||
invoke_in_main_thread(tray.setIcon, QtGui.QIcon(icon))
|
invoke_in_main_thread(tray.setIcon, QtGui.QIcon(icon))
|
||||||
|
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
|
@ -119,11 +119,11 @@ class InitThread(BaseThread):
|
||||||
args=list(),
|
args=list(),
|
||||||
kwargs=dict(lElts=None, oThread=self, iMax=2)
|
kwargs=dict(lElts=None, oThread=self, iMax=2)
|
||||||
).start()
|
).start()
|
||||||
|
|
||||||
if self._is_first_start:
|
if self._is_first_start:
|
||||||
LOG_INFO('starting plugins')
|
LOG_INFO('starting plugins')
|
||||||
self._plugin_loader.load()
|
self._plugin_loader.load()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG_DEBUG(f"InitThread run: ERROR {e}")
|
LOG_DEBUG(f"InitThread run: ERROR {e}")
|
||||||
pass
|
pass
|
||||||
|
@ -157,7 +157,7 @@ class ToxAVIterateThread(BaseQThread):
|
||||||
def __init__(self, toxav):
|
def __init__(self, toxav):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._toxav = toxav
|
self._toxav = toxav
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
LOG_DEBUG('ToxAVIterateThread run: ')
|
LOG_DEBUG('ToxAVIterateThread run: ')
|
||||||
while not self._stop_thread:
|
while not self._stop_thread:
|
||||||
|
|
|
@ -50,7 +50,7 @@ class GroupBansScreen(CenteredWidget):
|
||||||
def _retranslate_ui(self):
|
def _retranslate_ui(self):
|
||||||
# self.setWindowTitle(util_ui.tr('Bans list for group "{}"').format(self._group.name))
|
# self.setWindowTitle(util_ui.tr('Bans list for group "{}"').format(self._group.name))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _refresh_bans_list(self):
|
def _refresh_bans_list(self):
|
||||||
self.bansListWidget.clear()
|
self.bansListWidget.clear()
|
||||||
can_cancel_ban = self._group.is_self_moderator_or_founder()
|
can_cancel_ban = self._group.is_self_moderator_or_founder()
|
||||||
|
|
|
@ -27,6 +27,7 @@ class GroupInvitesScreen(CenteredWidget):
|
||||||
self._groups_service = groups_service
|
self._groups_service = groups_service
|
||||||
self._profile = profile
|
self._profile = profile
|
||||||
self._contacts_provider = contacts_provider
|
self._contacts_provider = contacts_provider
|
||||||
|
self._tox = self._groups_service._tox
|
||||||
|
|
||||||
uic.loadUi(util.get_views_path('group_invites_screen'), self)
|
uic.loadUi(util.get_views_path('group_invites_screen'), self)
|
||||||
|
|
||||||
|
@ -68,6 +69,8 @@ class GroupInvitesScreen(CenteredWidget):
|
||||||
password = self.passwordLineEdit.text()
|
password = self.passwordLineEdit.text()
|
||||||
status = self.statusComboBox.currentIndex()
|
status = self.statusComboBox.currentIndex()
|
||||||
|
|
||||||
|
if not nick:
|
||||||
|
nick = self._tox.self_get_name()
|
||||||
selected_invites = self._get_selected_invites()
|
selected_invites = self._get_selected_invites()
|
||||||
for invite in selected_invites:
|
for invite in selected_invites:
|
||||||
self._groups_service.accept_group_invite(invite, nick, status, password)
|
self._groups_service.accept_group_invite(invite, nick, status, password)
|
||||||
|
@ -90,7 +93,7 @@ class GroupInvitesScreen(CenteredWidget):
|
||||||
for index in range(items_count):
|
for index in range(items_count):
|
||||||
list_item = self.invitesListWidget.item(index)
|
list_item = self.invitesListWidget.item(index)
|
||||||
item_widget = self.invitesListWidget.itemWidget(list_item)
|
item_widget = self.invitesListWidget.itemWidget(list_item)
|
||||||
if item_widget.is_selected():
|
if item_widget and item_widget.is_selected():
|
||||||
selected.append(all_invites[index])
|
selected.append(all_invites[index])
|
||||||
|
|
||||||
return selected
|
return selected
|
||||||
|
|
|
@ -3,7 +3,6 @@ from PyQt5 import uic
|
||||||
import utils.util as util
|
import utils.util as util
|
||||||
import utils.ui as util_ui
|
import utils.ui as util_ui
|
||||||
|
|
||||||
|
|
||||||
class GroupManagementScreen(CenteredWidget):
|
class GroupManagementScreen(CenteredWidget):
|
||||||
|
|
||||||
def __init__(self, groups_service, group):
|
def __init__(self, groups_service, group):
|
||||||
|
@ -21,6 +20,7 @@ class GroupManagementScreen(CenteredWidget):
|
||||||
self.privacyStateComboBox.setCurrentIndex(1 if self._group.is_private else 0)
|
self.privacyStateComboBox.setCurrentIndex(1 if self._group.is_private else 0)
|
||||||
self.peersLimitSpinBox.setValue(self._group.peers_limit)
|
self.peersLimitSpinBox.setValue(self._group.peers_limit)
|
||||||
|
|
||||||
|
self.deletePushButton.clicked.connect(self._delete)
|
||||||
self.savePushButton.clicked.connect(self._save)
|
self.savePushButton.clicked.connect(self._save)
|
||||||
|
|
||||||
def _retranslate_ui(self):
|
def _retranslate_ui(self):
|
||||||
|
@ -28,12 +28,21 @@ class GroupManagementScreen(CenteredWidget):
|
||||||
self.passwordLabel.setText(util_ui.tr('Password:'))
|
self.passwordLabel.setText(util_ui.tr('Password:'))
|
||||||
self.peerLimitLabel.setText(util_ui.tr('Peer limit:'))
|
self.peerLimitLabel.setText(util_ui.tr('Peer limit:'))
|
||||||
self.privacyStateLabel.setText(util_ui.tr('Privacy state:'))
|
self.privacyStateLabel.setText(util_ui.tr('Privacy state:'))
|
||||||
|
self.deletePushButton.setText(util_ui.tr('Delete'))
|
||||||
self.savePushButton.setText(util_ui.tr('Save'))
|
self.savePushButton.setText(util_ui.tr('Save'))
|
||||||
|
|
||||||
self.privacyStateComboBox.clear()
|
self.privacyStateComboBox.clear()
|
||||||
self.privacyStateComboBox.addItem(util_ui.tr('Public'))
|
self.privacyStateComboBox.addItem(util_ui.tr('Public'))
|
||||||
self.privacyStateComboBox.addItem(util_ui.tr('Private'))
|
self.privacyStateComboBox.addItem(util_ui.tr('Private'))
|
||||||
|
|
||||||
|
def _delete(self):
|
||||||
|
self._groups_service.leave_group(self._group.number)
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def _disconnect(self):
|
||||||
|
self._groups_service.disconnect_from_group(self._group.number)
|
||||||
|
self.close()
|
||||||
|
|
||||||
def _save(self):
|
def _save(self):
|
||||||
password = self.passwordLineEdit.text()
|
password = self.passwordLineEdit.text()
|
||||||
privacy_state = self.privacyStateComboBox.currentIndex()
|
privacy_state = self.privacyStateComboBox.currentIndex()
|
||||||
|
|
|
@ -76,13 +76,16 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self._contacts_manager = None
|
self._contacts_manager = None
|
||||||
self._tray = tray
|
self._tray = tray
|
||||||
self._app = app
|
self._app = app
|
||||||
|
self._tox = app._tox
|
||||||
self._widget_factory = None
|
self._widget_factory = None
|
||||||
self._modal_window = None
|
self._modal_window = None
|
||||||
self._plugins_loader = None
|
self._plugins_loader = None
|
||||||
self.setAcceptDrops(True)
|
self.setAcceptDrops(True)
|
||||||
self._saved = False
|
self._saved = False
|
||||||
self._smiley_window = None
|
self._smiley_window = None
|
||||||
self._profile = self._toxes = self._messenger = None
|
self._profile = None
|
||||||
|
self._toxes = None
|
||||||
|
self._messenger = None
|
||||||
self._file_transfer_handler = self._history_loader = self._groups_service = self._calls_manager = None
|
self._file_transfer_handler = self._history_loader = self._groups_service = self._calls_manager = None
|
||||||
self._should_show_group_peers_list = False
|
self._should_show_group_peers_list = False
|
||||||
self.initUI()
|
self.initUI()
|
||||||
|
@ -91,6 +94,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
# take a rough guess of 2/3 the default width at the default font
|
# take a rough guess of 2/3 the default width at the default font
|
||||||
iMAX = settings['width'] * 2/3 / settings['message_font_size']
|
iMAX = settings['width'] * 2/3 / settings['message_font_size']
|
||||||
self._me = LogDialog(self, app)
|
self._me = LogDialog(self, app)
|
||||||
|
self._pe = None
|
||||||
|
|
||||||
def set_dependencies(self, widget_factory, tray, contacts_manager, messenger, profile, plugins_loader,
|
def set_dependencies(self, widget_factory, tray, contacts_manager, messenger, profile, plugins_loader,
|
||||||
file_transfer_handler, history_loader, calls_manager, groups_service, toxes, app):
|
file_transfer_handler, history_loader, calls_manager, groups_service, toxes, app):
|
||||||
|
@ -159,6 +163,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
self.actionLog_console = QtWidgets.QAction(window)
|
self.actionLog_console = QtWidgets.QAction(window)
|
||||||
self.actionLog_console.setObjectName("actionLog_console")
|
self.actionLog_console.setObjectName("actionLog_console")
|
||||||
|
self.actionPython_console = QtWidgets.QAction(window)
|
||||||
|
self.actionPython_console.setObjectName("actionLog_console")
|
||||||
self.updateSettings = QtWidgets.QAction(window)
|
self.updateSettings = QtWidgets.QAction(window)
|
||||||
self.actionSettings = QtWidgets.QAction(window)
|
self.actionSettings = QtWidgets.QAction(window)
|
||||||
self.actionSettings.setObjectName("actionSettings")
|
self.actionSettings.setObjectName("actionSettings")
|
||||||
|
@ -196,6 +202,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.menuPlugins.addAction(self.reloadPlugins)
|
self.menuPlugins.addAction(self.reloadPlugins)
|
||||||
self.menuPlugins.addAction(self.reloadToxchat)
|
self.menuPlugins.addAction(self.reloadToxchat)
|
||||||
self.menuPlugins.addAction(self.actionLog_console)
|
self.menuPlugins.addAction(self.actionLog_console)
|
||||||
|
self.menuPlugins.addAction(self.actionPython_console)
|
||||||
|
|
||||||
self.menuAbout.addAction(self.actionAbout_program)
|
self.menuAbout.addAction(self.actionAbout_program)
|
||||||
|
|
||||||
|
@ -211,6 +218,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.actionQuit_program.triggered.connect(self.quit_program)
|
self.actionQuit_program.triggered.connect(self.quit_program)
|
||||||
self.actionAbout_program.triggered.connect(self.about_program)
|
self.actionAbout_program.triggered.connect(self.about_program)
|
||||||
self.actionLog_console.triggered.connect(self.log_console)
|
self.actionLog_console.triggered.connect(self.log_console)
|
||||||
|
self.actionPython_console.triggered.connect(self.python_console)
|
||||||
self.actionNetwork.triggered.connect(self.network_settings)
|
self.actionNetwork.triggered.connect(self.network_settings)
|
||||||
self.actionAdd_friend.triggered.connect(self.add_contact_triggered)
|
self.actionAdd_friend.triggered.connect(self.add_contact_triggered)
|
||||||
self.createGC.triggered.connect(self.create_gc)
|
self.createGC.triggered.connect(self.create_gc)
|
||||||
|
@ -264,6 +272,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.actionNetwork.setText(util_ui.tr("Network"))
|
self.actionNetwork.setText(util_ui.tr("Network"))
|
||||||
self.actionAbout_program.setText(util_ui.tr("About program"))
|
self.actionAbout_program.setText(util_ui.tr("About program"))
|
||||||
self.actionLog_console.setText(util_ui.tr("Console Log"))
|
self.actionLog_console.setText(util_ui.tr("Console Log"))
|
||||||
|
self.actionPython_console.setText(util_ui.tr("Python Console"))
|
||||||
self.actionTest_tox.setText(util_ui.tr("Bootstrap"))
|
self.actionTest_tox.setText(util_ui.tr("Bootstrap"))
|
||||||
self.actionTest_socks.setText(util_ui.tr("Test program"))
|
self.actionTest_socks.setText(util_ui.tr("Test program"))
|
||||||
self.actionQuit_program.setText(util_ui.tr("Quit program"))
|
self.actionQuit_program.setText(util_ui.tr("Quit program"))
|
||||||
|
@ -554,6 +563,18 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
def log_console(self):
|
def log_console(self):
|
||||||
self._me.show()
|
self._me.show()
|
||||||
|
|
||||||
|
def python_console(self):
|
||||||
|
try:
|
||||||
|
if not self._pe:
|
||||||
|
from pyqtconsole.console import PythonConsole
|
||||||
|
self._pe = PythonConsole(sFont="Courier New", bBold=True)
|
||||||
|
self._pe.show()
|
||||||
|
self._pe.eval_queued()
|
||||||
|
# self._pe.eval_in_thread()
|
||||||
|
except Exception as e:
|
||||||
|
LOG.debug(e)
|
||||||
|
self._me.show()
|
||||||
|
|
||||||
def about_program(self):
|
def about_program(self):
|
||||||
# TODO: replace with window
|
# TODO: replace with window
|
||||||
text = util_ui.tr('Toxygen is Tox client written in Python.\nVersion: ')
|
text = util_ui.tr('Toxygen is Tox client written in Python.\nVersion: ')
|
||||||
|
|
|
@ -43,7 +43,7 @@ class AddContact(CenteredWidget):
|
||||||
if self._bootstrap:
|
if self._bootstrap:
|
||||||
return
|
return
|
||||||
self._bootstrap = True
|
self._bootstrap = True
|
||||||
|
|
||||||
def _add_friend(self):
|
def _add_friend(self):
|
||||||
if self._adding:
|
if self._adding:
|
||||||
return
|
return
|
||||||
|
@ -497,7 +497,7 @@ class AudioSettings(CenteredWidget):
|
||||||
uic.loadUi(get_views_path('audio_settings_screen'), self)
|
uic.loadUi(get_views_path('audio_settings_screen'), self)
|
||||||
self._update_ui()
|
self._update_ui()
|
||||||
self.center()
|
self.center()
|
||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
if 'audio' not in self._settings:
|
if 'audio' not in self._settings:
|
||||||
ex = f"self._settings=id(self._settings) {self._settings!r}"
|
ex = f"self._settings=id(self._settings) {self._settings!r}"
|
||||||
|
@ -618,7 +618,7 @@ class VideoSettings(CenteredWidget):
|
||||||
|
|
||||||
if 'device' not in self._settings['video']:
|
if 'device' not in self._settings['video']:
|
||||||
LOG.warn(f"'device' not in self._settings['video']: {self._settings!r}")
|
LOG.warn(f"'device' not in self._settings['video']: {self._settings!r}")
|
||||||
self._settings['video']['device'] = self._devices[-1]
|
self._settings['video']['device'] = self._devices[-1]
|
||||||
iIndex = self._settings['video']['device']
|
iIndex = self._settings['video']['device']
|
||||||
try:
|
try:
|
||||||
index = self._devices.index(iIndex)
|
index = self._devices.index(iIndex)
|
||||||
|
@ -628,7 +628,7 @@ class VideoSettings(CenteredWidget):
|
||||||
se = f"Video devices index error: index={iIndex} {e}"
|
se = f"Video devices index error: index={iIndex} {e}"
|
||||||
LOG.warn(se)
|
LOG.warn(se)
|
||||||
# util_ui.message_box(se, util_ui.tr(f"ERROR: Video devices error"))
|
# util_ui.message_box(se, util_ui.tr(f"ERROR: Video devices error"))
|
||||||
self._settings['video']['device'] = self._devices[-1]
|
self._settings['video']['device'] = self._devices[-1]
|
||||||
|
|
||||||
self._retranslate_ui()
|
self._retranslate_ui()
|
||||||
|
|
||||||
|
|
|
@ -412,4 +412,4 @@ class Settings(dict):
|
||||||
if key in aArgs.__dict__ and info[key] != val:
|
if key in aArgs.__dict__ and info[key] != val:
|
||||||
aRet[key] = val
|
aRet[key] = val
|
||||||
return aRet
|
return aRet
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
from ctypes import CDLL
|
from ctypes import CDLL
|
||||||
|
|
||||||
# You need a libs directory beside this directory
|
# You need a libs directory beside this directory
|
||||||
# and you need to link your libtoxcore.so and libtoxav.so
|
# and you need to link your libtoxcore.so and libtoxav.so
|
||||||
# and libtoxencryptsave.so into ../libs/
|
# and libtoxencryptsave.so into ../libs/
|
||||||
# Link all 3 to libtoxcore.so if you have only libtoxcore.so
|
# Link all 3 to libtoxcore.so if you have only libtoxcore.so
|
||||||
|
@ -13,7 +13,7 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sLIBS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)),
|
sLIBS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)),
|
||||||
'libs')
|
'libs')
|
||||||
|
|
||||||
class LibToxCore:
|
class LibToxCore:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -40,11 +40,11 @@ class LibToxCore:
|
||||||
class LibToxAV:
|
class LibToxAV:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
platform = util.get_platform()
|
platform = sys.platform
|
||||||
if platform == 'Windows':
|
if platform == 'win32':
|
||||||
# on Windows av api is in libtox.dll
|
# on Windows av api is in libtox.dll
|
||||||
self._libtoxav = CDLL(os.path.join(sLIBS_DIR, 'libtox.dll'))
|
self._libtoxav = CDLL(os.path.join(sLIBS_DIR, 'libtox.dll'))
|
||||||
elif platform == 'Darwin':
|
elif platform == 'darwin':
|
||||||
self._libtoxav = CDLL('libtoxcore.dylib')
|
self._libtoxav = CDLL('libtoxcore.dylib')
|
||||||
else:
|
else:
|
||||||
libFile = os.path.join(sLIBS_DIR, 'libtoxav.so')
|
libFile = os.path.join(sLIBS_DIR, 'libtoxav.so')
|
||||||
|
|
|
@ -172,7 +172,7 @@ class Tox:
|
||||||
LOG_ERROR(f"tox_kill {e!s}")
|
LOG_ERROR(f"tox_kill {e!s}")
|
||||||
else:
|
else:
|
||||||
LOG_DEBUG(f"tox_kill")
|
LOG_DEBUG(f"tox_kill")
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Startup options
|
# Startup options
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -287,7 +287,7 @@ class Tox:
|
||||||
LOG_ERROR(f"libtoxcore.tox_bootstrap {e}")
|
LOG_ERROR(f"libtoxcore.tox_bootstrap {e}")
|
||||||
# dunno
|
# dunno
|
||||||
raise
|
raise
|
||||||
|
|
||||||
tox_err_bootstrap = tox_err_bootstrap.value
|
tox_err_bootstrap = tox_err_bootstrap.value
|
||||||
if tox_err_bootstrap == TOX_ERR_BOOTSTRAP['OK']:
|
if tox_err_bootstrap == TOX_ERR_BOOTSTRAP['OK']:
|
||||||
return bool(result)
|
return bool(result)
|
||||||
|
@ -776,7 +776,7 @@ class Tox:
|
||||||
if friend_list is None:
|
if friend_list is None:
|
||||||
friend_list = create_string_buffer(sizeof(c_uint32) * friend_list_size)
|
friend_list = create_string_buffer(sizeof(c_uint32) * friend_list_size)
|
||||||
friend_list = POINTER(c_uint32)(friend_list)
|
friend_list = POINTER(c_uint32)(friend_list)
|
||||||
LOG_DEBUG(f"tox_self_get_friend_list")
|
LOG_TRACE(f"tox_self_get_friend_list")
|
||||||
Tox.libtoxcore.tox_self_get_friend_list(self._tox_pointer, friend_list)
|
Tox.libtoxcore.tox_self_get_friend_list(self._tox_pointer, friend_list)
|
||||||
return friend_list[0:friend_list_size]
|
return friend_list[0:friend_list_size]
|
||||||
|
|
||||||
|
@ -1341,7 +1341,7 @@ class Tox:
|
||||||
POINTER(None)())
|
POINTER(None)())
|
||||||
self.file_recv_control_cb = None
|
self.file_recv_control_cb = None
|
||||||
return
|
return
|
||||||
|
|
||||||
LOG_DEBUG(f"tox_callback_file_recv_control")
|
LOG_DEBUG(f"tox_callback_file_recv_control")
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_int, c_void_p)
|
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_int, c_void_p)
|
||||||
self.file_recv_control_cb = c_callback(callback)
|
self.file_recv_control_cb = c_callback(callback)
|
||||||
|
@ -1607,7 +1607,7 @@ class Tox:
|
||||||
POINTER(None)())
|
POINTER(None)())
|
||||||
self.file_recv_cb = None
|
self.file_recv_cb = None
|
||||||
return
|
return
|
||||||
|
|
||||||
LOG_DEBUG(f"tox_callback_file_recv")
|
LOG_DEBUG(f"tox_callback_file_recv")
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_uint32, c_uint64, c_char_p, c_size_t, c_void_p)
|
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_uint32, c_uint64, c_char_p, c_size_t, c_void_p)
|
||||||
self.file_recv_cb = c_callback(callback)
|
self.file_recv_cb = c_callback(callback)
|
||||||
|
@ -1640,7 +1640,7 @@ class Tox:
|
||||||
POINTER(None)())
|
POINTER(None)())
|
||||||
self.file_recv_chunk_cb = None
|
self.file_recv_chunk_cb = None
|
||||||
return
|
return
|
||||||
|
|
||||||
LOG_DEBUG(f"tox_callback_file_recv_chunk")
|
LOG_DEBUG(f"tox_callback_file_recv_chunk")
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_uint64, POINTER(c_uint8), c_size_t, c_void_p)
|
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_uint64, POINTER(c_uint8), c_size_t, c_void_p)
|
||||||
self.file_recv_chunk_cb = c_callback(callback)
|
self.file_recv_chunk_cb = c_callback(callback)
|
||||||
|
@ -1764,7 +1764,7 @@ class Tox:
|
||||||
self.friend_lossless_packet_cb = None
|
self.friend_lossless_packet_cb = None
|
||||||
self.libtoxcore.tox_callback_friend_lossless_packet(self._tox_pointer, POINTER(None)())
|
self.libtoxcore.tox_callback_friend_lossless_packet(self._tox_pointer, POINTER(None)())
|
||||||
return
|
return
|
||||||
|
|
||||||
LOG_DEBUG(f"callback_friend_lossless_packet")
|
LOG_DEBUG(f"callback_friend_lossless_packet")
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, POINTER(c_uint8), c_size_t, c_void_p)
|
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, POINTER(c_uint8), c_size_t, c_void_p)
|
||||||
self.friend_lossless_packet_cb = c_callback(callback)
|
self.friend_lossless_packet_cb = c_callback(callback)
|
||||||
|
@ -2387,7 +2387,6 @@ class Tox:
|
||||||
|
|
||||||
error = c_int()
|
error = c_int()
|
||||||
buff = create_string_buffer(TOX_GROUP_CHAT_ID_SIZE)
|
buff = create_string_buffer(TOX_GROUP_CHAT_ID_SIZE)
|
||||||
LOG_DEBUG(f"tox_group_get_chat_id")
|
|
||||||
result = Tox.libtoxcore.tox_group_get_chat_id(self._tox_pointer,
|
result = Tox.libtoxcore.tox_group_get_chat_id(self._tox_pointer,
|
||||||
group_number,
|
group_number,
|
||||||
buff, byref(error))
|
buff, byref(error))
|
||||||
|
@ -2575,23 +2574,27 @@ class Tox:
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def group_send_custom_packet(self, group_number, lossless, data):
|
def group_send_custom_packet(self, group_number, lossless, data):
|
||||||
"""
|
"""Send a custom packet to the group.
|
||||||
Send a custom packet to the group.
|
|
||||||
|
|
||||||
If lossless is true the packet will be lossless. Lossless packet behaviour is comparable
|
If lossless is true the packet will be lossless. Lossless
|
||||||
to TCP (reliability, arrive in order) but with packets instead of a stream.
|
packet behaviour is comparable to TCP (reliability, arrive in
|
||||||
|
order) but with packets instead of a stream.
|
||||||
|
|
||||||
If lossless is false, the packet will be lossy. Lossy packets behave like UDP packets,
|
If lossless is false, the packet will be lossy. Lossy packets
|
||||||
meaning they might never reach the other side or might arrive more than once (if someone
|
behave like UDP packets, meaning they might never reach the
|
||||||
is messing with the connection) or might arrive in the wrong order.
|
other side or might arrive more than once (if someone is
|
||||||
|
messing with the connection) or might arrive in the wrong
|
||||||
|
order.
|
||||||
|
|
||||||
Unless latency is an issue or message reliability is not important, it is recommended that you use
|
Unless latency is an issue or message reliability is not
|
||||||
lossless custom packets.
|
important, it is recommended that you use lossless custom
|
||||||
|
packets.
|
||||||
|
|
||||||
:param group_number: The group number of the group the message is intended for.
|
:param group_number: The group number of the group the message is intended for.
|
||||||
:param lossless: True if the packet should be lossless.
|
:param lossless: True if the packet should be lossless.
|
||||||
:param data A byte array containing the packet data.
|
:param data A byte array containing the packet data.
|
||||||
:return True on success.
|
:return True on success.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
error = c_int()
|
error = c_int()
|
||||||
|
|
Loading…
Reference in a new issue