From d1c8d445bcd7f768995bfb0ba656ff7a7293b77d Mon Sep 17 00:00:00 2001 From: "emdee@spm.plastiras.org" Date: Fri, 9 Feb 2024 09:38:24 +0000 Subject: [PATCH] qt6 fixes --- README.md | 2 +- ToDo.md | 5 ++- docs/ToxygenWeechat.md | 55 ++++++++++++++++++---------- docs/plugin_api.md | 2 +- docs/todo.md | 5 ++- toxygen/app.py | 4 +- toxygen/av/calls.py | 12 +++--- toxygen/user_data/profile_manager.py | 20 +++++----- toxygen/user_data/settings.py | 17 +++++---- 9 files changed, 75 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 3f4bd7d..4ff45f3 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ on pypi as it is a dependency. Just download and install it from https://git.plastiras.org/emdee/toxygen_wrapper This is being ported to Qt6 using qtpy https://github.com/spyder-ide/qtpy -It now runs on PyQt5 and should soon run on PyQt6 and may run on PySide2 and +It now runs on PyQt5 and should run on PyQt6, and may run on PySide2 and PySide6 - YMMV. You will be able to choose between them by setting the environment variable QT_API to one of: pyqt5 pyqt6 pyside2 pyside6. diff --git a/ToDo.md b/ToDo.md index 4222944..9b4266f 100644 --- a/ToDo.md +++ b/ToDo.md @@ -53,7 +53,8 @@ line. ## Migration -Migrate PyQt5 to qtpy - almost done. +Migrate PyQt5 to qtpy - done, but I'm not sure qtpy supports PyQt6. +https://github.com/spyder-ide/qtpy/ Maybe migrate gevent to asyncio, and migrate to [qasync](https://github.com/CabbageDevelopment/qasync) @@ -65,3 +66,5 @@ Maybe migrate gevent to asyncio, and migrate to There's a standard for Tox clients that this has not been tested against: https://tox.gitbooks.io/tox-client-standard/content/general_requirements/general_requirements.html +https://github.com/Tox/Tox-Client-Standard + diff --git a/docs/ToxygenWeechat.md b/docs/ToxygenWeechat.md index 7feaf77..eb990e9 100644 --- a/docs/ToxygenWeechat.md +++ b/docs/ToxygenWeechat.md @@ -6,7 +6,7 @@ There's a copy of qweechat in ```thirdparty/qweechat``` backported to PyQt5 and integrated into toxygen. Follow the normal instructions for adding a ```relay``` to [weechat](https://github.com/weechat/weechat) ``` -/relay add ipv4.ssl.weechat 9001 +/relay add ipv4.ssl.weechat 9000 /relay start ipv4.ssl.weechat ``` or @@ -39,27 +39,27 @@ It should now show up in the list of proxies. ``` ``` -/nick SyniTox +/nick NickName ``` ## TLS certificates [Create a Self-signed Certificate](https://www.oftc.net/NickServ/CertFP/) -Choose a SyniTox you will identify as. +Choose a NickName you will identify as. Create a directory for your certificates ~/.config/weechat/ssl/ and make a subdirectory for each server ~/.config/weechat/ssl/irc.oftc.net/ Change to the server directory and use openssl to make a keypair and answer the questions: ``` -openssl req -nodes -newkey rsa:2048 -keyout SyniTox.key -x509 -days 3650 -out SyniTox.cer -chmod 400 SyniTox.key +openssl req -nodes -newkey rsa:2048 -keyout NickName.key -x509 -days 3650 -out NickName.cer +chmod 400 NickName.key ``` -We now combine certificate and key to a single file SyniTox.pem +We now combine certificate and key to a single file NickName.pem ``` -cat SyniTox.cer SyniTox.key > SyniTox.pem -chmod 400 SyniTox.pem +cat NickName.cer NickName.key > NickName.pem +chmod 400 NickName.pem ``` Do this for each server you want to connect to, or just use one for all of them. @@ -68,11 +68,27 @@ Do this for each server you want to connect to, or just use one for all of them. The main discussion forum for Tox is the #TokTok channel on libera. -libera has an onion server so we can map an address in tor. Add this +https://mox.sh/sysadmin/secure-irc-connection-to-freenode-with-tor-and-weechat/ +We have to create an account without Tor, this is a requirement to use TOR: +Connect to irc.libera.chat without Tor and register +``` +/msg NickServ identify NickName password +/msg NickServ REGISTER mypassword mycoolemail@example.com +/msg NickServ SET PRIVATE ON +``` +Confirm registration after getting the mail with the code: +``` +/msg NickServ VERIFY REGISTER NickName code1235678 +``` + +Libera has an onion server so we can map an address in tor. Add this to your /etc/tor/torrc ``` MapAddress palladium.libera.chat libera75jm6of4wxpxt4aynol3xjmbtxgfyjpu34ss4d7r7q2v5zrpyd.onion ``` +Or without the MapAddress just use +libera75jm6of4wxpxt4aynol3xjmbtxgfyjpu34ss4d7r7q2v5zrpyd.onion +as the server address below, but set tls_verify to off. Define the server in weechat https://www.weechat.org/files/doc/stable/weechat_user.en.html#irc_sasl_authentication @@ -81,16 +97,17 @@ https://www.weechat.org/files/doc/stable/weechat_user.en.html#irc_sasl_authentic /server add libera palladium.libera.chat/6697 -tls -tls_verify /set irc.server.libera.ipv6 off /set irc.server.libera.proxy tor -/set irc.server.libera.username SyniTox -/set irc.server.libera.nicks SyniTox +/set irc.server.libera.username NickName +/set irc.server.libera.password password +/set irc.server.libera.nicks NickName /set irc.server.libera.tls on -/set irc.server.libera.tls_cert "${weechat_config_dir}/ssl/libera.chat/SyniTox.pem" +/set irc.server.libera.tls_cert "${weechat_config_dir}/ssl/libera.chat/NickName.pem" ``` ``` /set irc.server.libera.sasl_mechanism ecdsa-nist256p-challenge -/set irc.server.libera.sasl_username "SyniTox" -/set irc.server.libera.sasl_key "${weechat_config_dir}/ssl/libera.chat/SyniTox.pem" +/set irc.server.libera.sasl_username "NickName" +/set irc.server.libera.sasl_key "${weechat_config_dir}/ssl/libera.chat/NickName.pem" ``` Disconnect and connect back to the server. @@ -99,7 +116,7 @@ Disconnect and connect back to the server. /connect libera ``` -/msg nickserv identify password SyniTox +/msg nickserv identify password NickName ### oftc.net @@ -113,10 +130,10 @@ Define the server in weechat /server add OFTC irc.oftc.net/6697 -tls -tls_verify /set irc.server.OFTC.ipv6 off /set irc.server.OFTC.proxy tor -/set irc.server.OFTC.username SyniTox -/set irc.server.OFTC.nicks SyniTox +/set irc.server.OFTC.username NickName +/set irc.server.OFTC.nicks NickName /set irc.server.OFTC.tls on -/set irc.server.OFTC.tls_cert "${weechat_config_dir}/ssl/irc.oftc.chat/SyniTox.pem" +/set irc.server.OFTC.tls_cert "${weechat_config_dir}/ssl/irc.oftc.chat/NickName.pem" # Disconnect and connect back to the server. /disconnect OFTC @@ -124,7 +141,7 @@ Define the server in weechat ``` You must be identified in order to validate using certs ``` -/msg nickserv identify password SyniTox +/msg nickserv identify password NickName ``` To allow NickServ to identify you based on this certificate you need to associate the certificate fingerprint with your nick. To do this diff --git a/docs/plugin_api.md b/docs/plugin_api.md index 9eb30a4..32a27f8 100644 --- a/docs/plugin_api.md +++ b/docs/plugin_api.md @@ -53,5 +53,5 @@ Plugin's methods MUST NOT raise exceptions. # Examples -You can find examples in [official repo](https://github.com/toxygen-project/toxygen_plugins) +You can find examples in [official repo](https://git.plastiras.org/emdee/toxygen_plugins) diff --git a/docs/todo.md b/docs/todo.md index 4222944..9b4266f 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -53,7 +53,8 @@ line. ## Migration -Migrate PyQt5 to qtpy - almost done. +Migrate PyQt5 to qtpy - done, but I'm not sure qtpy supports PyQt6. +https://github.com/spyder-ide/qtpy/ Maybe migrate gevent to asyncio, and migrate to [qasync](https://github.com/CabbageDevelopment/qasync) @@ -65,3 +66,5 @@ Maybe migrate gevent to asyncio, and migrate to There's a standard for Tox clients that this has not been tested against: https://tox.gitbooks.io/tox-client-standard/content/general_requirements/general_requirements.html +https://github.com/Tox/Tox-Client-Standard + diff --git a/toxygen/app.py b/toxygen/app.py index 5045470..05e6df4 100644 --- a/toxygen/app.py +++ b/toxygen/app.py @@ -211,7 +211,9 @@ class App: self._app = QtWidgets.QApplication([]) self._load_icon() - if util.get_platform() == 'Linux': + # is this still needed? + if util.get_platform() == 'Linux' and \ + hasattr(QtCore.Qt, 'AA_X11InitThreads'): QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads) self._load_base_style() diff --git a/toxygen/av/calls.py b/toxygen/av/calls.py index 5d8eac0..f60ac8a 100644 --- a/toxygen/av/calls.py +++ b/toxygen/av/calls.py @@ -320,7 +320,7 @@ class AV(common.tox_save.ToxAvSave): name='_video_thread') self._video_thread.start() - def stop_video_thread(self): + def stop_video_thread(self) -> None: if self._video_thread is None: return @@ -341,7 +341,7 @@ class AV(common.tox_save.ToxAvSave): # Incoming chunks - def audio_chunk(self, samples, channels_count, rate): + def audio_chunk(self, samples, channels_count, rate) -> None: """ Incoming chunk """ @@ -377,7 +377,7 @@ class AV(common.tox_save.ToxAvSave): # AV sending - def send_audio_data(self, data, count, *largs, **kwargs): + def send_audio_data(self, data, count, *largs, **kwargs) -> None: pcm = data # :param sampling_rate: Audio sampling rate used in this frame. if self._toxav is None: @@ -404,7 +404,7 @@ class AV(common.tox_save.ToxAvSave): # util_ui.tr("Error send_audio audio_send_frame")) pass - def send_audio(self): + def send_audio(self) -> None: """ This method sends audio to friends """ @@ -425,7 +425,7 @@ class AV(common.tox_save.ToxAvSave): i += 1 sleep(0.01) - def send_video(self): + def send_video(self) -> None: """ This method sends video to friends """ @@ -466,7 +466,7 @@ class AV(common.tox_save.ToxAvSave): sleep( 1.0/iFPS) - def convert_bgr_to_yuv(self, frame): + def convert_bgr_to_yuv(self, frame) -> tuple: """ :param frame: input bgr frame :return y, u, v: y, u, v values of frame diff --git a/toxygen/user_data/profile_manager.py b/toxygen/user_data/profile_manager.py index 4b003ba..a6f5df0 100644 --- a/toxygen/user_data/profile_manager.py +++ b/toxygen/user_data/profile_manager.py @@ -54,31 +54,33 @@ class ProfileManager: def save_profile(self, data): if self._toxes.has_password(): data = self._toxes.pass_encrypt(data) + profile_path = self._path.replace('.json', '.tox') try: suf = f"{os.getpid()}" - with open(self._path+suf, 'wb') as fl: + with open(profile_path+suf, 'wb') as fl: fl.write(data) - stat = os.stat(self._path+suf) + stat = os.stat(profile_path+suf) if hasattr(stat, 'st_blocks'): - assert stat.st_blocks > 0, f"Zero length file {self._path+suf}" - os.rename(self._path+suf,self._path) - LOG_INFO('Profile saved successfully to' +self._path) + assert stat.st_blocks > 0, f"Zero length file {profile_path+suf}" + os.rename(profile_path+suf,profile_path) + LOG_INFO('Profile saved successfully to' +profile_path) except Exception as e: - LOG_WARN(f"Profile save failed to {self._path}\n{e}") + LOG_WARN(f"Profile save failed to {profile_path}\n{e}") self._profile_saved_event(data) def export_profile(self, settings, new_path, use_new_path): - with open(self._path, 'rb') as fin: + profile_path = self._path.replace('.json', '.tox') + with open(profile_path, 'rb') as fin: data = fin.read() - path = new_path + os.path.basename(self._path) + path = new_path + os.path.basename(profile_path) with open(path, 'wb') as fout: fout.write(data) LOG.info('Profile exported successfully to ' +path) util.copy(os.path.join(self._directory, 'avatars'), os.path.join(new_path, 'avatars')) if use_new_path: - self._path = os.path.join(new_path, os.path.basename(self._path)) + profile_path = os.path.join(new_path, os.path.basename(profile_path)) self._directory = new_path settings.update_path(new_path) diff --git a/toxygen/user_data/settings.py b/toxygen/user_data/settings.py index f3283d2..2a89644 100644 --- a/toxygen/user_data/settings.py +++ b/toxygen/user_data/settings.py @@ -210,19 +210,20 @@ class Settings(dict): text = bytes(self._toxes.pass_encrypt(bytes(text, 'utf-8'))) else: text = bytes(text, 'utf-8') - if not self._path: + json_path = self._path.replace('.tox', '.json') + if not json_path: #? - self._path = os.path.join(get_user_config_path(), 'toxygen.json') - tmp = self._path + str(os.getpid()) + json_path = os.path.join(get_user_config_path(), 'toxygen.json') + tmp = json_path + str(os.getpid()) try: with open(tmp, 'wb') as fl: fl.write(text) - if os.path.exists(self._path+'.bak'): - os.remove(self._path+'.bak') - os.rename(self._path, self._path+'.bak') - os.rename(tmp, self._path) + if os.path.exists(json_path+'.bak'): + os.remove(json_path+'.bak') + os.rename(json_path, json_path+'.bak') + os.rename(tmp, json_path) except Exception as e: - LOG.warn(f'Error saving to {self._path} ' +str(e)) + LOG.warn(f'Error saving to {json_path} ' +str(e)) else: self._settings_saved_event(text)