update
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled

This commit is contained in:
emdee@spm.plastiras.org 2024-02-04 01:07:37 +00:00
parent 74a29f7ce3
commit 75ac0b2e07
8 changed files with 122 additions and 88 deletions

1
.gitignore vendored
View File

@ -172,3 +172,4 @@ cython_debug/
*~
.rsync.sh
.pyanal.out

View File

@ -2,7 +2,7 @@
ROLE=logging
PYTHONPATH=$PWD/wrapper /var/local/bin/python3.bash `which pyanalyze` \
tox_wrapper/tox.py tox_wrapper/tests/tests_wrapper.py \
PYTHONPATH=$PWD/src /var/local/bin/python3.bash `which pyanalyze` \
src/tox_wrapper/tox.py src/tox_wrapper/tests/tests_wrapper.py \
> .pyanal.out 2>&1

View File

@ -1,16 +1,16 @@
#!/bin/sh
EXE=/var/local/bin/pydev_pylint.bash
ROLE=logging
EXE=/usr/local/bin/toxcore_pylint.bash
ROLE=toxcore
$EXE --recursive y --verbose --py-version 3.11 \
--output-format colorized --rcfile .pylint.rc \
-E -f text tox_wrapper/*py tox_wrapper/tests/*py > .pylint.err
-E -f text src/tox_wrapper/*py src/tox_wrapper/tests/*py > .pylint.err
retval=$?
$EXE --recursive y --verbose --py-version 3.11 \
--output-format colorized --rcfile .pylint.rc \
tox_wrapper/*py tox_wrapper/tests/*py > .pylint.out
src/tox_wrapper/*py src/tox_wrapper/tests/*py > .pylint.out
sed -e "/Module 'os' has no/d" \
-e "/Undefined variable 'app'/d" \

View File

@ -1,6 +1,8 @@
PREFIX=/usr/local
PYTHON=python3.sh
PIP=pip3.sh
iTEST_TIMEOUT=60
fSOCKET_TIMEOUT=15.0
prepare::
bash .pylint.sh
@ -21,8 +23,23 @@ help::
$(PYTHON) src/tox_wrapper/tests/tests_wrapper.py --help
test::
test_direct::
PYTHONPATH=$${PWD}/src \
$(PYTHON) src/tox_wrapper/tests/tests_wrapper.py
sudo -u bin $(PYTHON) src/tox_wrapper/tests/tests_wrapper.py \
--test_timeout=${iTEST_TIMEOUT} \
--nodes_json=/tmp/toxygen_nodes.json \
--udp_enabled=True \
--trace_enabled=False --loglevel=10
test_proxy::
PYTHONPATH=$${PWD}/src \
$(PYTHON) src/tox_wrapper/tests/tests_wrapper.py \
--test_timeout=${iTEST_TIMEOUT} \
--proxy_host=127.0.0.1 \
--proxy_port=9050 \
--proxy_type=2 \
--nodes_json=$$HOME/.config/tox/DHTnodes.json \
--trace_enabled=False --loglevel=10
clean::
rm -f .[a-z]* *~ */*~ */*/*~

View File

@ -89,5 +89,8 @@ Others include:
To our point of view, the ability of CTYPEs to follow code in the
debugger is a crucial advantage.
Up-to-date code is on https://git.plastiras.org/emdee/toxygen_wrapper
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!

View File

@ -14,6 +14,7 @@ import sys
import time
import traceback
import unittest
import traceback
from ctypes import *
from random import Random
import functools
@ -46,11 +47,6 @@ from tox_wrapper.tests.support_onions import (is_valid_fingerprint,
oGetStemController,
sMapaddressResolv, sTorResolve)
try:
from user_data.settings import get_user_config_path
except ImportError:
get_user_config_path = None
# LOG=util.log
global LOG
LOG = logging.getLogger()
@ -96,6 +92,7 @@ iTHREAD_TIMEOUT = 1
iTHREAD_SLEEP = 1
iTHREAD_JOINS = 8
iNODES = 6
fSOCKET_TIMEOUT = 15.0
lToxSamplerates = [8000, 12000, 16000, 24000, 48000]
lToxSampleratesK = [8, 12, 16, 24, 48]
@ -192,7 +189,6 @@ def clean_booleans(oArgs) -> None:
else:
setattr(oArgs, key, True)
import traceback
def toxygen_log_cb(_, level: int, source, line: int, func, message, userdata=None):
"""
* @param level The severity of the log message.
@ -210,6 +206,7 @@ def toxygen_log_cb(_, level: int, source, line: int, func, message, userdata=Non
if type(message) == bytes:
message = str(message, 'UTF-8')
if source == 'network.c':
if line in [944, 660, 781, 789]: return
squelch='network family 10 (probably IPv6) on IPv4 socket'
if message.find(squelch) > 0: return
if message.find('07 = GET_NODES') > 0: return
@ -217,6 +214,8 @@ def toxygen_log_cb(_, level: int, source, line: int, func, message, userdata=Non
squelch='read_tcp_packet recv buffer has'
if message.find(squelch) > 0: return
return
elif source == 'Messenger.c':
if line in [2691, 2764]: return
LOG_LOG(f"{source}#{line}:{func} {message}")
except Exception as e:
LOG_WARN(f"toxygen_log_cb EXCEPTION {e}\n{traceback.format_exc()}")
@ -240,7 +239,9 @@ def tox_log_cb(_, level:int, source, line:int , func, message, userdata=None) ->
source = str(source, 'UTF-8')
if source == 'network.c':
if line in [944, 660]: return
if line in [944, 660, 781, 789]: return
# CORE: network.c#789:loglogdata [05 = <unknown> ] T=> 10= 81.169.136.229:33445 (0: OK) | 01000151a988e582...a5x
# CORE: network.c#781:loglogdata [dd = <unknown> ] T=> 128E 51.15.227.109:33445 (11: Resource temporarily unavailable) | d4f98b02ddf79693...76
# root WARNING 3network.c#944:b'send_packet'attempted to send message with network family 10 (probably IPv6) on IPv4 socket
if message.find('07 = GET_NODES') > 0: return
if source == 'TCP_common.c': return
@ -298,6 +299,14 @@ def vAddLoggerCallback(tox_options, callback=toxygen_log_cb) -> None:
tox_options.self_logger_cb)
LOG.debug("toxcore logging enabled")
def get_user_config_path():
system = sys.platform
if system == 'windows':
return os.path.join(os.getenv('APPDATA'), 'Tox/')
elif system == 'darwin':
return os.path.join(os.getenv('HOME'), 'Library/Application Support/Tox/')
else:
return os.path.join(os.getenv('HOME'), '.config/tox/')
def oMainArgparser(_=None, iMode=0):
# 'Mode: 0=chat 1=chat+audio 2=chat+audio+video default: 0'
@ -307,11 +316,10 @@ def oMainArgparser(_=None, iMode=0):
bIpV6 = 'True'
lIpV6Choices=[bIpV6, 'False']
sNodesJson = os.path.join(os.environ['HOME'], '.config', 'tox', 'DHTnodes.json')
sNodesJson = _get_nodes_path(None)
if not os.path.exists(sNodesJson): sNodesJson = ''
logfile = os.path.join(os.environ.get('TMPDIR', '/tmp'), 'toxygen.log')
if not os.path.exists(logfile): logfile = ''
parser = argparse.ArgumentParser(add_help=True)
parser.add_argument('--proxy_host', '--proxy-host', type=str,
@ -322,16 +330,16 @@ def oMainArgparser(_=None, iMode=0):
help='proxy port')
parser.add_argument('--proxy_type', '--proxy-type', default=0, type=int,
choices=[0,1,2],
help='proxy type 1=http, 2=socks')
help='proxy type 0=noproxy, 1=http, 2=socks')
parser.add_argument('--tcp_port', '--tcp-port', default=0, type=int,
help='tcp port')
help='tcp relay server port')
parser.add_argument('--udp_enabled', type=str, default='True',
choices=['True', 'False'],
help='En/Disable udp')
parser.add_argument('--ipv6_enabled', type=str, default=bIpV6,
choices=lIpV6Choices,
help=f"En/Disable ipv6 - default {bIpV6}")
parser.add_argument('--trace_enabled',type=str,
parser.add_argument('--trace_enabled', type=str,
default='False',
choices=['True','False'],
help='Debugging from toxcore logger_trace')
@ -363,6 +371,8 @@ def oMainArgparser(_=None, iMode=0):
# parser.add_argument('--save_history', type=str, default='True',
# choices=['True', 'False'],
# help='En/Disable saving history')
parser.add_argument('--socket_timeout',type=float, default=fSOCKET_TIMEOUT,
help='Socket timeout set during bootstrap')
return parser
def get_video_indexes() -> list:
@ -586,16 +596,14 @@ def lSdSamplerates(iDev:int) -> list:
supported_samplerates.append(fs)
return supported_samplerates
def _get_nodes_path(oArgs:str):
def _get_nodes_path(oArgs):
if oArgs and hasattr(oArgs, 'nodes_json') and \
oArgs.nodes_json and os.path.isfile(oArgs.nodes_json):
default = oArgs.nodes_json
elif get_user_config_path:
default = os.path.join(get_user_config_path(), 'toxygen_nodes.json')
else:
# Windwoes
default = os.path.join(os.getenv('HOME'), '.config', 'tox', 'toxygen_nodes.json')
LOG.debug("_get_nodes_path: " +default)
default = os.path.join(get_user_config_path(), 'toxygen_nodes.json')
# default = os.path.join(os.getenv('HOME'), '.config', 'tox', 'toxygen_nodes.json')
LOG.debug(f"_get_nodes_path: {default}")
return default
DEFAULT_NODES_COUNT = 8
@ -604,7 +612,7 @@ global aNODES
aNODES = {}
# @functools.lru_cache(maxsize=12) TypeError: unhashable type: 'Namespace'
def generate_nodes(oArgs=None,
def generate_nodes(oArgs,
nodes_count:int = DEFAULT_NODES_COUNT,
ipv:str = 'ipv4',
udp_not_tcp=True) -> dict:
@ -614,7 +622,7 @@ def generate_nodes(oArgs=None,
if sKey in aNODES and aNODES[sKey]:
return aNODES[sKey]
sFile = _get_nodes_path(oArgs)
assert os.path.exists(sFile), sFile
# assert os.path.isfile(sFile), sFile
lNodes = generate_nodes_from_file(sFile,
nodes_count=nodes_count,
ipv=ipv,
@ -639,9 +647,6 @@ I had a conversation with @irungentoo on IRC about whether we really need to cal
if key in aNODES_CACHE:
sorted_nodes = aNODES_CACHE[key]
else:
if not os.path.exists(sFile):
LOG.error("generate_nodes_from_file file not found " +sFile)
return []
try:
with open(sFile, 'rt') as fl:
json_nodes = json.loads(fl.read())['nodes']
@ -824,9 +829,9 @@ def sDNSLookup(host:str) -> str:
aHOSTS[host] = ip
return ip
def bootstrap_udp(lelts:list, lToxes:list, oArgs=None) -> None:
def bootstrap_udp(lelts:list, lToxes:list[int], oArgs=None, fsocket_timeout:float = fSOCKET_TIMEOUT) -> None:
lelts = lDNSClean(lelts)
socket.setdefaulttimeout(15.0)
socket.setdefaulttimeout(fsocket_timeout)
for oTox in lToxes:
random.shuffle(lelts)
if hasattr(oTox, 'oArgs'):
@ -868,7 +873,8 @@ def bootstrap_udp(lelts:list, lToxes:list, oArgs=None) -> None:
# LOG.debug(f'bootstrap_udp to {host} not connected')
pass
def bootstrap_tcp(lelts:list, lToxes:list, oArgs=None) -> None:
def bootstrap_tcp(lelts:list, lToxes:list, oArgs=None, fsocket_timeout:float = fSOCKET_TIMEOUT) -> None:
socket.setdefaulttimeout(fsocket_timeout)
lelts = lDNSClean(lelts)
for oTox in lToxes:
if hasattr(oTox, 'oArgs'): oArgs = oTox.oArgs

View File

@ -112,7 +112,9 @@ else:
ADDR_SIZE = 38 * 2
CLIENT_ID_SIZE = 32 * 2
THRESHOLD = 60 # >25
THRESHOLD = 120 # >25
fSOCKET_TIMEOUT = 15.0
iN = 6
global oTOX_OPTIONS
@ -220,7 +222,7 @@ def prepare(self):
self.bob.mycon_time = time.time()
try:
if status != TOX_CONNECTION['NONE']:
LOG_DEBUG(f"bobs_on_self_connection_status TRUE {status}" \
LOG_INFO(f"bobs_on_self_connection_status TRUE {status}" \
+f" last={int(self.bob.mycon_time)}" )
self.bob.mycon_status = True
else:
@ -232,7 +234,6 @@ def prepare(self):
else:
if self.bob.self_get_connection_status() != status:
LOG_WARN(f"bobs_on_self_connection_status DISAGREE {status}")
self.bob.dht_connected = status
def alices_on_self_connection_status(iTox, connection_state: int, *args) -> None:
#FixMe connection_num
@ -241,16 +242,15 @@ def prepare(self):
self.alice.mycon_time = time.time()
try:
if status != TOX_CONNECTION['NONE']:
LOG_DEBUG(f"alices_on_self_connection_status TRUE {status}" \
LOG_INFO(f"alices_on_self_connection_status TRUE {status}" \
+f" last={int(self.alice.mycon_time)}" )
self.alice.mycon_status = True
else:
LOG_WARN(f"alices_on_self_connection_status FALSE {status}" \
LOG_DEBUG(f"alices_on_self_connection_status FALSE {status}" \
+f" last={int(self.alice.mycon_time)}" )
self.alice.mycon_status = False
except Exception as e:
LOG_ERROR(f"alices_on_self_connection_status error={e}")
self.alice.dht_connected = status
opts = oTestsToxOptions(oTOX_OARGS)
global bUSE_NOREQUEST
@ -268,7 +268,7 @@ def prepare(self):
LOG.info(f"toxcore trace_enabled")
ts.vAddLoggerCallback(opts)
else:
LOG.debug(f"toxcore trace_enabled")
LOG.debug(f"toxcore trace_enabled=False")
bob = BobTox(opts, app=oAPP)
bob.oArgs = opts
@ -382,10 +382,10 @@ class ToxSuite(unittest.TestCase):
def run(self, result=None) -> None:
""" Stop after first error """
if not result.errors:
if result and not result.errors:
super(ToxSuite, self).run(result)
def get_connection_status(self) -> None:
def get_connection_status(self) -> bool:
if self.bob.mycon_time <= 1 or self.alice.mycon_time <= 1:
pass
# drop through
@ -412,7 +412,7 @@ class ToxSuite(unittest.TestCase):
self.bob.iterate()
sleep(interval / 1000.0)
def call_bootstrap(self, num: Union[int, None] = None, lToxes:list[int] =None, i:int =0) -> None:
def call_bootstrap(self, num: Union[int, None] = None, lToxes:Union[list[int], None] =None, i:int =0, fsocket_timeout:float = fSOCKET_TIMEOUT) -> None:
if num == None: num=ts.iNODES
if lToxes is None:
lToxes = [self.alice, self.bob]
@ -428,13 +428,13 @@ class ToxSuite(unittest.TestCase):
else:
lElts = self.lUdp[:num+i]
LOG.debug(f"call_bootstrap ts.bootstrap_udp {len(lElts)}")
ts.bootstrap_udp(lElts, lToxes)
ts.bootstrap_udp(lElts, lToxes, fsocket_timeout=fsocket_timeout)
random.shuffle(self.lTcp)
lElts = self.lTcp[:num+i]
LOG.debug(f"call_bootstrap ts.bootstrap_tcp {len(lElts)}")
ts.bootstrap_tcp(lElts, lToxes)
ts.bootstrap_tcp(lElts, lToxes, fsocket_timeout=fsocket_timeout)
def group_until_connected(self, otox, group_number:int, num: Union[int, None] = None, iMax:int = THRESHOLD) -> None:
def group_until_connected(self, otox, group_number:int, num: Union[int, None] = None, iMax:int = THRESHOLD, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
"""
"""
i = 0
@ -446,7 +446,7 @@ class ToxSuite(unittest.TestCase):
break
if i % 5 == 0:
j = i//5
self.call_bootstrap(num, lToxes=None, i=j)
self.call_bootstrap(num, lToxes=None, i=j, fsocket_timeout=fsocket_timeout)
s = ''
if i == 0: s = '\n'
LOG.info(s+"group_until_connected " \
@ -472,7 +472,7 @@ class ToxSuite(unittest.TestCase):
+f" last={int(otox.mycon_time)}" )
return False
def loop_until_connected(self, num: Union[int, None] = None) -> None:
def loop_until_connected(self, num: Union[int, None] = None, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
"""
t:on_self_connection_status
t:self_get_connection_status
@ -486,7 +486,7 @@ class ToxSuite(unittest.TestCase):
break
if i % 5 == 0:
j = i//5
self.call_bootstrap(num, lToxes=None, i=j)
self.call_bootstrap(num, lToxes=None, i=j, fsocket_timeout=fsocket_timeout)
s = ''
if i == 0: s = '\n'
LOG.info(s+"loop_until_connected " \
@ -528,7 +528,7 @@ class ToxSuite(unittest.TestCase):
+f" last={int(self.bob.mycon_time)}" )
return False
def wait_objs_attr(self, objs: list, attr: str) -> bool:
def wait_objs_attr(self, objs: list, attr: str, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
global THRESHOLD
i = 0
while i <= THRESHOLD:
@ -536,7 +536,7 @@ class ToxSuite(unittest.TestCase):
num = None
j = 0
j = i//5
self.call_bootstrap(num, objs, i=j)
self.call_bootstrap(num, lToxes=objs, i=j, fsocket_timeout=fsocket_timeout)
LOG.debug(f"wait_objs_attr {objs} for {attr} {i}")
if all([getattr(obj, attr) for obj in objs]):
return True
@ -548,7 +548,7 @@ class ToxSuite(unittest.TestCase):
return all([getattr(obj, attr) is not None for obj in objs])
def wait_otox_attrs(self, obj, attrs: list[str]) -> bool:
def wait_otox_attrs(self, obj, attrs: list[str], fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
assert all(attrs), f"wait_otox_attrs {attrs}"
i = 0
while i <= THRESHOLD:
@ -559,7 +559,7 @@ class ToxSuite(unittest.TestCase):
num = 4
j = i//5
if obj.self_get_connection_status() == TOX_CONNECTION['NONE']:
self.call_bootstrap(num, [obj], i=j)
self.call_bootstrap(num, lToxes=[obj], i=j, fsocket_timeout=fsocket_timeout)
LOG.debug(f"wait_otox_attrs {obj.name} for {attrs} {i}" \
+f" last={int(obj.mycon_time)}")
if all([getattr(obj, attr) is not None for attr in attrs]):
@ -571,13 +571,13 @@ class ToxSuite(unittest.TestCase):
return all([getattr(obj, attr) for attr in attrs])
def wait_ensure_exec(self, method, args:list) -> bool:
def wait_ensure_exec(self, method, args:list, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
i = 0
oRet = None
while i <= THRESHOLD:
if i % 5 == 0:
j = i//5
self.call_bootstrap(num=None, lToxes=None, i=j)
self.call_bootstrap(num=None, lToxes=None, i=j, fsocket_timeout=fsocket_timeout)
LOG.debug("wait_ensure_exec " \
+" " +str(method)
+" " +str(i))
@ -605,7 +605,6 @@ class ToxSuite(unittest.TestCase):
def bob_add_alice_as_friend_norequest(self) -> bool:
if not self.bBobNeedAlice(): return True
MSG = 'Hi, this is Bob.'
iRet = self.bob.friend_add_norequest(self.alice._address)
if iRet < 0:
return False
@ -674,7 +673,6 @@ class ToxSuite(unittest.TestCase):
message_data,
message_data_size,
*largs) -> None:
LOG_DEBUG(f"alices_on_friend_request: " +repr(message_data))
try:
assert str(message_data, 'UTF-8') == MSG
LOG_INFO(f"alices_on_friend_request: {sSlot} = True ")
@ -858,7 +856,7 @@ class ToxSuite(unittest.TestCase):
LOG.info(f"group pK={sPk} iGrp={iGrp} numg={otox.group_get_number_groups()}")
return iGrp
def otox_verify_group(self, otox, iGrp) -> int:
def otox_verify_group(self, otox, iGrp) -> None:
"""
group_self_get_name
group_self_get_peer_id
@ -1065,14 +1063,14 @@ class ToxSuite(unittest.TestCase):
else:
LOG.warning(f"bootstrap_local_netstat NOT {port} iStatus={iStatus}")
def test_bootstrap_local(self) -> None: # works
def test_bootstrap_local(self, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool: # works
"""
t:call_bootstrap
t:add_tcp_relay
t:self_get_dht_id
"""
# get port from /etc/tox-bootstrapd.conf 33445
self.call_bootstrap()
self.call_bootstrap(fsocket_timeout=fsocket_timeout)
# ts.bootstrap_local(self, self.lUdp)
i = 0
iStatus = -1
@ -1118,7 +1116,7 @@ class ToxSuite(unittest.TestCase):
lRetval = []
random.shuffle(lElts)
# assert
ts.bootstrap_iNmapInfo(lElts, oTOX_OARGS, bIS_LOCAL, iNODES=8)
ts.bootstrap_iNmapInfo(lElts, oTOX_OARGS, "tcp4", bIS_LOCAL=bIS_LOCAL, iNODES=8)
def test_self_get_secret_key(self) -> None: # works
"""
@ -1937,7 +1935,6 @@ class ToxSuite(unittest.TestCase):
else:
assert self.both_add_as_friend()
FRIEND_NUMBER = self.baid
FILE_NUMBER = 1
FILE = os.urandom(1024 * 1024)
FILE_NAME = b"/tmp/test.bin"
@ -2114,6 +2111,7 @@ class ToxSuite(unittest.TestCase):
"""
# Fatal Python error: Aborted
# "/var/local/src/toxygen_wrapper/wrapper/tox.py", line 180 in kill
global oTOX_OARGS
assert self.alice.get_savedata_size() > 0
data = self.alice.get_savedata()
@ -2190,7 +2188,7 @@ def oTestsToxOptions(oArgs):
tox_options.contents.proxy_type = int(oArgs.proxy_type)
tox_options.contents.proxy_host = bytes(oArgs.proxy_host, 'UTF-8')
tox_options.contents.proxy_port = int(oArgs.proxy_port)
tox_options.contents.udp_enabled = False
tox_options.contents.udp_enabled = oArgs.udp_enabled = False
else:
tox_options.contents.udp_enabled = oArgs.udp_enabled
if not os.path.exists('/proc/sys/net/ipv6'):
@ -2224,18 +2222,18 @@ def oTestsToxOptions(oArgs):
return tox_options
def oArgparse(lArgv):
global THRESHOLD
parser = ts.oMainArgparser()
parser.add_argument('--norequest',type=str, default='False',
choices=['True','False'],
help='Use _norequest')
help='Use _norequest during testing')
parser.add_argument('--test_timeout',type=int, default=THRESHOLD,
help='Test timeout during testing')
parser.add_argument('profile', type=str, nargs='?', default=None,
help='Path to Tox profile')
oArgs = parser.parse_args(lArgv)
for key in ts.lBOOLEANS:
if key not in oArgs: continue
val = getattr(oArgs, key)
setattr(oArgs, key, bool(val))
ts.clean_booleans(oArgs)
THRESHOLD = oArgs.test_timeout
if hasattr(oArgs, 'sleep'):
if oArgs.sleep == 'qt':
@ -2249,10 +2247,13 @@ def oArgparse(lArgv):
def main(lArgs=None) -> int:
global oTOX_OARGS
global bIS_LOCAL
global THRESHOLD
if lArgs is None: lArgs = sys.argv[1:]
oArgs = oArgparse(lArgs)
global bIS_LOCAL
bIS_LOCAL = oArgs.network in ['newlocal', 'localnew', 'local']
THRESHOLD = oArgs.test_timeout
oTOX_OARGS = oArgs
setattr(oTOX_OARGS, 'bIS_LOCAL', bIS_LOCAL)
bIS_LOCAL = True

View File

@ -1,8 +1,9 @@
#!/var/local/bin/python3.bash
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
# A work in progress - chat works.
""" echo.py features
# A work in progress - chat works, but I don't think AV does.
""" echo.py a basic Tox echo service. Features:
- accept friend request
- echo back friend message
# - accept and answer friend call request
@ -17,6 +18,7 @@ import threading
import random
from ctypes import *
import time
from typing import Union, Callable
# LOG=util.log
global LOG
@ -38,7 +40,7 @@ from tox_wrapper.toxcore_enums_and_consts import TOX_CONNECTION, TOX_USER_STATUS
import tox_wrapper.tests.support_testing as ts
from tox_wrapper.tests.support_testing import oMainArgparser
def sleep(fSec):
def sleep(fSec) -> None:
if 'QtCore' in globals():
if fSec > .000001: QtCore.QThread.msleep(fSec)
QtCore.QCoreApplication.processEvents()
@ -74,26 +76,30 @@ else:
super(AV, self).__init__(core)
self.core = self.get_tox()
def on_call(self, fid, audio_enabled, video_enabled) -> None:
def on_call(self, fid:int, audio_enabled:bool, video_enabled:bool) -> None:
LOG.info("Incoming %s call from %d:%s ..." % (
"video" if video_enabled else "audio", fid,
"video" if video_enabled else "audio",
fid,
self.core.friend_get_name(fid)))
bret = self.answer(fid, 48, 64)
LOG.info(f"Answered, in call... {bret}")
def on_call_state(self, fid, state) -> None:
def on_call_state(self, fid:int, state:int) -> None:
LOG.info('call state:fn=%d, state=%d' % (fid, state))
def on_audio_bit_rate(self, fid, audio_bit_rate) -> None:
def on_audio_bit_rate(self, fid:int, audio_bit_rate:int) -> None:
LOG.info('audio bit rate status: fn=%d, abr=%d' %
(fid, audio_bit_rate))
def on_video_bit_rate(self, fid, video_bit_rate) -> None:
def on_video_bit_rate(self, fid:int, video_bit_rate:int) -> None:
LOG.info('video bit rate status: fn=%d, vbr=%d' %
(fid, video_bit_rate))
def on_audio_receive_frame(self, fid, pcm, sample_count,
channels, sampling_rate) -> None:
def on_audio_receive_frame(self, fid:int,
pcm:int,
sample_count:int,
channels:int,
sampling_rate:int) -> None:
# LOG.info('audio frame: %d, %d, %d, %d' %
# (fid, sample_count, channels, sampling_rate))
# LOG.info('pcm len:%d, %s' % (len(pcm), str(type(pcm))))
@ -104,7 +110,7 @@ else:
if bret is False:
LOG.error('on_audio_receive_frame error.')
def on_video_receive_frame(self, fid, width, height, frame, u, v) -> None:
def on_video_receive_frame(self, fid:int, width:int, height:int, frame, u, v) -> None:
LOG.info('video frame: %d, %d, %d, ' % (fid, width, height))
sys.stdout.write('*')
sys.stdout.flush()
@ -116,12 +122,12 @@ else:
self.iterate()
def save_to_file(tox, fname):
def save_to_file(tox, fname) -> None:
data = tox.get_savedata()
with open(fname, 'wb') as f:
f.write(data)
def load_from_file(fname):
def load_from_file(fname:str):
assert os.path.exists(fname)
return open(fname, 'rb').read()
@ -261,20 +267,20 @@ class EchoBot():
LOG.info('Ending loop.')
def iterate(self, n=100) -> None:
def iterate(self, n:int = 100) -> None:
interval = self._tox.iteration_interval()
for i in range(n):
self._tox.iterate()
sleep(interval / 1000.0)
self._tox.iterate()
def on_friend_request(self, pk, message) -> None:
def on_friend_request(self, pk: Union[bytes,str], message: Union[bytes,str]) -> None:
LOG.debug('Friend request from %s: %s' % (pk, message))
self._tox.friend_add_norequest(pk)
LOG.info('on_friend_request Accepted.')
save_to_file(self._tox, sDATA_FILE)
def on_friend_message(self, friendId, message_type , message) -> None:
def on_friend_message(self, friendId:int , message_type, message: Union[bytes,str]) -> None:
name = self._tox.friend_get_name(friendId)
LOG.debug(f"{name}, {message}, {message_type}")
yMessage = bytes(message, 'UTF-8')
@ -350,7 +356,7 @@ class ToxIterateThread(BaseThread):
def oArgparse(lArgv):
parser = ts.oMainArgparser()
parser.add_argument('--norequest',type=str, default='False',
parser.add_argument('--norequest', type=str, default='False',
choices=['True','False'],
help='Use _norequest')
parser.add_argument('profile', type=str, nargs='?', default=None,