qt6 fixes
This commit is contained in:
parent
4d2d4034f9
commit
d1c8d445bc
9 changed files with 75 additions and 47 deletions
|
@ -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.
|
||||||
|
|
||||||
|
|
5
ToDo.md
5
ToDo.md
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue