qt6 fixes

This commit is contained in:
emdee@spm.plastiras.org 2024-02-09 09:38:24 +00:00
parent 4d2d4034f9
commit d1c8d445bc
9 changed files with 75 additions and 47 deletions

View file

@ -97,7 +97,7 @@ on pypi as it is a dependency. Just download and install it from
https://git.plastiras.org/emdee/toxygen_wrapper https://git.plastiras.org/emdee/toxygen_wrapper
This is being ported to Qt6 using qtpy https://github.com/spyder-ide/qtpy 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 PySide6 - YMMV. You will be able to choose between them by setting the
environment variable QT_API to one of: pyqt5 pyqt6 pyside2 pyside6. environment variable QT_API to one of: pyqt5 pyqt6 pyside2 pyside6.

View file

@ -53,7 +53,8 @@ line.
## Migration ## 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 Maybe migrate gevent to asyncio, and migrate to
[qasync](https://github.com/CabbageDevelopment/qasync) [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: 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://tox.gitbooks.io/tox-client-standard/content/general_requirements/general_requirements.html
https://github.com/Tox/Tox-Client-Standard

View file

@ -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 PyQt5 and integrated into toxygen. Follow the normal instructions for
adding a ```relay``` to [weechat](https://github.com/weechat/weechat) 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 /relay start ipv4.ssl.weechat
``` ```
or or
@ -39,27 +39,27 @@ It should now show up in the list of proxies.
``` ```
``` ```
/nick SyniTox /nick NickName
``` ```
## TLS certificates ## TLS certificates
[Create a Self-signed Certificate](https://www.oftc.net/NickServ/CertFP/) [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/ Create a directory for your certificates ~/.config/weechat/ssl/
and make a subdirectory for each server ~/.config/weechat/ssl/irc.oftc.net/ 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: 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 openssl req -nodes -newkey rsa:2048 -keyout NickName.key -x509 -days 3650 -out NickName.cer
chmod 400 SyniTox.key 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 cat NickName.cer NickName.key > NickName.pem
chmod 400 SyniTox.pem chmod 400 NickName.pem
``` ```
Do this for each server you want to connect to, or just use one for all of them. 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. 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 to your /etc/tor/torrc
``` ```
MapAddress palladium.libera.chat libera75jm6of4wxpxt4aynol3xjmbtxgfyjpu34ss4d7r7q2v5zrpyd.onion 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 Define the server in weechat
https://www.weechat.org/files/doc/stable/weechat_user.en.html#irc_sasl_authentication 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 /server add libera palladium.libera.chat/6697 -tls -tls_verify
/set irc.server.libera.ipv6 off /set irc.server.libera.ipv6 off
/set irc.server.libera.proxy tor /set irc.server.libera.proxy tor
/set irc.server.libera.username SyniTox /set irc.server.libera.username NickName
/set irc.server.libera.nicks SyniTox /set irc.server.libera.password password
/set irc.server.libera.nicks NickName
/set irc.server.libera.tls on /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_mechanism ecdsa-nist256p-challenge
/set irc.server.libera.sasl_username "SyniTox" /set irc.server.libera.sasl_username "NickName"
/set irc.server.libera.sasl_key "${weechat_config_dir}/ssl/libera.chat/SyniTox.pem" /set irc.server.libera.sasl_key "${weechat_config_dir}/ssl/libera.chat/NickName.pem"
``` ```
Disconnect and connect back to the server. Disconnect and connect back to the server.
@ -99,7 +116,7 @@ Disconnect and connect back to the server.
/connect libera /connect libera
``` ```
/msg nickserv identify password SyniTox /msg nickserv identify password NickName
### oftc.net ### oftc.net
@ -113,10 +130,10 @@ Define the server in weechat
/server add OFTC irc.oftc.net/6697 -tls -tls_verify /server add OFTC irc.oftc.net/6697 -tls -tls_verify
/set irc.server.OFTC.ipv6 off /set irc.server.OFTC.ipv6 off
/set irc.server.OFTC.proxy tor /set irc.server.OFTC.proxy tor
/set irc.server.OFTC.username SyniTox /set irc.server.OFTC.username NickName
/set irc.server.OFTC.nicks SyniTox /set irc.server.OFTC.nicks NickName
/set irc.server.OFTC.tls on /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 and connect back to the server.
/disconnect OFTC /disconnect OFTC
@ -124,7 +141,7 @@ Define the server in weechat
``` ```
You must be identified in order to validate using certs 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 allow NickServ to identify you based on this certificate you need
to associate the certificate fingerprint with your nick. To do this to associate the certificate fingerprint with your nick. To do this

View file

@ -53,5 +53,5 @@ Plugin's methods MUST NOT raise exceptions.
# Examples # 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)

View file

@ -53,7 +53,8 @@ line.
## Migration ## 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 Maybe migrate gevent to asyncio, and migrate to
[qasync](https://github.com/CabbageDevelopment/qasync) [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: 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://tox.gitbooks.io/tox-client-standard/content/general_requirements/general_requirements.html
https://github.com/Tox/Tox-Client-Standard

View file

@ -211,7 +211,9 @@ class App:
self._app = QtWidgets.QApplication([]) self._app = QtWidgets.QApplication([])
self._load_icon() 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) QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)
self._load_base_style() self._load_base_style()

View file

@ -320,7 +320,7 @@ class AV(common.tox_save.ToxAvSave):
name='_video_thread') name='_video_thread')
self._video_thread.start() self._video_thread.start()
def stop_video_thread(self): def stop_video_thread(self) -> None:
if self._video_thread is None: if self._video_thread is None:
return return
@ -341,7 +341,7 @@ class AV(common.tox_save.ToxAvSave):
# Incoming chunks # Incoming chunks
def audio_chunk(self, samples, channels_count, rate): def audio_chunk(self, samples, channels_count, rate) -> None:
""" """
Incoming chunk Incoming chunk
""" """
@ -377,7 +377,7 @@ class AV(common.tox_save.ToxAvSave):
# AV sending # AV sending
def send_audio_data(self, data, count, *largs, **kwargs): def send_audio_data(self, data, count, *largs, **kwargs) -> None:
pcm = data pcm = data
# :param sampling_rate: Audio sampling rate used in this frame. # :param sampling_rate: Audio sampling rate used in this frame.
if self._toxav is None: if self._toxav is None:
@ -404,7 +404,7 @@ class AV(common.tox_save.ToxAvSave):
# 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) -> None:
""" """
This method sends audio to friends This method sends audio to friends
""" """
@ -425,7 +425,7 @@ class AV(common.tox_save.ToxAvSave):
i += 1 i += 1
sleep(0.01) sleep(0.01)
def send_video(self): def send_video(self) -> None:
""" """
This method sends video to friends This method sends video to friends
""" """
@ -466,7 +466,7 @@ class AV(common.tox_save.ToxAvSave):
sleep( 1.0/iFPS) sleep( 1.0/iFPS)
def convert_bgr_to_yuv(self, frame): def convert_bgr_to_yuv(self, frame) -> tuple:
""" """
:param frame: input bgr frame :param frame: input bgr frame
:return y, u, v: y, u, v values of frame :return y, u, v: y, u, v values of frame

View file

@ -54,31 +54,33 @@ class ProfileManager:
def save_profile(self, data): def save_profile(self, data):
if self._toxes.has_password(): if self._toxes.has_password():
data = self._toxes.pass_encrypt(data) data = self._toxes.pass_encrypt(data)
profile_path = self._path.replace('.json', '.tox')
try: try:
suf = f"{os.getpid()}" suf = f"{os.getpid()}"
with open(self._path+suf, 'wb') as fl: with open(profile_path+suf, 'wb') as fl:
fl.write(data) fl.write(data)
stat = os.stat(self._path+suf) stat = os.stat(profile_path+suf)
if hasattr(stat, 'st_blocks'): if hasattr(stat, 'st_blocks'):
assert stat.st_blocks > 0, f"Zero length file {self._path+suf}" assert stat.st_blocks > 0, f"Zero length file {profile_path+suf}"
os.rename(self._path+suf,self._path) os.rename(profile_path+suf,profile_path)
LOG_INFO('Profile saved successfully to' +self._path) LOG_INFO('Profile saved successfully to' +profile_path)
except Exception as e: 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) self._profile_saved_event(data)
def export_profile(self, settings, new_path, use_new_path): 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() 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: with open(path, 'wb') as fout:
fout.write(data) fout.write(data)
LOG.info('Profile exported successfully to ' +path) LOG.info('Profile exported successfully to ' +path)
util.copy(os.path.join(self._directory, 'avatars'), util.copy(os.path.join(self._directory, 'avatars'),
os.path.join(new_path, 'avatars')) os.path.join(new_path, 'avatars'))
if use_new_path: 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 self._directory = new_path
settings.update_path(new_path) settings.update_path(new_path)

View file

@ -210,19 +210,20 @@ class Settings(dict):
text = bytes(self._toxes.pass_encrypt(bytes(text, 'utf-8'))) text = bytes(self._toxes.pass_encrypt(bytes(text, 'utf-8')))
else: else:
text = bytes(text, 'utf-8') 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') json_path = os.path.join(get_user_config_path(), 'toxygen.json')
tmp = self._path + str(os.getpid()) tmp = json_path + str(os.getpid())
try: try:
with open(tmp, 'wb') as fl: with open(tmp, 'wb') as fl:
fl.write(text) fl.write(text)
if os.path.exists(self._path+'.bak'): if os.path.exists(json_path+'.bak'):
os.remove(self._path+'.bak') os.remove(json_path+'.bak')
os.rename(self._path, self._path+'.bak') os.rename(json_path, json_path+'.bak')
os.rename(tmp, self._path) os.rename(tmp, json_path)
except Exception as e: 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: else:
self._settings_saved_event(text) self._settings_saved_event(text)