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