update
This commit is contained in:
parent
e4b1b9c4d8
commit
3ce822fc27
@ -85,3 +85,7 @@ Work on Tox on this project is suspended until the
|
|||||||
This will probably be ported to Qt6 using qtpy
|
This will probably be ported to Qt6 using qtpy
|
||||||
https://github.com/spyder-ide/qtpy .
|
https://github.com/spyder-ide/qtpy .
|
||||||
|
|
||||||
|
Up-to-date code is on https://git.plastiras.org/emdee/toxygen
|
||||||
|
|
||||||
|
Work on this project is suspended until the
|
||||||
|
[MultiDevice](https://git.plastiras.org/emdee/tox_profile/wiki/MultiDevice-Announcements-POC) problem is solved. Fork me!
|
||||||
|
51
pyproject.tom
Normal file
51
pyproject.tom
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
[project]
|
||||||
|
name = "stem_examples"
|
||||||
|
description = "examples of using stem"
|
||||||
|
authors = [{ name = "emdee", email = "emdee@spm.plastiras.org" } ]
|
||||||
|
requires-python = ">=3.6"
|
||||||
|
dependencies = [
|
||||||
|
'stem',
|
||||||
|
]
|
||||||
|
keywords = ["stem", "python3", "tor"]
|
||||||
|
classifiers = [
|
||||||
|
"License :: OSI Approved",
|
||||||
|
"Operating System :: POSIX :: BSD :: FreeBSD",
|
||||||
|
"Operating System :: POSIX :: Linux",
|
||||||
|
"Programming Language :: Python :: 3 :: Only",
|
||||||
|
"Programming Language :: Python :: 3.6",
|
||||||
|
"Programming Language :: Python :: 3.7",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
|
"Programming Language :: Python :: Implementation :: CPython",
|
||||||
|
]
|
||||||
|
#
|
||||||
|
dynamic = ["version", "readme", ] # cannot be dynamic ['license']
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
toxygen = "toxygen.toxygen.main:main"
|
||||||
|
|
||||||
|
#[project.license]
|
||||||
|
#file = "LICENSE.md"
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
repository = "https://git.plastiras.org/emdee/toxygen"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools >= 61.0"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[tool.setuptools.dynamic]
|
||||||
|
version = {attr = "stem_examples.__version__"}
|
||||||
|
readme = {file = ["README.md", "ToDo.txt"]}
|
||||||
|
|
||||||
|
[tool.setuptools]
|
||||||
|
packages = ["toxygen"]
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
where = "toxygen"
|
||||||
|
|
||||||
|
[tool.setuptools.packages.package-data]
|
||||||
|
"*" = ["*.ui"]
|
||||||
|
|
@ -4,3 +4,8 @@ numpy
|
|||||||
opencv-python
|
opencv-python
|
||||||
pydenticon
|
pydenticon
|
||||||
cv2
|
cv2
|
||||||
|
gevent
|
||||||
|
greenlet
|
||||||
|
pydenticon
|
||||||
|
pyqtconsole
|
||||||
|
toxygen_wrapper
|
||||||
|
10
setup.py
10
setup.py
@ -5,8 +5,7 @@ from setuptools.command.install import install
|
|||||||
|
|
||||||
version = '1.0.0'
|
version = '1.0.0'
|
||||||
|
|
||||||
MODULES = ['argparse', 'PyQt5', 'PyAudio', 'numpy', 'opencv-python', 'cv2',
|
MODULES = open('requirements.txt', 'rt').readlines()
|
||||||
'pydenticon', 'pyqtconsole', 'toxygen_wrapper'] # qweechat
|
|
||||||
|
|
||||||
def get_packages():
|
def get_packages():
|
||||||
directory = os.path.join(os.path.dirname(__file__), 'tox_wrapper')
|
directory = os.path.join(os.path.dirname(__file__), 'tox_wrapper')
|
||||||
@ -35,11 +34,18 @@ setup(name='Toxygen',
|
|||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Programming Language :: Python :: 3 :: Only',
|
'Programming Language :: Python :: 3 :: Only',
|
||||||
|
"Programming Language :: Python :: 3.6",
|
||||||
|
"Programming Language :: Python :: 3.7",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
'Programming Language :: Python :: 3.11',
|
'Programming Language :: Python :: 3.11',
|
||||||
],
|
],
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': ['toxygen=toxygen.main:main']
|
'console_scripts': ['toxygen=toxygen.main:main']
|
||||||
},
|
},
|
||||||
|
package_data={"": ["*.ui"],},
|
||||||
cmdclass={
|
cmdclass={
|
||||||
'install': InstallScript,
|
'install': InstallScript,
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
|
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
|
||||||
import pyaudio
|
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
import itertools
|
import itertools
|
||||||
@ -8,6 +7,8 @@ from tox_wrapper.toxav_enums import *
|
|||||||
from tox_wrapper.tests import support_testing as ts
|
from tox_wrapper.tests import support_testing as ts
|
||||||
from tox_wrapper.tests.support_testing import LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG, LOG_TRACE
|
from tox_wrapper.tests.support_testing import LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG, LOG_TRACE
|
||||||
|
|
||||||
|
with ts.ignoreStderr():
|
||||||
|
import pyaudio
|
||||||
from av import screen_sharing
|
from av import screen_sharing
|
||||||
from av.call import Call
|
from av.call import Call
|
||||||
import common.tox_save
|
import common.tox_save
|
||||||
|
@ -161,6 +161,12 @@ class BaseContact:
|
|||||||
# Widgets
|
# Widgets
|
||||||
|
|
||||||
def init_widget(self):
|
def init_widget(self):
|
||||||
|
# File "/mnt/o/var/local/src/toxygen/toxygen/contacts/contacts_manager.py", line 252, in filtration_and_sorting
|
||||||
|
# contact.set_widget(item_widget)
|
||||||
|
# File "/mnt/o/var/local/src/toxygen/toxygen/contacts/contact.py", line 320, in set_widget
|
||||||
|
if not self._widget:
|
||||||
|
LOG_WARN("BC.init_widget self._widget is NULL")
|
||||||
|
return
|
||||||
self._widget.name.setText(self._name)
|
self._widget.name.setText(self._name)
|
||||||
self._widget.status_message.setText(self._status_message)
|
self._widget.status_message.setText(self._status_message)
|
||||||
if hasattr(self._widget, 'kind'):
|
if hasattr(self._widget, 'kind'):
|
||||||
|
@ -33,9 +33,11 @@ class ContactProvider(tox_save.ToxSave):
|
|||||||
if friend is not None:
|
if friend is not None:
|
||||||
return friend
|
return friend
|
||||||
friend = self._friend_factory.create_friend_by_public_key(public_key)
|
friend = self._friend_factory.create_friend_by_public_key(public_key)
|
||||||
|
if friend is None:
|
||||||
|
LOG_WARN(f"CP.get_friend_by_public_key NULL {friend} ")
|
||||||
|
else:
|
||||||
self._add_to_cache(public_key, friend)
|
self._add_to_cache(public_key, friend)
|
||||||
LOG_INFO(f"CP.get_friend_by_public_key ADDED {friend} ")
|
LOG_DEBUG(f"CP.get_friend_by_public_key ADDED {friend} ")
|
||||||
|
|
||||||
return friend
|
return friend
|
||||||
|
|
||||||
def get_all_friends(self):
|
def get_all_friends(self):
|
||||||
@ -72,7 +74,7 @@ class ContactProvider(tox_save.ToxSave):
|
|||||||
def get_group_by_number(self, group_number):
|
def get_group_by_number(self, group_number):
|
||||||
group = None
|
group = None
|
||||||
try:
|
try:
|
||||||
LOG_INFO(f"CP.CP.group_get_number {group_number} ")
|
# LOG_DEBUG(f"CP.CP.group_get_number {group_number} ")
|
||||||
# original code
|
# original code
|
||||||
chat_id = self._tox.group_get_chat_id(group_number)
|
chat_id = self._tox.group_get_chat_id(group_number)
|
||||||
if chat_id is None:
|
if chat_id is None:
|
||||||
@ -110,7 +112,7 @@ class ContactProvider(tox_save.ToxSave):
|
|||||||
return group
|
return group
|
||||||
group = self._group_factory.create_group_by_public_key(public_key)
|
group = self._group_factory.create_group_by_public_key(public_key)
|
||||||
if group is None:
|
if group is None:
|
||||||
LOG_ERROR(f"get_group_by_public_key NULL group public_key={public_key}")
|
LOG_WARN(f"get_group_by_public_key NULL group public_key={public_key}")
|
||||||
else:
|
else:
|
||||||
self._add_to_cache(public_key, group)
|
self._add_to_cache(public_key, group)
|
||||||
|
|
||||||
@ -123,13 +125,17 @@ class ContactProvider(tox_save.ToxSave):
|
|||||||
|
|
||||||
def get_group_peer_by_id(self, group, peer_id):
|
def get_group_peer_by_id(self, group, peer_id):
|
||||||
peer = group.get_peer_by_id(peer_id)
|
peer = group.get_peer_by_id(peer_id)
|
||||||
if peer:
|
if peer is not None:
|
||||||
return self._get_group_peer(group, peer)
|
return self._get_group_peer(group, peer)
|
||||||
|
LOG_WARN(f"get_group_peer_by_id peer_id={peer_id}")
|
||||||
|
return None
|
||||||
|
|
||||||
def get_group_peer_by_public_key(self, group, public_key):
|
def get_group_peer_by_public_key(self, group, public_key):
|
||||||
peer = group.get_peer_by_public_key(public_key)
|
peer = group.get_peer_by_public_key(public_key)
|
||||||
if peer:
|
if peer is not None:
|
||||||
return self._get_group_peer(group, peer)
|
return self._get_group_peer(group, peer)
|
||||||
|
LOG_WARN(f"get_group_peer_by_public_key public_key={public_key}")
|
||||||
|
return None
|
||||||
|
|
||||||
# All contacts
|
# All contacts
|
||||||
|
|
||||||
|
@ -99,6 +99,10 @@ class ContactsManager(ToxSave):
|
|||||||
LOG.warn(f"ERROR NULL {self._contacts[self._active_contact]} {contact.tox_id}")
|
LOG.warn(f"ERROR NULL {self._contacts[self._active_contact]} {contact.tox_id}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if not hasattr(contact, 'tox_id'):
|
||||||
|
LOG.warn(f"ERROR is_contact_active no contact.tox_id {type(contact)} contact={contact}")
|
||||||
|
return False
|
||||||
|
|
||||||
return self._contacts[self._active_contact].tox_id == contact.tox_id
|
return self._contacts[self._active_contact].tox_id == contact.tox_id
|
||||||
|
|
||||||
# Reconnection support
|
# Reconnection support
|
||||||
@ -142,7 +146,11 @@ class ContactsManager(ToxSave):
|
|||||||
current_contact.curr_text = self._screen.messageEdit.toPlainText()
|
current_contact.curr_text = self._screen.messageEdit.toPlainText()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# IndexError: list index out of range
|
# IndexError: list index out of range
|
||||||
|
if value >= len(self._contacts):
|
||||||
|
LOG.warn("CM.set_active value too big: {{self._contacts}}")
|
||||||
|
return
|
||||||
contact = self._contacts[value]
|
contact = self._contacts[value]
|
||||||
self._subscribe_to_events(contact)
|
self._subscribe_to_events(contact)
|
||||||
contact.remove_invalid_unsent_files()
|
contact.remove_invalid_unsent_files()
|
||||||
@ -171,9 +179,8 @@ class ContactsManager(ToxSave):
|
|||||||
# self._screen.call_finished()
|
# self._screen.call_finished()
|
||||||
self._set_current_contact_data(contact)
|
self._set_current_contact_data(contact)
|
||||||
self._active_contact_changed(contact)
|
self._active_contact_changed(contact)
|
||||||
except Exception as ex: # no friend found. ignore
|
except Exception as e: # no friend found. ignore
|
||||||
LOG.warn(f"no friend found. Friend value: {value!s}")
|
LOG.warn(f"CM.set_active EXCEPTION value:{value} len={len(self._contacts)} {e}")
|
||||||
LOG.error('in set active: ' + str(ex))
|
|
||||||
# gulp raise
|
# gulp raise
|
||||||
|
|
||||||
active_contact = property(get_active, set_active)
|
active_contact = property(get_active, set_active)
|
||||||
@ -249,6 +256,9 @@ class ContactsManager(ToxSave):
|
|||||||
for index, contact in enumerate(self._contacts):
|
for index, contact in enumerate(self._contacts):
|
||||||
list_item = self._screen.friends_list.item(index)
|
list_item = self._screen.friends_list.item(index)
|
||||||
item_widget = self._screen.friends_list.itemWidget(list_item)
|
item_widget = self._screen.friends_list.itemWidget(list_item)
|
||||||
|
if not item_widget:
|
||||||
|
LOG_WARN("CM.filtration_and_sorting( item_widget is NULL")
|
||||||
|
continue
|
||||||
contact.set_widget(item_widget)
|
contact.set_widget(item_widget)
|
||||||
|
|
||||||
for index, friend in enumerate(self._contacts):
|
for index, friend in enumerate(self._contacts):
|
||||||
@ -287,16 +297,16 @@ class ContactsManager(ToxSave):
|
|||||||
def get_or_create_group_peer_contact(self, group_number, peer_id):
|
def get_or_create_group_peer_contact(self, group_number, peer_id):
|
||||||
group = self.get_group_by_number(group_number)
|
group = self.get_group_by_number(group_number)
|
||||||
peer = group.get_peer_by_id(peer_id)
|
peer = group.get_peer_by_id(peer_id)
|
||||||
if peer is None: # broken? is 0 allowed?
|
if peer is None:
|
||||||
if not hasattr(peer, 'public_key') or not peer.public_key:
|
LOG.warn(f'get_or_create_group_peer_contact group_number={group_number} peer_id={peer_id} peer={peer}')
|
||||||
LOG.error(f'no peer public_key ' + repr(dir(peer)))
|
return None
|
||||||
else:
|
LOG.debug(f'get_or_create_group_peer_contact group_number={group_number} peer_id={peer_id} peer={peer}')
|
||||||
if not self.check_if_contact_exists(peer.public_key):
|
if not self.check_if_contact_exists(peer.public_key):
|
||||||
self.add_group_peer(group, peer)
|
contact = self.add_group_peer(group, peer)
|
||||||
|
# dunno
|
||||||
|
return contact
|
||||||
|
# me - later wrong kind of object?
|
||||||
return self.get_contact_by_tox_id(peer.public_key)
|
return self.get_contact_by_tox_id(peer.public_key)
|
||||||
else:
|
|
||||||
LOG.warn(f'no peer group_number={group_number} peer_id={peer_id}')
|
|
||||||
return peer
|
|
||||||
|
|
||||||
def check_if_contact_exists(self, tox_id):
|
def check_if_contact_exists(self, tox_id):
|
||||||
return any(filter(lambda c: c.tox_id == tox_id, self._contacts))
|
return any(filter(lambda c: c.tox_id == tox_id, self._contacts))
|
||||||
@ -436,6 +446,7 @@ class ContactsManager(ToxSave):
|
|||||||
self._contacts.append(contact)
|
self._contacts.append(contact)
|
||||||
contact.reset_avatar(self._settings['identicons'])
|
contact.reset_avatar(self._settings['identicons'])
|
||||||
self._save_profile()
|
self._save_profile()
|
||||||
|
return contact
|
||||||
|
|
||||||
def remove_group_peer_by_id(self, group, peer_id):
|
def remove_group_peer_by_id(self, group, peer_id):
|
||||||
peer = group.get_peer_by_id(peer_id)
|
peer = group.get_peer_by_id(peer_id)
|
||||||
|
@ -107,7 +107,7 @@ class GroupChat(contact.Contact, ToxSave):
|
|||||||
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}")
|
||||||
return []
|
return None
|
||||||
|
|
||||||
def get_peer_by_public_key(self, public_key):
|
def get_peer_by_public_key(self, public_key):
|
||||||
peers = list(filter(lambda p: p.public_key == public_key, self._peers))
|
peers = list(filter(lambda p: p.public_key == public_key, self._peers))
|
||||||
@ -117,7 +117,7 @@ class GroupChat(contact.Contact, ToxSave):
|
|||||||
return peers[0]
|
return peers[0]
|
||||||
else:
|
else:
|
||||||
LOG_WARN(f"get_peer_by_public_key empty peers for {public_key}")
|
LOG_WARN(f"get_peer_by_public_key empty peers for {public_key}")
|
||||||
return []
|
return None
|
||||||
|
|
||||||
def remove_all_peers_except_self(self):
|
def remove_all_peers_except_self(self):
|
||||||
self._peers = self._peers[:1]
|
self._peers = self._peers[:1]
|
||||||
|
@ -72,7 +72,11 @@ def setup_default_audio():
|
|||||||
|
|
||||||
def setup_video(oArgs):
|
def setup_video(oArgs):
|
||||||
video = setup_default_video()
|
video = setup_default_video()
|
||||||
if oArgs.video_input == '-1':
|
# this is messed up - no video_input in oArgs
|
||||||
|
# parser.add_argument('--video_input', type=str,)
|
||||||
|
if not hasattr(oArgs, 'video_input'):
|
||||||
|
video['device'] = video['output_devices'][0]
|
||||||
|
elif oArgs.video_input == '-1':
|
||||||
video['device'] = video['output_devices'][1]
|
video['device'] = video['output_devices'][1]
|
||||||
else:
|
else:
|
||||||
video['device'] = oArgs.video_input
|
video['device'] = oArgs.video_input
|
||||||
@ -165,7 +169,7 @@ def setup_audio(oArgs):
|
|||||||
def setup_default_video():
|
def setup_default_video():
|
||||||
default_video = ["-1"]
|
default_video = ["-1"]
|
||||||
default_video.extend(ts.get_video_indexes())
|
default_video.extend(ts.get_video_indexes())
|
||||||
LOG.info(f"Video input choices: {default_video!r}")
|
LOG.info(f"Video input choices: {default_video}")
|
||||||
video = {'device': -1, 'width': 320, 'height': 240, 'x': 0, 'y': 0}
|
video = {'device': -1, 'width': 320, 'height': 240, 'x': 0, 'y': 0}
|
||||||
video['output_devices'] = default_video
|
video['output_devices'] = default_video
|
||||||
return video
|
return video
|
||||||
@ -179,7 +183,7 @@ def main_parser(_=None, iMode=2):
|
|||||||
lIpV6Choices=[bIpV6, 'False']
|
lIpV6Choices=[bIpV6, 'False']
|
||||||
|
|
||||||
audio = setup_default_audio()
|
audio = setup_default_audio()
|
||||||
default_video = setup_default_video()
|
default_video = setup_default_video()['output_devices']
|
||||||
|
|
||||||
parser = ts.oMainArgparser()
|
parser = ts.oMainArgparser()
|
||||||
parser.add_argument('--version', action='store_true', help='Prints Toxygen version')
|
parser.add_argument('--version', action='store_true', help='Prints Toxygen version')
|
||||||
@ -225,7 +229,7 @@ def main_parser(_=None, iMode=2):
|
|||||||
help='Update program (broken)')
|
help='Update program (broken)')
|
||||||
parser.add_argument('--video_input', type=str,
|
parser.add_argument('--video_input', type=str,
|
||||||
default=-1,
|
default=-1,
|
||||||
choices=default_video['output_devices'],
|
choices=default_video,
|
||||||
help="Video input device number - /dev/video?")
|
help="Video input device number - /dev/video?")
|
||||||
parser.add_argument('--audio_input', type=str,
|
parser.add_argument('--audio_input', type=str,
|
||||||
default=oPYA.get_default_input_device_info()['name'],
|
default=oPYA.get_default_input_device_info()['name'],
|
||||||
@ -266,6 +270,8 @@ lKEEP_SETTINGS = ['uri',
|
|||||||
'ipv6_enabled',
|
'ipv6_enabled',
|
||||||
'udp_enabled',
|
'udp_enabled',
|
||||||
'local_discovery_enabled',
|
'local_discovery_enabled',
|
||||||
|
'trace_enabled',
|
||||||
|
|
||||||
'theme',
|
'theme',
|
||||||
'network',
|
'network',
|
||||||
'message_font_size',
|
'message_font_size',
|
||||||
@ -283,9 +289,11 @@ lKEEP_SETTINGS = ['uri',
|
|||||||
|
|
||||||
class A(): pass
|
class A(): pass
|
||||||
|
|
||||||
def main(lArgs):
|
def main(lArgs=None):
|
||||||
global oPYA
|
global oPYA
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
|
if lArgs is None:
|
||||||
|
lArgs = sys.argv[1:]
|
||||||
parser = main_parser()
|
parser = main_parser()
|
||||||
default_ns = parser.parse_args([])
|
default_ns = parser.parse_args([])
|
||||||
oArgs = parser.parse_args(lArgs)
|
oArgs = parser.parse_args(lArgs)
|
||||||
@ -328,7 +336,10 @@ def main(lArgs):
|
|||||||
|
|
||||||
oApp = app.App(__version__, oArgs)
|
oApp = app.App(__version__, oArgs)
|
||||||
# for pyqtconsole
|
# for pyqtconsole
|
||||||
__builtins__.app = oApp
|
try:
|
||||||
|
setattr(__builtins__, 'app', oApp)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
i = oApp.iMain()
|
i = oApp.iMain()
|
||||||
return i
|
return i
|
||||||
|
|
||||||
|
@ -192,20 +192,32 @@ class Messenger(tox_save.ToxSave):
|
|||||||
return
|
return
|
||||||
if group.number < 0:
|
if group.number < 0:
|
||||||
return
|
return
|
||||||
if peer_id and peer_id < 0:
|
if peer_id is not None and peer_id < 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
assert_main_thread()
|
assert_main_thread()
|
||||||
# FixMe: peer_id is None?
|
|
||||||
group_peer_contact = self._contacts_manager.get_or_create_group_peer_contact(group_number, peer_id)
|
|
||||||
# group_peer_contact now may be None
|
|
||||||
group = self._get_group_by_number(group_number)
|
group = self._get_group_by_number(group_number)
|
||||||
messages = self._split_message(text.encode('utf-8'))
|
messages = self._split_message(text.encode('utf-8'))
|
||||||
|
|
||||||
|
# FixMe: peer_id is None?
|
||||||
|
group_peer_contact = self._contacts_manager.get_or_create_group_peer_contact(group_number, peer_id)
|
||||||
|
if group_peer_contact is None:
|
||||||
|
LOG.warn("M.group_send_private_message group_peer_contact is None")
|
||||||
|
return
|
||||||
|
# group_peer_contact now may be None
|
||||||
|
|
||||||
t = util.get_unix_time()
|
t = util.get_unix_time()
|
||||||
for message in messages:
|
for message in messages:
|
||||||
self._tox.group_send_private_message(group_number, peer_id, message_type, message)
|
bRet = self._tox.group_send_private_message(group_number, peer_id, message_type, message)
|
||||||
|
if not bRet:
|
||||||
|
LOG.warn("M.group_send_private_messag failed")
|
||||||
|
continue
|
||||||
message_author = MessageAuthor(group.get_self_name(), MESSAGE_AUTHOR['GC_PEER'])
|
message_author = MessageAuthor(group.get_self_name(), MESSAGE_AUTHOR['GC_PEER'])
|
||||||
message = OutgoingTextMessage(text, message_author, t, message_type)
|
message = OutgoingTextMessage(text, message_author, t, message_type)
|
||||||
|
# AttributeError: 'GroupChatPeer' object has no attribute 'append_message'
|
||||||
|
if not hasattr(group_peer_contact, 'append_message'):
|
||||||
|
LOG.warn("M. group_peer_contact has no append_message group_peer_contact={group_peer_contact}")
|
||||||
|
else:
|
||||||
group_peer_contact.append_message(message)
|
group_peer_contact.append_message(message)
|
||||||
if not self._contacts_manager.is_contact_active(group_peer_contact):
|
if not self._contacts_manager.is_contact_active(group_peer_contact):
|
||||||
return
|
return
|
||||||
|
@ -473,7 +473,11 @@ def group_private_message(window, tray, tox, messenger, settings, profile):
|
|||||||
if window.isActiveWindow():
|
if window.isActiveWindow():
|
||||||
return
|
return
|
||||||
bl = settings['notify_all_gc'] or profile.name in message
|
bl = settings['notify_all_gc'] or profile.name in message
|
||||||
|
try:
|
||||||
name = tox.group_peer_get_name(group_number, peer_id)
|
name = tox.group_peer_get_name(group_number, peer_id)
|
||||||
|
except Exception as e:
|
||||||
|
LOG_WARN("tox.group_peer_get_name {group_number} {peer_id}")
|
||||||
|
name = ''
|
||||||
if settings['notifications'] and settings['tray_icon'] \
|
if settings['notifications'] and settings['tray_icon'] \
|
||||||
and profile.status != TOX_USER_STATUS['BUSY'] \
|
and profile.status != TOX_USER_STATUS['BUSY'] \
|
||||||
and (not settings.locked) and bl:
|
and (not settings.locked) and bl:
|
||||||
|
@ -69,12 +69,9 @@ def tox_factory(data=None, settings=None, args=None, app=None):
|
|||||||
|
|
||||||
if 'trace_enabled' in settings and not settings['trace_enabled']:
|
if 'trace_enabled' in settings and not settings['trace_enabled']:
|
||||||
LOG_DEBUG("settings['trace_enabled' disabled" )
|
LOG_DEBUG("settings['trace_enabled' disabled" )
|
||||||
elif tox_options._options_pointer:
|
elif tox_options._options_pointer and \
|
||||||
c_callback = CFUNCTYPE(None, c_void_p, c_int, c_char_p, c_int, c_char_p, c_char_p, c_void_p)
|
'trace_enabled' in settings and settings['trace_enabled']:
|
||||||
tox_options.self_logger_cb = c_callback(ts.tox_log_cb)
|
ts.vAddLoggerCallback(tox_options)
|
||||||
tox_wrapper.tox.Tox.libtoxcore.tox_options_set_log_callback(
|
|
||||||
tox_options._options_pointer,
|
|
||||||
tox_options.self_logger_cb)
|
|
||||||
LOG_INFO("c-toxcore trace_enabled enabled" )
|
LOG_INFO("c-toxcore trace_enabled enabled" )
|
||||||
else:
|
else:
|
||||||
LOG_WARN("No tox_options._options_pointer to add self_logger_cb" )
|
LOG_WARN("No tox_options._options_pointer to add self_logger_cb" )
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
import os.path
|
||||||
import utils.util
|
import utils.util
|
||||||
import wave
|
import wave
|
||||||
|
|
||||||
|
import tox_wrapper.tests.support_testing as ts
|
||||||
|
with ts.ignoreStderr():
|
||||||
import pyaudio
|
import pyaudio
|
||||||
import os.path
|
|
||||||
|
|
||||||
global LOG
|
global LOG
|
||||||
import logging
|
import logging
|
||||||
|
@ -1756,7 +1756,7 @@ class ToxSuite(unittest.TestCase):
|
|||||||
else:
|
else:
|
||||||
LOG.info("passed test_tox_savedata")
|
LOG.info("passed test_tox_savedata")
|
||||||
|
|
||||||
def vOargsToxPreamble(oArgs, Tox, ToxTest):
|
def vOargsToxPreamble(oArgs, Tox, ToxTest) -> None:
|
||||||
|
|
||||||
ts.vSetupLogging(oArgs)
|
ts.vSetupLogging(oArgs)
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import threading
|
import threading
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
import pyaudio
|
|
||||||
import wave
|
import wave
|
||||||
|
|
||||||
from ui import widgets
|
from ui import widgets
|
||||||
import utils.util as util
|
import utils.util as util
|
||||||
import tox_wrapper.tests.support_testing as ts
|
import tox_wrapper.tests.support_testing as ts
|
||||||
|
with ts.ignoreStderr():
|
||||||
|
import pyaudio
|
||||||
|
|
||||||
global LOG
|
global LOG
|
||||||
import logging
|
import logging
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
|
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets, uic
|
from PyQt5 import QtCore, QtGui, QtWidgets, uic
|
||||||
import pyaudio
|
|
||||||
|
|
||||||
from user_data.settings import *
|
from user_data.settings import *
|
||||||
from utils.util import *
|
from utils.util import *
|
||||||
@ -8,6 +8,8 @@ from ui.widgets import CenteredWidget, DataLabel, LineEdit, RubberBandWindow
|
|||||||
import updater.updater as updater
|
import updater.updater as updater
|
||||||
import utils.ui as util_ui
|
import utils.ui as util_ui
|
||||||
import tox_wrapper.tests.support_testing as ts
|
import tox_wrapper.tests.support_testing as ts
|
||||||
|
with ts.ignoreStderr():
|
||||||
|
import pyaudio
|
||||||
from user_data import settings
|
from user_data import settings
|
||||||
|
|
||||||
global LOG
|
global LOG
|
||||||
|
@ -17,7 +17,6 @@ LOG = logging.getLogger('settings')
|
|||||||
|
|
||||||
def merge_args_into_settings(args, settings):
|
def merge_args_into_settings(args, settings):
|
||||||
if args:
|
if args:
|
||||||
print(repr(args.__dict__.keys()))
|
|
||||||
if not hasattr(args, 'audio'):
|
if not hasattr(args, 'audio'):
|
||||||
LOG.warn('No audio ' +repr(args))
|
LOG.warn('No audio ' +repr(args))
|
||||||
settings['audio'] = getattr(args, 'audio')
|
settings['audio'] = getattr(args, 'audio')
|
||||||
@ -131,17 +130,17 @@ class Settings(dict):
|
|||||||
Settings of current profile + global app settings
|
Settings of current profile + global app settings
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, toxes, path, app):
|
def __init__(self, toxes, json_path, app):
|
||||||
self._path = path
|
|
||||||
self._profile_path = path.replace('.json', '.tox')
|
|
||||||
self._toxes = toxes
|
self._toxes = toxes
|
||||||
self._app = app
|
self._app = app
|
||||||
self._path = app._path
|
self._path = app._path
|
||||||
self._args = app._args
|
self._args = app._args
|
||||||
self._oArgs = app._args
|
self._oArgs = app._args
|
||||||
self._log = lambda l: LOG.log(self._oArgs.loglevel, l)
|
self._log = lambda l: LOG.log(self._oArgs.loglevel, l)
|
||||||
|
self._profile_path = app._path # json_path.replace('.json', '.tox')
|
||||||
|
|
||||||
self._settings_saved_event = Event()
|
self._settings_saved_event = Event()
|
||||||
|
path = json_path.replace('.tox', '.json')
|
||||||
if path and os.path.isfile(path):
|
if path and os.path.isfile(path):
|
||||||
try:
|
try:
|
||||||
with open(path, 'rb') as fl:
|
with open(path, 'rb') as fl:
|
||||||
@ -151,9 +150,9 @@ class Settings(dict):
|
|||||||
info = json.loads(str(data, 'utf-8'))
|
info = json.loads(str(data, 'utf-8'))
|
||||||
LOG.debug('Parsed settings from: ' + str(path))
|
LOG.debug('Parsed settings from: ' + str(path))
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
title = 'Error opening/parsing settings file: '
|
title = f"Error opening/parsing settings file:"
|
||||||
text = title + path
|
text = title +f"\n{path}\n"
|
||||||
LOG.error(title +str(ex))
|
LOG.error(text +str(ex))
|
||||||
util_ui.message_box(text, title)
|
util_ui.message_box(text, title)
|
||||||
info = Settings.get_default_settings(app._args)
|
info = Settings.get_default_settings(app._args)
|
||||||
user_data.settings.clean_settings(info)
|
user_data.settings.clean_settings(info)
|
||||||
@ -161,7 +160,7 @@ class Settings(dict):
|
|||||||
LOG.debug('get_default_settings for: ' + repr(path))
|
LOG.debug('get_default_settings for: ' + repr(path))
|
||||||
info = Settings.get_default_settings(app._args)
|
info = Settings.get_default_settings(app._args)
|
||||||
|
|
||||||
if not os.path.exists(path):
|
if not path or not os.path.exists(path):
|
||||||
merge_args_into_settings(app._args, info)
|
merge_args_into_settings(app._args, info)
|
||||||
else:
|
else:
|
||||||
aC = self._changed(app._args, info)
|
aC = self._changed(app._args, info)
|
||||||
@ -178,12 +177,16 @@ class Settings(dict):
|
|||||||
merge_args_into_settings(app._args, info)
|
merge_args_into_settings(app._args, info)
|
||||||
info['audio'] = getattr(app._args, 'audio')
|
info['audio'] = getattr(app._args, 'audio')
|
||||||
info['video'] = getattr(app._args, 'video')
|
info['video'] = getattr(app._args, 'video')
|
||||||
|
if getattr(app._args, 'trace_enabled'):
|
||||||
info['trace_enabled'] = getattr(app._args, 'trace_enabled')
|
info['trace_enabled'] = getattr(app._args, 'trace_enabled')
|
||||||
|
else:
|
||||||
|
LOG.warn("app._args, 'trace_enabled")
|
||||||
|
info['trace_enabled'] = False
|
||||||
super().__init__(info)
|
super().__init__(info)
|
||||||
self._upgrade()
|
self._upgrade()
|
||||||
|
|
||||||
LOG.info('Parsed settings from: ' + str(path))
|
LOG.info('Parsed settings from: ' + str(path))
|
||||||
ex = f"self=id(self) {self!r}"
|
ex = f"self=id(self) {self}"
|
||||||
LOG.debug(ex)
|
LOG.debug(ex)
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
@ -206,10 +209,16 @@ 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:
|
||||||
|
#?
|
||||||
|
self._path = os.path.join(get_user_config_path(), 'toxygen.json')
|
||||||
tmp = self._path + str(os.getpid())
|
tmp = self._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'):
|
||||||
|
os.remove(self._path+'.bak')
|
||||||
|
os.rename(self._path, self._path+'.bak')
|
||||||
os.rename(tmp, self._path)
|
os.rename(tmp, self._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 {self._path} ' +str(e))
|
||||||
@ -221,17 +230,17 @@ class Settings(dict):
|
|||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
|
|
||||||
def set_active_profile(self):
|
def set_active_profile(self, profile_path):
|
||||||
"""
|
"""
|
||||||
Mark current profile as active
|
Mark current profile as active
|
||||||
"""
|
"""
|
||||||
path = self._profile_path + '.lock'
|
path = profile_path + '.lock'
|
||||||
try:
|
try:
|
||||||
import shutil
|
import shutil
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
shutil.copy2(self._profile_path, path)
|
shutil.copy2(profile_path, path)
|
||||||
# need to open this with the same perms as _profile_path
|
# need to open this with the same perms as _profile_path
|
||||||
# copy profile_path and then write?
|
# copy profile_path and then write?
|
||||||
with open(path, 'wb') as fl:
|
with open(path, 'wb') as fl:
|
||||||
@ -250,9 +259,9 @@ class Settings(dict):
|
|||||||
# Static methods
|
# Static methods
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_auto_profile():
|
def get_auto_profile(appdir):
|
||||||
# self._path =
|
# self._path =
|
||||||
p = os.path.join(os.path.dirname(self._app._path), 'toxygen.json')
|
p = os.path.join(appdir, 'toxygen.json')
|
||||||
if not os.path.isfile(p):
|
if not os.path.isfile(p):
|
||||||
return None
|
return None
|
||||||
with open(p) as fl:
|
with open(p) as fl:
|
||||||
@ -260,14 +269,15 @@ class Settings(dict):
|
|||||||
try:
|
try:
|
||||||
auto = json.loads(data)
|
auto = json.loads(data)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.warn(f"json.loads {data}: {ex!s}")
|
LOG.warn(f"json.loads {data}: {ex}")
|
||||||
auto = {}
|
auto = {}
|
||||||
if 'profile_path' in auto:
|
if 'profile_path' in auto:
|
||||||
path = str(auto['profile_path'])
|
path = str(auto['profile_path'])
|
||||||
if not os.path.isabs(path):
|
if not os.path.isabs(path):
|
||||||
path = join_path(path, curr_directory(__file__))
|
path = join_path(path, os.path.dirname(os.path.realpath(__file__)))
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
return path
|
return path
|
||||||
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def supported_languages():
|
def supported_languages():
|
||||||
@ -276,7 +286,7 @@ class Settings(dict):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_auto_profile(path):
|
def set_auto_profile(path):
|
||||||
p = os.path.join(os.path.dirname(self._app._path), 'toxygen.json')
|
p = os.path.join(os.path.dirname(path), 'toxygen.json')
|
||||||
if os.path.isfile(p):
|
if os.path.isfile(p):
|
||||||
with open(p) as fl:
|
with open(p) as fl:
|
||||||
data = fl.read()
|
data = fl.read()
|
||||||
@ -289,7 +299,7 @@ class Settings(dict):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def reset_auto_profile():
|
def reset_auto_profile():
|
||||||
p = os.path.join(os.path.dirname(self._app._path), 'toxygen.json')
|
p = os.path.join(os.path.dirname(app._path), 'toxygen.json')
|
||||||
if os.path.isfile(p):
|
if os.path.isfile(p):
|
||||||
with open(p) as fl:
|
with open(p) as fl:
|
||||||
data = fl.read()
|
data = fl.read()
|
||||||
|
Loading…
Reference in New Issue
Block a user