Compare commits

..

No commits in common. "a073dd9bc94bfc4c24f8f7a07c8294f2313740c7" and "90e379a6deab52f7acc23f3de18a1a6048fb8221" have entirely different histories.

15 changed files with 138 additions and 200 deletions

View File

@ -49,10 +49,6 @@ Toxygen is powerful cross-platform [Tox](https://tox.chat/) client written in pu
This hard-forked from https://github.com/toxygen-project/toxygen This hard-forked from https://github.com/toxygen-project/toxygen
```next_gen``` branch. ```next_gen``` branch.
https://git.plastiras.org/emdee/toxygen_wrapper needs packaging
is making a dependency. Just download it and copy the two directories
```wrapper``` and ```wrapper_tests``` into ```toxygen/toxygen```.
See ToDo.md to the current ToDo list. See ToDo.md to the current ToDo list.
Work on this project is suspended until the Work on this project is suspended until the

15
ToDo.md
View File

@ -1,13 +1,5 @@
# Toxygen ToDo List # Toxygen ToDo List
## Bugs
1. There is an agravating bug where new messages are not put in the
current window, and a messages waiting indicator appears. You have
to focus out of the window and then back in the window.
## Fix history ## Fix history
The code is in there but it's not working. The code is in there but it's not working.
@ -22,7 +14,7 @@ command line.
## Fix Video ## Fix Video
The code is in there but it's not working. I may have broken it The code is in there but it's not working. I may have broken it
trying to wire up the ability to set the video device from the command trying to wire up the ability to set the audio device from the command
line. line.
## Groups ## Groups
@ -48,5 +40,6 @@ line.
https://git.plastiras.org/emdee/toxygen_wrapper but the tox.py https://git.plastiras.org/emdee/toxygen_wrapper but the tox.py
needs each call double checking. needs each call double checking.
2. https://git.plastiras.org/emdee/toxygen_wrapper needs packaging
and making a dependency.

View File

@ -15,11 +15,14 @@ if system() == 'Windows':
MODULES = ['PyQt5', 'PyAudio', 'numpy', 'opencv-python', 'pydenticon', 'cv2'] MODULES = ['PyQt5', 'PyAudio', 'numpy', 'opencv-python', 'pydenticon', 'cv2']
else: else:
MODULES = ['pydenticon'] MODULES = ['pydenticon']
MODULES.append('PyQt5')
try: try:
import pyaudio import pyaudio
except ImportError: except ImportError:
MODULES.append('PyAudio') MODULES.append('PyAudio')
try:
import PyQt5
except ImportError:
MODULES.append('PyQt5')
try: try:
import numpy import numpy
except ImportError: except ImportError:
@ -32,10 +35,6 @@ else:
import coloredlogs import coloredlogs
except ImportError: except ImportError:
MODULES.append('coloredlogs') MODULES.append('coloredlogs')
try:
import pyqtconsole
except ImportError:
MODULES.append('pyqtconsole')
def get_packages(): def get_packages():
@ -43,8 +42,10 @@ def get_packages():
for root, dirs, files in os.walk(directory): for root, dirs, files in os.walk(directory):
packages = map(lambda d: 'toxygen.' + d, dirs) packages = map(lambda d: 'toxygen.' + d, dirs)
packages = ['toxygen'] + list(packages) packages = ['toxygen'] + list(packages)
return packages return packages
class InstallScript(install): class InstallScript(install):
"""This class configures Toxygen after installation""" """This class configures Toxygen after installation"""
@ -71,16 +72,20 @@ setup(name='Toxygen',
version=version, version=version,
description='Toxygen - Tox client', description='Toxygen - Tox client',
long_description='Toxygen is powerful Tox client written in Python3', long_description='Toxygen is powerful Tox client written in Python3',
url='https://git.plastiras.org/emdee/toxygen/', url='https://github.com/toxygen-project/toxygen/',
keywords='toxygen Tox messenger', keywords='toxygen tox messenger',
author='Ingvar', author='Ingvar',
maintainer='', maintainer='Ingvar',
license='GPL3', license='GPL3',
packages=get_packages(), packages=get_packages(),
install_requires=MODULES, install_requires=MODULES,
include_package_data=True, include_package_data=True,
classifiers=[ classifiers=[
'Programming Language :: Python :: 3 :: Only', 'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.9',
], ],
entry_points={ entry_points={
@ -88,6 +93,4 @@ setup(name='Toxygen',
}, },
cmdclass={ cmdclass={
'install': InstallScript 'install': InstallScript
}, })
zip_safe=False
)

View File

@ -4,7 +4,7 @@ import sys
import traceback import traceback
from random import shuffle from random import shuffle
import threading import threading
from time import sleep from time import sleep, time
from gevent import monkey; monkey.patch_all(); del monkey # noqa from gevent import monkey; monkey.patch_all(); del monkey # noqa
import gevent import gevent
@ -75,6 +75,7 @@ from user_data.backup_service import BackupService
import styles.style # TODO: dynamic loading import styles.style # TODO: dynamic loading
import wrapper_tests.support_testing as ts import wrapper_tests.support_testing as ts
from wrapper_tests.tests_wrapper import test_bootstrap_iNmapInfo
global LOG global LOG
import logging import logging
@ -487,7 +488,7 @@ class App:
LOG.debug(f"_start_threads init: {te()!r}") LOG.debug(f"_start_threads init: {te()!r}")
# starting threads for tox iterate and toxav iterate # starting threads for tox iterate and toxav iterate
self._main_loop = threads.ToxIterateThread(self._tox) self._main_loop = threads.ToxIterateThread(self._tox, self)
self._main_loop.start() self._main_loop.start()
self._av_loop = threads.ToxAVIterateThread(self._tox.AV) self._av_loop = threads.ToxAVIterateThread(self._tox.AV)
@ -774,7 +775,8 @@ class App:
# FixMe: # FixMe:
self._log = lambda line: LOG.log(self._oArgs.loglevel, self._log = lambda line: LOG.log(self._oArgs.loglevel,
self._ms.status(line)) self._ms.status(line))
# self._ms._log = self._log # was used in callbacks.py self._ms._log = self._log # used in callbacks.py
self.LOG = self._log # backwards
if False: if False:
self.status_handler = logging.Handler() self.status_handler = logging.Handler()
@ -810,7 +812,6 @@ class App:
def _init_callbacks(self, ms=None): def _init_callbacks(self, ms=None):
LOG.debug("_init_callbacks") LOG.debug("_init_callbacks")
# this will block if you are not connected
callbacks.init_callbacks(self._tox, self._profile, self._settings, callbacks.init_callbacks(self._tox, self._profile, self._settings,
self._plugin_loader, self._contacts_manager, self._plugin_loader, self._contacts_manager,
self._calls_manager, self._calls_manager,
@ -845,10 +846,10 @@ class App:
sleep(interval / 1000.0) sleep(interval / 1000.0)
def _test_tox(self): def _test_tox(self):
self.test_net() self.test_net(iMax=8)
self._ms.log_console() self._ms.log_console()
def test_net(self, lElts=None, oThread=None, iMax=4): def test_net(self, oThread=None, iMax=6):
LOG.debug("test_net " +self._oArgs.network) LOG.debug("test_net " +self._oArgs.network)
# bootstrap # bootstrap
@ -886,25 +887,13 @@ class App:
else: else:
LOG.debug("Have default route for network " +self._oArgs.network) LOG.debug("Have default route for network " +self._oArgs.network)
lUdpElts = self._settings['current_nodes_udp'] LOG.debug(f"test_net {self._oArgs.network} iMax= {iMax}")
if self._oArgs.proxy_type <= 0 and not lUdpElts:
title = 'test_net Error'
text = 'Error: ' + str('No UDP nodes')
util_ui.message_box(text, title)
return
lTcpElts = self._settings['current_nodes_tcp']
if self._oArgs.proxy_type > 0 and not lTcpElts:
title = 'test_net Error'
text = 'Error: ' + str('No TCP nodes')
util_ui.message_box(text, title)
return
LOG.debug(f"test_net {self._oArgs.network} lenU={len(lUdpElts)} lenT={len(lTcpElts)} iMax= {iMax}")
i = 0 i = 0
while i < iMax: while i < iMax:
# if oThread and oThread._stop_thread: return # if oThread and oThread._stop_thread: return
i = i + 1 i = i + 1
LOG.debug(f"bootstrapping status # {i}") LOG.debug(f"bootstrapping status # {i}")
self._test_bootstrap(lUdpElts) self._test_bootstrap(self._settings['current_nodes_udp'])
if hasattr(self._oArgs, 'proxy_type') and self._oArgs.proxy_type > 0: if hasattr(self._oArgs, 'proxy_type') and self._oArgs.proxy_type > 0:
LOG.debug(f"relaying status # {i}") LOG.debug(f"relaying status # {i}")
self._test_relays(self._settings['current_nodes_tcp']) self._test_relays(self._settings['current_nodes_tcp'])
@ -916,6 +905,9 @@ class App:
LOG.trace(f"Connected status #{i}: {status!r}") LOG.trace(f"Connected status #{i}: {status!r}")
self.loop(2) self.loop(2)
global iLAST_CONN
iLAST_CONN = time()
def _test_env(self): def _test_env(self):
_settings = self._settings _settings = self._settings
if 'proxy_type' not in _settings or _settings['proxy_type'] == 0 or \ if 'proxy_type' not in _settings or _settings['proxy_type'] == 0 or \
@ -942,11 +934,9 @@ class App:
def _test_bootstrap(self, lElts=None): def _test_bootstrap(self, lElts=None):
if lElts is None: if lElts is None:
lElts = self._settings['current_nodes_udp'] lElts = self._settings['current_nodes_udp']
LOG.debug(f"_test_bootstrap #Elts={len(lElts)}")
if not lElts:
return
shuffle(lElts) shuffle(lElts)
ts.bootstrap_udp(lElts[:iNODES], [self._tox]) LOG.debug(f"_test_bootstrap #Elts={len(lElts)}")
ts.bootstrap_good(lElts[:iNODES], [self._tox])
LOG.info("Connected status: " +repr(self._tox.self_get_connection_status())) LOG.info("Connected status: " +repr(self._tox.self_get_connection_status()))
def _test_relays(self, lElts=None): def _test_relays(self, lElts=None):
@ -971,7 +961,7 @@ class App:
lElts = self._settings['current_nodes_tcp'] lElts = self._settings['current_nodes_tcp']
shuffle(lElts) shuffle(lElts)
try: try:
bootstrap_iNodeInfo(lElts) test_bootstrap_iNmapInfo(lElts)
except Exception as e: except Exception as e:
# json.decoder.JSONDecodeError # json.decoder.JSONDecodeError
LOG.error(f"test_tox ' +' : {e}") LOG.error(f"test_tox ' +' : {e}")

View File

@ -13,7 +13,6 @@ except ImportError:
from user_data.settings import get_user_config_path from user_data.settings import get_user_config_path
from wrapper_tests.support_testing import _get_nodes_path from wrapper_tests.support_testing import _get_nodes_path
from wrapper_tests.support_http import download_url from wrapper_tests.support_http import download_url
import wrapper_tests.support_testing as ts
global LOG global LOG
import logging import logging

View File

@ -93,10 +93,10 @@ class ContactsManager(ToxSave):
def is_contact_active(self, contact): def is_contact_active(self, contact):
if not self._active_contact: if not self._active_contact:
# LOG.debug("No self._active_contact") LOG.warn("No self._active_contact")
return False return False
if self._active_contact not in self._contacts: if self._active_contact not in self._contacts:
LOG.warn(f"_active_contact={self._active_contact} not in contacts len={len(self._contacts)}") LOG.debug(f"_active_contact={self._active_contact} len={len(self._contacts)}")
return False return False
if not self._contacts[self._active_contact]: if not self._contacts[self._active_contact]:
LOG.debug(f"{self._contacts[self._active_contact]} {contact.tox_id}") LOG.debug(f"{self._contacts[self._active_contact]} {contact.tox_id}")
@ -241,7 +241,7 @@ class ContactsManager(ToxSave):
# AttributeError: 'NoneType' object has no attribute 'number' # AttributeError: 'NoneType' object has no attribute 'number'
for (i, contact) in enumerate(self._contacts): for (i, contact) in enumerate(self._contacts):
if contact is None or not hasattr(contact, 'number'): if contact is None or not hasattr(contact, 'number'):
LOG.error(f"Contact {i} is None or not hasattr 'number'") LOG.error("Contact {i} is None or not hasattr 'number'")
del self._contacts[i] del self._contacts[i]
continue continue
contacts = sorted(self._contacts, key=lambda c: c.number) contacts = sorted(self._contacts, key=lambda c: c.number)

View File

@ -110,6 +110,7 @@ class GroupChat(contact.Contact, ToxSave):
def get_peer_by_id(self, peer_id): def get_peer_by_id(self, peer_id):
peers = list(filter(lambda p: p.id == peer_id, self._peers)) peers = list(filter(lambda p: p.id == peer_id, self._peers))
if peers: if peers:
#? broken
return peers[0] return peers[0]
else: else:
LOG_WARN(f"get_peer_by_id empty peers for {peer_id}") LOG_WARN(f"get_peer_by_id empty peers for {peer_id}")

View File

@ -35,8 +35,19 @@ with ts.ignoreStderr():
__maintainer__ = 'Ingvar' __maintainer__ = 'Ingvar'
__version__ = '0.5.0+' __version__ = '0.5.0+'
import time from PyQt5 import QtCore
sleep = time.sleep import gevent
if 'QtCore' in sys.modules:
def qt_sleep(fSec):
if fSec > .001:
QtCore.QThread.msleep(int(fSec*1000.0))
QtCore.QCoreApplication.processEvents()
sleep = qt_sleep
elif 'gevent' in sys.modules:
sleep = gevent.sleep
else:
import time
sleep = time.sleep
def reset(): def reset():
Settings.reset_auto_profile() Settings.reset_auto_profile()
@ -219,9 +230,6 @@ def main_parser():
parser.add_argument('--udp_enabled',type=str, parser.add_argument('--udp_enabled',type=str,
default='True', choices=['True','False'], default='True', choices=['True','False'],
help='En/Disable udp') help='En/Disable udp')
parser.add_argument('--trace_enabled',type=str,
default='False', choices=['True','False'],
help='Debugging from toxcore logger_trace')
parser.add_argument('--ipv6_enabled',type=str, parser.add_argument('--ipv6_enabled',type=str,
default=bIpV6, choices=lIpV6Choices, default=bIpV6, choices=lIpV6Choices,
help='En/Disable ipv6') help='En/Disable ipv6')

View File

@ -76,7 +76,7 @@ class Messenger(tox_save.ToxSave):
if self._contacts_manager.is_active_a_friend(): if self._contacts_manager.is_active_a_friend():
self.send_message_to_friend(text, message_type) self.send_message_to_friend(text, message_type)
elif self._contacts_manager.is_active_a_group(): elif self._contacts_manager.is_active_a_group():
self.send_message_to_group(text, message_type) self.send_message_to_group('~'+text, message_type)
elif self._contacts_manager.is_active_a_group_chat_peer(): elif self._contacts_manager.is_active_a_group_chat_peer():
self.send_message_to_group_peer(text, message_type) self.send_message_to_group_peer(text, message_type)
else: else:
@ -97,19 +97,20 @@ class Messenger(tox_save.ToxSave):
:param friend_number: number of friend :param friend_number: number of friend
from Qt callback from Qt callback
""" """
if not text:
return
if friend_number is None: if friend_number is None:
friend_number = self._contacts_manager.get_active_number() friend_number = self._contacts_manager.get_active_number()
if friend_number is None or friend_number < 0: if friend_number is None:
LOG.error(f"No _contacts_manager.get_active_number") LOG.error(f"No _contacts_manager.get_active_number")
return return
if not text or friend_number < 0:
return
assert_main_thread() assert_main_thread()
friend = self._get_friend_by_number(friend_number) friend = self._get_friend_by_number(friend_number)
if not friend: if not friend:
LOG.error(f"No self._get_friend_by_number") LOG.error(f"No self._get_friend_by_number")
return return
assert friend
messages = self._split_message(text.encode('utf-8')) messages = self._split_message(text.encode('utf-8'))
t = util.get_unix_time() t = util.get_unix_time()
for message in messages: for message in messages:
@ -335,8 +336,8 @@ class Messenger(tox_save.ToxSave):
self._add_info_message(friend_number, text) self._add_info_message(friend_number, text)
def _add_info_message(self, friend_number, text): def _add_info_message(self, friend_number, text):
friend = self._get_friend_by_number(friend_number)
assert friend assert friend
friend = self._get_friend_by_number(friend_number)
message = InfoMessage(text, util.get_unix_time()) message = InfoMessage(text, util.get_unix_time())
friend.append_message(message) friend.append_message(message)
if self._contacts_manager.is_friend_active(friend_number): if self._contacts_manager.is_friend_active(friend_number):

View File

@ -10,6 +10,18 @@ from wrapper.toxcore_enums_and_consts import TOX_USER_STATUS, TOX_CONNECTION
import wrapper_tests.support_testing as ts import wrapper_tests.support_testing as ts
from utils import util from utils import util
if 'QtCore' in sys.modules:
def qt_sleep(fSec):
if fSec > .001:
QtCore.QThread.msleep(int(fSec*1000.0))
QtCore.QCoreApplication.processEvents()
sleep = qt_sleep
elif 'gevent' in sys.modules:
import gevent
sleep = gevent.sleep
else:
import time
sleep = time.sleep
import time import time
sleep = time.sleep sleep = time.sleep
@ -51,7 +63,7 @@ class BaseThread(threading.Thread):
if not self.is_alive(): break if not self.is_alive(): break
i = i + 1 i = i + 1
else: else:
LOG_WARN(f"BaseThread {self.name} BLOCKED after {ts.iTHREAD_JOINS}") LOG_WARN(f"BaseThread {self.name} BLOCKED")
class BaseQThread(QtCore.QThread): class BaseQThread(QtCore.QThread):
@ -89,14 +101,12 @@ class InitThread(BaseThread):
self._is_first_start = is_first_start self._is_first_start = is_first_start
def run(self): def run(self):
# DBUG+ InitThread run: ERROR name 'ts' is not defined
import wrapper_tests.support_testing as ts
LOG_DEBUG('InitThread run: ') LOG_DEBUG('InitThread run: ')
try: try:
if self._is_first_start and ts.bAreWeConnected() and \ if self._is_first_start and ts.bAreWeConnected():
self._settings['download_nodes_list']: if self._settings['download_nodes_list']:
LOG_INFO(f"downloading list of nodes {self._settings['download_nodes_list']}") LOG_INFO('downloading list of nodes')
download_nodes_list(self._settings, oArgs=self._app._args) download_nodes_list(self._settings, oArgs=self._app._args)
if ts.bAreWeConnected(): if ts.bAreWeConnected():
LOG_INFO(f"calling test_net nodes") LOG_INFO(f"calling test_net nodes")

View File

@ -22,7 +22,7 @@ def LOG_INFO(a):
bVERBOSE = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 20 bVERBOSE = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 20
if bVERBOSE: print('INFO> '+a) if bVERBOSE: print('INFO> '+a)
def LOG_DEBUG(a): def LOG_DEBUG(a):
bVERBOSE = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 10 bVERBOSE = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 10-1
if bVERBOSE: print('DBUG> '+a) if bVERBOSE: print('DBUG> '+a)
def LOG_TRACE(a): def LOG_TRACE(a):
bVERBOSE = hasattr(__builtins__, 'app') and app.oArgs.loglevel < 10 bVERBOSE = hasattr(__builtins__, 'app') and app.oArgs.loglevel < 10
@ -39,21 +39,18 @@ def tox_log_cb(iTox, level, file, line, func, message, *args):
* @param user_data The user data pointer passed to tox_new in options. * @param user_data The user data pointer passed to tox_new in options.
""" """
try: try:
file = str(file, 'UTF-8') if type(file) == bytes:
# root WARNING 3network.c#944:b'send_packet'attempted to send message with network family 10 (probably IPv6) on IPv4 socket file = str(file, 'UTF-8')
if file == 'network.c' and line in [944, 660]: return if file == 'network.c' and line in [944, 660]: return
func = str(func, 'UTF-8') # root WARNING 3network.c#944:b'send_packet'attempted to send message with network family 10 (probably IPv6) on IPv4 socket
message = str(message, 'UTF-8') if type(func) == bytes:
func = str(func, 'UTF-8')
if type(message) == bytes:
message = str(message, 'UTF-8')
message = f"{file}#{line}:{func} {message}" message = f"{file}#{line}:{func} {message}"
LOG_LOG(message) LOG_LOG(message)
except Exception as e: except Exception as e:
LOG_ERROR(f"tox_log_cb {e}") LOG_ERROR("tox_log_cb {e}")
#tox_log_handler (context=0x24763d0,
# level=LOGGER_LEVEL_TRACE, file=0x7fffe599fb99 "TCP_common.c", line=203,
# func=0x7fffe599fc50 <__func__.2> "read_TCP_packet",
# message=0x7fffba7fabd0 "recv buffer has 0 bytes, but requested 10 bytes",
# userdata=0x0) at /var/local/src/c-toxcore/toxcore/tox.c:78
def tox_factory(data=None, settings=None, args=None, app=None): def tox_factory(data=None, settings=None, args=None, app=None):
""" """
@ -101,9 +98,7 @@ def tox_factory(data=None, settings=None, args=None, app=None):
LOG.debug("wrapper.tox.Tox settings: " +repr(settings)) LOG.debug("wrapper.tox.Tox settings: " +repr(settings))
if 'trace_enabled' in settings and settings['trace_enabled']: if tox_options._options_pointer:
LOG_INFO("settings['trace_enabled' disabled" )
elif tox_options._options_pointer:
c_callback = CFUNCTYPE(None, c_void_p, c_int, c_char_p, c_int, c_char_p, c_char_p, c_void_p) c_callback = CFUNCTYPE(None, c_void_p, c_int, c_char_p, c_int, c_char_p, c_char_p, c_void_p)
tox_options.self_logger_cb = c_callback(tox_log_cb) tox_options.self_logger_cb = c_callback(tox_log_cb)
wrapper.tox.Tox.libtoxcore.tox_options_set_log_callback( wrapper.tox.Tox.libtoxcore.tox_options_set_log_callback(

View File

@ -26,75 +26,39 @@ except Exception as e:
LOG.warn(e) LOG.warn(e)
PythonConsole = None PythonConsole = None
else: else:
if True: def hl_format(color, style=''):
# I want to do reverse video but I cant figure how """Return a QTextCharFormat with the given attributes.
bg='white' unused
def hl_format(color, style=''): """
"""Return a QTextCharFormat with the given attributes. _color = QColor()
""" _color.setNamedColor(color)
_color = QColor()
_color.setNamedColor(color)
_format = QTextCharFormat() _format = QTextCharFormat()
_format.setForeground(_color) _format.setBackground(_color)
if 'bold' in style: if 'bold' in style:
_format.setFontWeight(QFont.Bold) _format.setFontWeight(QFont.Bold)
if 'italic' in style: if 'italic' in style:
_format.setFontItalic(True) _format.setFontItalic(True)
_bgcolor = QColor() _fgcolor = QColor()
_bgcolor.setNamedColor(bg) _fgcolor.setNamedColor('white')
_format.setBackground(_bgcolor) _format.setForeground(_fgcolor)
return _format return _format
aFORMATS = { aFORMATS = {
'keyword': hl_format('blue', 'bold'), 'keyword': hl.format('blue', 'bold'),
'operator': hl_format('red'), 'operator': hl.format('red'),
'brace': hl_format('darkGray'), 'brace': hl.format('darkGray'),
'defclass': hl_format('black', 'bold'), 'defclass': hl.format('black', 'bold'),
'string': hl_format('magenta'), 'string': hl.format('magenta'),
'string2': hl_format('darkMagenta'), 'string2': hl.format('darkMagenta'),
'comment': hl_format('darkGreen', 'italic'), 'comment': hl.format('darkGreen', 'italic'),
'self': hl_format('black', 'italic'), 'self': hl.format('black', 'italic'),
'numbers': hl_format('brown'), 'numbers': hl.format('brown'),
'inprompt': hl_format('darkBlue', 'bold'), 'inprompt': hl.format('darkBlue', 'bold'),
'outprompt': hl_format('darkRed', 'bold'), 'outprompt': hl.format('darkRed', 'bold'),
} }
else:
bg = 'black'
def hl_format(color, style=''):
"""Return a QTextCharFormat with the given attributes.
unused
"""
_color = QColor()
_color.setNamedColor(color)
_format = QTextCharFormat()
_format.setForeground(_color)
if 'bold' in style:
_format.setFontWeight(QFont.Bold)
if 'italic' in style:
_format.setFontItalic(True)
_bgcolor = QColor()
_bgcolor.setNamedColor(bg)
_format.setBackground(_bgcolor)
return _format
aFORMATS = {
'keyword': hl_format('blue', 'bold'),
'operator': hl_format('red'),
'brace': hl_format('lightGray'),
'defclass': hl_format('white', 'bold'),
'string': hl_format('magenta'),
'string2': hl_format('lightMagenta'),
'comment': hl_format('lightGreen', 'italic'),
'self': hl_format('white', 'italic'),
'numbers': hl_format('lightBrown'),
'inprompt': hl_format('lightBlue', 'bold'),
'outprompt': hl_format('lightRed', 'bold'),
}
class QTextEditLogger(logging.Handler): class QTextEditLogger(logging.Handler):
def __init__(self, parent, app): def __init__(self, parent, app):
@ -213,10 +177,8 @@ class MainWindow(QtWidgets.QMainWindow):
self.actionTest_tox = QtWidgets.QAction(window) self.actionTest_tox = QtWidgets.QAction(window)
self.actionTest_tox.setObjectName("actionTest_tox") self.actionTest_tox.setObjectName("actionTest_tox")
self.actionTest_nmap = QtWidgets.QAction(window) self.actionTest_socks = QtWidgets.QAction(window)
self.actionTest_nmap.setObjectName("actionTest_nmap") self.actionTest_socks.setObjectName("actionTest_socks")
self.actionTest_main = QtWidgets.QAction(window)
self.actionTest_main.setObjectName("actionTest_main")
self.actionQuit_program = QtWidgets.QAction(window) self.actionQuit_program = QtWidgets.QAction(window)
self.actionQuit_program.setObjectName("actionQuit_program") self.actionQuit_program.setObjectName("actionQuit_program")
@ -269,8 +231,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.menuProfile.addAction(self.actionSettings) self.menuProfile.addAction(self.actionSettings)
self.menuProfile.addAction(self.lockApp) self.menuProfile.addAction(self.lockApp)
self.menuProfile.addAction(self.actionTest_tox) self.menuProfile.addAction(self.actionTest_tox)
self.menuProfile.addAction(self.actionTest_nmap) self.menuProfile.addAction(self.actionTest_socks)
self.menuProfile.addAction(self.actionTest_main)
self.menuProfile.addAction(self.actionQuit_program) self.menuProfile.addAction(self.actionQuit_program)
self.menuGC.addAction(self.createGC) self.menuGC.addAction(self.createGC)
@ -299,8 +260,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.menubar.addAction(self.menuPlugins.menuAction()) self.menubar.addAction(self.menuPlugins.menuAction())
self.menubar.addAction(self.menuAbout.menuAction()) self.menubar.addAction(self.menuAbout.menuAction())
self.actionTest_nmap.triggered.connect(self.test_nmap) self.actionTest_socks.triggered.connect(self.test_socks)
self.actionTest_main.triggered.connect(self.test_main)
self.actionTest_tox.triggered.connect(self.test_tox) self.actionTest_tox.triggered.connect(self.test_tox)
self.actionQuit_program.triggered.connect(self.quit_program) self.actionQuit_program.triggered.connect(self.quit_program)
@ -362,8 +322,7 @@ class MainWindow(QtWidgets.QMainWindow):
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.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_nmap.setText(util_ui.tr("Test Nodes")) self.actionTest_socks.setText(util_ui.tr("Test program"))
self.actionTest_main.setText(util_ui.tr("Test Program"))
self.actionQuit_program.setText(util_ui.tr("Quit program")) self.actionQuit_program.setText(util_ui.tr("Quit program"))
self.actionSettings.setText(util_ui.tr("Settings")) self.actionSettings.setText(util_ui.tr("Settings"))
self.audioSettings.setText(util_ui.tr("Audio")) self.audioSettings.setText(util_ui.tr("Audio"))
@ -669,17 +628,13 @@ class MainWindow(QtWidgets.QMainWindow):
try: try:
if not self._pe: if not self._pe:
self._pe = PythonConsole(formats=aFORMATS) self._pe = PythonConsole(sFont=font_name,
formats=aFORMATS,
bBold=True,
font_width=size)
self._pe.setWindowTitle('variable: app is the application') self._pe.setWindowTitle('variable: app is the application')
# self._pe.edit.setStyleSheet('foreground: white; background-color: black;}') # self._pe.edit.setStyleSheet('foreground: white; background-color: black;}')
# Fix the pyconsole geometry # Fix the pyconsole geometry
font = self._pe.edit.document().defaultFont()
font.setFamily(font_name)
font.setBold(True)
if font_width is None:
font_width = QFontMetrics(font).width('M')
self._pe.setFont(font)
geometry = self._pe.geometry() geometry = self._pe.geometry()
geometry.setWidth(font_width*80+20) geometry.setWidth(font_width*80+20)
geometry.setHeight(font_width*40) geometry.setHeight(font_width*40)
@ -781,9 +736,6 @@ class MainWindow(QtWidgets.QMainWindow):
def test_nmap(self): def test_nmap(self):
self._app._test_nmap() self._app._test_nmap()
def test_main(self):
self._app._test_main()
def quit_program(self): def quit_program(self):
try: try:
self.close_window() self.close_window()

View File

@ -29,11 +29,9 @@ class PeerScreen(CenteredWidget):
self.statusCircle = StatusCircle(self) self.statusCircle = StatusCircle(self)
self.statusCircle.setGeometry(50, 15, 30, 30) self.statusCircle.setGeometry(50, 15, 30, 30)
if self._peer: self.statusCircle.update(self._peer.status)
self.statusCircle.update(self._peer.status) self.peerNameLabel.setText(self._peer.name)
self.peerNameLabel.setText(self._peer.name) self.ignorePeerCheckBox.setChecked(self._peer.is_muted)
self.ignorePeerCheckBox.setChecked(self._peer.is_muted)
self.ignorePeerCheckBox.clicked.connect(self._toggle_ignore) self.ignorePeerCheckBox.clicked.connect(self._toggle_ignore)
self.sendPrivateMessagePushButton.clicked.connect(self._send_private_message) self.sendPrivateMessagePushButton.clicked.connect(self._send_private_message)
self.copyPublicKeyPushButton.clicked.connect(self._copy_public_key) self.copyPublicKeyPushButton.clicked.connect(self._copy_public_key)

View File

@ -63,17 +63,9 @@ 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)
try: with open(self._path, 'wb') as fl:
suf = f"{os.getpid()}" fl.write(data)
with open(self._path+suf, 'wb') as fl: LOG_INFO('Profile saved successfully to' +self._path)
fl.write(data)
stat = os.stat(self._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)
except Exception as e:
LOG_WARN(f"Profile save failed to {self._path}\n{e}")
self._profile_saved_event(data) self._profile_saved_event(data)

View File

@ -138,8 +138,9 @@ class Settings(dict):
self._profile_path = path.replace('.json', '.tox') self._profile_path = path.replace('.json', '.tox')
self._toxes = toxes self._toxes = toxes
self._app = app self._app = app
self._oArgs = app._oArgs self._args = app._args
self._log = lambda l: LOG.log(self._oArgs.loglevel, l) self.LOG = lambda l: LOG.log(self._args.loglevel, l)
self._log = self.LOG
self._settings_saved_event = Event() self._settings_saved_event = Event()
if path and os.path.isfile(path): if path and os.path.isfile(path):
@ -155,29 +156,29 @@ class Settings(dict):
text = title + path text = title + path
LOG.error(title +str(ex)) LOG.error(title +str(ex))
util_ui.message_box(text, title) util_ui.message_box(text, title)
info = Settings.get_default_settings(app._oArgs) info = Settings.get_default_settings(app._args)
user_data.settings.clean_settings(info) user_data.settings.clean_settings(info)
else: else:
LOG.debug('get_default_settings for: ' + repr(path)) LOG.debug('get_default_settings for: ' + repr(path))
info = Settings.get_default_settings(app._oArgs) info = Settings.get_default_settings(app._args)
if not os.path.exists(path): if not os.path.exists(path):
merge_args_into_settings(app._oArgs, info) merge_args_into_settings(app._args, info)
else: else:
aC = self._changed(app._oArgs, info) aC = self._changed(app._args, info)
if aC: if aC:
title = 'Override profile with commandline - ' title = 'Override profile with commandline - '
if path: if path:
title += os.path.basename(path) title += os.path.basename(path)
text = 'Override profile with command-line settings? \n' text = 'Override profile with command-line settings? \n'
# text += '\n'.join([str(key) +'=' +str(val) for # text += '\n'.join([str(key) +'=' +str(val) for
# key,val in self._changed(app._oArgs).items()]) # key,val in self._changed(app._args).items()])
text += repr(aC) text += repr(aC)
reply = util_ui.question(text, title) reply = util_ui.question(text, title)
if reply: if reply:
merge_args_into_settings(app._oArgs, info) merge_args_into_settings(app._args, info)
info['audio'] = getattr(app._oArgs, 'audio') info['audio'] = getattr(app._args, 'audio')
info['video'] = getattr(app._oArgs, 'video') info['video'] = getattr(app._args, 'video')
super().__init__(info) super().__init__(info)
self._upgrade() self._upgrade()
@ -315,7 +316,6 @@ class Settings(dict):
# FixMe: match? /var/local/src/c-toxcore/toxcore/tox.h # FixMe: match? /var/local/src/c-toxcore/toxcore/tox.h
'ipv6_enabled': True, 'ipv6_enabled': True,
'udp_enabled': True, 'udp_enabled': True,
'trace_enabled': False,
'local_discovery_enabled': True, 'local_discovery_enabled': True,
'dht_announcements_enabled': True, 'dht_announcements_enabled': True,
'proxy_type': 0, 'proxy_type': 0,