Compare commits
3 Commits
66a31110b3
...
5218cc1c7c
Author | SHA1 | Date | |
---|---|---|---|
5218cc1c7c | |||
946dea2d9e | |||
a8eee6fa4c |
33
README.md
33
README.md
@ -4,7 +4,8 @@
|
|||||||
wrapping of [Tox](https://tox.chat/)
|
wrapping of [Tox](https://tox.chat/)
|
||||||
[```libtoxcore```](https://github.com/TokTok/c-toxcore) into Python
|
[```libtoxcore```](https://github.com/TokTok/c-toxcore) into Python
|
||||||
using [ctypesgen](https://github.com/ctypesgen/ctypesgen)
|
using [ctypesgen](https://github.com/ctypesgen/ctypesgen)
|
||||||
The full c-toxcore library is covered.
|
The full c-toxcore library is covered, but it doesn't actually work yet -
|
||||||
|
dunno why.
|
||||||
|
|
||||||
The code is typed so that every call in ```tox*.py``` should have the
|
The code is typed so that every call in ```tox*.py``` should have the
|
||||||
right signature.
|
right signature.
|
||||||
@ -28,6 +29,10 @@ files. Link all 3 filenames to ```libtoxcore.so``` if you have only
|
|||||||
```c-toxcore``` with ```cmake``` rather than
|
```c-toxcore``` with ```cmake``` rather than
|
||||||
```autogen/configure```). The environment variable TOXCORE_LIBS overrides;
|
```autogen/configure```). The environment variable TOXCORE_LIBS overrides;
|
||||||
look in the file ```tox_wrapper/libtox.py``` for the details.
|
look in the file ```tox_wrapper/libtox.py``` for the details.
|
||||||
|
You can use pip to install the package from the source:
|
||||||
|
```
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
|
|
||||||
@ -42,9 +47,9 @@ def LOG_DEBUG(a): print('DBUG> '+a)
|
|||||||
def LOG_TRACE(a): pass # print('TRAC> '+a)
|
def LOG_TRACE(a): pass # print('TRAC> '+a)
|
||||||
```
|
```
|
||||||
to all ```pass #``` or use ```logging.logger``` to suite your tastes.
|
to all ```pass #``` or use ```logging.logger``` to suite your tastes.
|
||||||
```logging.logger``` can be dangerous in callbacks in ```Qt``` applications,
|
```logging.logger``` can be dangerous in callbacks in GUI applications
|
||||||
so we use simple print statements as default. The same applies to
|
if it's wired up to a console, so we use simple print statements as default.
|
||||||
```tox_wrapper/tests/tests_wrapper.py```.
|
The same applies to ```tox_wrapper/tests/tests_wrapper.py```.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@ -66,6 +71,12 @@ module can be helpful in debugging crashes
|
|||||||
|
|
||||||
Others include:
|
Others include:
|
||||||
|
|
||||||
|
* <https://git.plastiras.org/emdee/toxygen_wrapper> Ctypes bindings
|
||||||
|
originally from <https://github.com/toxygen-project/toxygen>
|
||||||
|
```next_gen``` branch by Ingvar. Those bindings work, unlike these.
|
||||||
|
Because it's ctypes you can follow things in a Python debugger,
|
||||||
|
or with the utterly stupendous Python feature of ```gdb```.
|
||||||
|
|
||||||
* <https://github.com/TokTok/py-toxcore-c> Cython bindings.
|
* <https://github.com/TokTok/py-toxcore-c> Cython bindings.
|
||||||
Incomplete and not really actively supported. Maybe it will get
|
Incomplete and not really actively supported. Maybe it will get
|
||||||
worked on in the future, but TokTok seems to be working on
|
worked on in the future, but TokTok seems to be working on
|
||||||
@ -84,10 +95,22 @@ debugger is a crucial advantage.
|
|||||||
|
|
||||||
## Updates
|
## Updates
|
||||||
|
|
||||||
|
To regerate the bindings to a new c-toxcore, install ctypesgen
|
||||||
|
and exit the Makefile to set CTOXCORE to where your c-toxcore is. Then
|
||||||
|
```
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
Then try patching the resulting file with:
|
||||||
|
```
|
||||||
|
patch -b -z .dst src/tox_wrapper/tox_ctypesgen.py \
|
||||||
|
< src/tox_wrapper/tox_ctypesgen.py.diff
|
||||||
|
```
|
||||||
|
You may need to resolve any rejections if the ctypesgen file has changed.
|
||||||
|
|
||||||
Although Tox works over Tor, we do not recommend its usage for
|
Although Tox works over Tor, we do not recommend its usage for
|
||||||
anonymity as it leaks DNS requests due to a 6-year old known security
|
anonymity as it leaks DNS requests due to a 6-year old known security
|
||||||
issue: https://github.com/TokTok/c-toxcore/issues/469 unless your Tox client
|
issue: https://github.com/TokTok/c-toxcore/issues/469 unless your Tox client
|
||||||
does hostname lookups before calling Tox (like toxygen does). Otherwise,
|
does hostname lookups before calling Tox (like [toxygen](https://git.plastiras.org/emdee/tox_wrapper) does). Otherwise,
|
||||||
do not use it for anonymous communication unless you have a firewall in place.
|
do not use it for anonymous communication unless you have a firewall in place.
|
||||||
|
|
||||||
The Tox project does not follow semantic versioning of its main structures
|
The Tox project does not follow semantic versioning of its main structures
|
||||||
|
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
0
src/tox_wrapper/__init__.py
Normal file
0
src/tox_wrapper/__init__.py
Normal file
@ -21,7 +21,7 @@ from stem.control import Controller
|
|||||||
from stem.util.tor_tools import is_valid_fingerprint
|
from stem.util.tor_tools import is_valid_fingerprint
|
||||||
|
|
||||||
global LOG
|
global LOG
|
||||||
from toxygen_wrapper.tests.support_http import bAreWeConnected
|
from tox_wrapper.tests.support_http import bAreWeConnected
|
||||||
|
|
||||||
warnings.filterwarnings('ignore')
|
warnings.filterwarnings('ignore')
|
||||||
LOG = logging.getLogger('TestS')
|
LOG = logging.getLogger('TestS')
|
||||||
|
@ -38,11 +38,11 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
nmap = False
|
nmap = False
|
||||||
|
|
||||||
import toxygen_wrapper
|
import tox_wrapper
|
||||||
import toxygen_wrapper.toxcore_enums_and_consts as enums
|
import tox_wrapper.toxcore_enums_and_consts as enums
|
||||||
|
|
||||||
from toxygen_wrapper.tests.support_http import bAreWeConnected
|
from tox_wrapper.tests.support_http import bAreWeConnected
|
||||||
from toxygen_wrapper.tests.support_onions import (is_valid_fingerprint,
|
from tox_wrapper.tests.support_onions import (is_valid_fingerprint,
|
||||||
lIntroductionPoints,
|
lIntroductionPoints,
|
||||||
oGetStemController,
|
oGetStemController,
|
||||||
sMapaddressResolv, sTorResolve)
|
sMapaddressResolv, sTorResolve)
|
||||||
@ -287,7 +287,7 @@ def tox_log_cb(_, level:int, source, line:int , func, message, userdata=None) ->
|
|||||||
|
|
||||||
def vAddLoggerCallback(tox_options, callback=toxygen_log_cb) -> None:
|
def vAddLoggerCallback(tox_options, callback=toxygen_log_cb) -> None:
|
||||||
if callback is None:
|
if callback is None:
|
||||||
toxygen_wrapper.tox.Tox.libtoxcore.tox_options_set_log_callback(
|
tox_wrapper.tox.Tox.libtoxcore.tox_options_set_log_callback(
|
||||||
tox_options._options_pointer,
|
tox_options._options_pointer,
|
||||||
POINTER(None)())
|
POINTER(None)())
|
||||||
tox_options.self_logger_cb = None
|
tox_options.self_logger_cb = None
|
||||||
@ -296,7 +296,7 @@ def vAddLoggerCallback(tox_options, callback=toxygen_log_cb) -> None:
|
|||||||
|
|
||||||
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(callback)
|
tox_options.self_logger_cb = c_callback(callback)
|
||||||
toxygen_wrapper.tox.Tox.libtoxcore.tox_options_set_log_callback(
|
tox_wrapper.tox.Tox.libtoxcore.tox_options_set_log_callback(
|
||||||
tox_options._options_pointer,
|
tox_options._options_pointer,
|
||||||
tox_options.self_logger_cb)
|
tox_options.self_logger_cb)
|
||||||
LOG.debug("toxcore logging enabled")
|
LOG.debug("toxcore logging enabled")
|
||||||
@ -409,7 +409,7 @@ def get_audio():
|
|||||||
|
|
||||||
def oToxygenToxOptions(oArgs, logger_cb=None):
|
def oToxygenToxOptions(oArgs, logger_cb=None):
|
||||||
data = None
|
data = None
|
||||||
tox_options = toxygen_wrapper.tox.Tox.options_new()
|
tox_options = tox_wrapper.tox.Tox.options_new()
|
||||||
if oArgs.proxy_type:
|
if oArgs.proxy_type:
|
||||||
tox_options.contents.proxy_type = int(oArgs.proxy_type)
|
tox_options.contents.proxy_type = int(oArgs.proxy_type)
|
||||||
tox_options.contents.proxy_host = bytes(oArgs.proxy_host, 'UTF-8')
|
tox_options.contents.proxy_host = bytes(oArgs.proxy_host, 'UTF-8')
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
"""Originaly from https://github.com/oxij/PyTox c-toxcore-02 branch
|
"""Originaly from https://github.com/oxij/PyTox c-toxcore-02 branch
|
||||||
which itself was forked from https://github.com/aitjcize/PyTox/
|
which itself was forked from https://github.com/aitjcize/PyTox/
|
||||||
Modified to work with toxygen_wrapper
|
Modified to work with tox_wrapper
|
||||||
Unlike almost all of the c-toxcore ctests, these are real tests that
|
Unlike almost all of the c-toxcore ctests, these are real tests that
|
||||||
take place over and Internet connection.
|
take place over and Internet connection.
|
||||||
|
|
||||||
|
@ -10,10 +10,10 @@ import threading
|
|||||||
from ctypes import *
|
from ctypes import *
|
||||||
from typing import Union, Callable
|
from typing import Union, Callable
|
||||||
|
|
||||||
import toxygen_wrapper.toxcore_enums_and_consts as enums
|
import tox_wrapper.toxcore_enums_and_consts as enums
|
||||||
from toxygen_wrapper.tox import Tox, UINT32_MAX, ToxError
|
from tox_wrapper.tox import Tox, UINT32_MAX, ToxError
|
||||||
|
|
||||||
from toxygen_wrapper.toxcore_enums_and_consts import (TOX_ADDRESS_SIZE, TOX_CONNECTION,
|
from tox_wrapper.toxcore_enums_and_consts import (TOX_ADDRESS_SIZE, TOX_CONNECTION,
|
||||||
TOX_FILE_CONTROL,
|
TOX_FILE_CONTROL,
|
||||||
TOX_MESSAGE_TYPE,
|
TOX_MESSAGE_TYPE,
|
||||||
TOX_SECRET_KEY_SIZE,
|
TOX_SECRET_KEY_SIZE,
|
||||||
@ -22,7 +22,7 @@ from toxygen_wrapper.toxcore_enums_and_consts import (TOX_ADDRESS_SIZE, TOX_CONN
|
|||||||
try:
|
try:
|
||||||
import support_testing as ts
|
import support_testing as ts
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import toxygen_wrapper.tests.support_testing as ts
|
import tox_wrapper.tests.support_testing as ts
|
||||||
sleep = time.sleep
|
sleep = time.sleep
|
||||||
|
|
||||||
ADDR_SIZE = 38 * 2
|
ADDR_SIZE = 38 * 2
|
||||||
|
@ -14,8 +14,8 @@ import ctypes
|
|||||||
import sys
|
import sys
|
||||||
from ctypes import * # noqa: F401, F403
|
from ctypes import * # noqa: F401, F403
|
||||||
|
|
||||||
# callbacks can be called in any thread so were being careful
|
# callbacks can be called in any thread so we are being careful
|
||||||
# tox.py can be called by callbacks
|
# NOT to use logging. tox.py can also be called by callbacks.
|
||||||
def LOG_ERROR(a) -> None:
|
def LOG_ERROR(a) -> None:
|
||||||
print('EROR> '+a)
|
print('EROR> '+a)
|
||||||
def LOG_WARN(a) -> None:
|
def LOG_WARN(a) -> None:
|
||||||
|
3584
src/tox_wrapper/tox_ctypesgen.py.diff
Normal file
3584
src/tox_wrapper/tox_ctypesgen.py.diff
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,12 +5,9 @@ from ctypes import (CFUNCTYPE, POINTER, ArgumentError, byref, c_bool, c_char_p,
|
|||||||
c_void_p, cast)
|
c_void_p, cast)
|
||||||
from typing import Union, Callable
|
from typing import Union, Callable
|
||||||
|
|
||||||
try:
|
from tox_wrapper.libtox_ctypesgen import LibToxAV
|
||||||
from toxygen_wrapper.libtox import LibToxAV
|
import tox_wrapper.toxav_enums as enum
|
||||||
import toxygen_wrapper.toxav_enums as enum
|
|
||||||
except:
|
|
||||||
from libtox import LibToxAV
|
|
||||||
import toxav_enums as enum
|
|
||||||
class ToxError(ArgumentError): pass
|
class ToxError(ArgumentError): pass
|
||||||
|
|
||||||
def LOG_ERROR(a: str) -> None: print('EROR> '+a)
|
def LOG_ERROR(a: str) -> None: print('EROR> '+a)
|
||||||
|
133
src/tox_wrapper/toxav_enums.py
Normal file
133
src/tox_wrapper/toxav_enums.py
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
|
||||||
|
|
||||||
|
TOXAV_ERR_NEW = {
|
||||||
|
# The function returned successfully.
|
||||||
|
'OK': 0,
|
||||||
|
# One of the arguments to the function was NULL when it was not expected.
|
||||||
|
'NULL': 1,
|
||||||
|
# Memory allocation failure while trying to allocate structures required for the A/V session.
|
||||||
|
'MALLOC': 2,
|
||||||
|
# Attempted to create a second session for the same Tox instance.
|
||||||
|
'MULTIPLE': 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
TOXAV_ERR_CALL = {
|
||||||
|
# The function returned successfully.
|
||||||
|
'OK': 0,
|
||||||
|
# A resource allocation error occurred while trying to create the structures required for the call.
|
||||||
|
'MALLOC': 1,
|
||||||
|
# Synchronization error occurred.
|
||||||
|
'SYNC': 2,
|
||||||
|
# The friend number did not designate a valid friend.
|
||||||
|
'FRIEND_NOT_FOUND': 3,
|
||||||
|
# The friend was valid, but not currently connected.
|
||||||
|
'FRIEND_NOT_CONNECTED': 4,
|
||||||
|
# Attempted to call a friend while already in an audio or video call with them.
|
||||||
|
'FRIEND_ALREADY_IN_CALL': 5,
|
||||||
|
# Audio or video bit rate is invalid.
|
||||||
|
'INVALID_BIT_RATE': 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
TOXAV_ERR_ANSWER = {
|
||||||
|
# The function returned successfully.
|
||||||
|
'OK': 0,
|
||||||
|
# Synchronization error occurred.
|
||||||
|
'SYNC': 1,
|
||||||
|
# Failed to initialize codecs for call session. Note that codec initiation will fail if there is no receive callback
|
||||||
|
# registered for either audio or video.
|
||||||
|
'CODEC_INITIALIZATION': 2,
|
||||||
|
# The friend number did not designate a valid friend.
|
||||||
|
'FRIEND_NOT_FOUND': 3,
|
||||||
|
# The friend was valid, but they are not currently trying to initiate a call. This is also returned if this client
|
||||||
|
# is already in a call with the friend.
|
||||||
|
'FRIEND_NOT_CALLING': 4,
|
||||||
|
# Audio or video bit rate is invalid.
|
||||||
|
'INVALID_BIT_RATE': 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
TOXAV_FRIEND_CALL_STATE = {
|
||||||
|
# Set by the AV core if an error occurred on the remote end or if friend timed out. This is the final state after
|
||||||
|
# which no more state transitions can occur for the call. This call state will never be triggered in combination
|
||||||
|
# with other call states.
|
||||||
|
'ERROR': 1,
|
||||||
|
# The call has finished. This is the final state after which no more state transitions can occur for the call. This
|
||||||
|
# call state will never be triggered in combination with other call states.
|
||||||
|
'FINISHED': 2,
|
||||||
|
# The flag that marks that friend is sending audio.
|
||||||
|
'SENDING_A': 4,
|
||||||
|
# The flag that marks that friend is sending video.
|
||||||
|
'SENDING_V': 8,
|
||||||
|
# The flag that marks that friend is receiving audio.
|
||||||
|
'ACCEPTING_A': 16,
|
||||||
|
# The flag that marks that friend is receiving video.
|
||||||
|
'ACCEPTING_V': 32,
|
||||||
|
}
|
||||||
|
|
||||||
|
TOXAV_CALL_CONTROL = {
|
||||||
|
# Resume a previously paused call. Only valid if the pause was caused by this client, if not, this control is
|
||||||
|
# ignored. Not valid before the call is accepted.
|
||||||
|
'RESUME': 0,
|
||||||
|
# Put a call on hold. Not valid before the call is accepted.
|
||||||
|
'PAUSE': 1,
|
||||||
|
# Reject a call if it was not answered, yet. Cancel a call after it was answered.
|
||||||
|
'CANCEL': 2,
|
||||||
|
# Request that the friend stops sending audio. Regardless of the friend's compliance, this will cause the
|
||||||
|
# audio_receive_frame event to stop being triggered on receiving an audio frame from the friend.
|
||||||
|
'MUTE_AUDIO': 3,
|
||||||
|
# Calling this control will notify client to start sending audio again.
|
||||||
|
'UNMUTE_AUDIO': 4,
|
||||||
|
# Request that the friend stops sending video. Regardless of the friend's compliance, this will cause the
|
||||||
|
# video_receive_frame event to stop being triggered on receiving a video frame from the friend.
|
||||||
|
'HIDE_VIDEO': 5,
|
||||||
|
# Calling this control will notify client to start sending video again.
|
||||||
|
'SHOW_VIDEO': 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
TOXAV_ERR_CALL_CONTROL = {
|
||||||
|
# The function returned successfully.
|
||||||
|
'OK': 0,
|
||||||
|
# Synchronization error occurred.
|
||||||
|
'SYNC': 1,
|
||||||
|
# The friend_number passed did not designate a valid friend.
|
||||||
|
'FRIEND_NOT_FOUND': 2,
|
||||||
|
# This client is currently not in a call with the friend. Before the call is answered, only CANCEL is a valid
|
||||||
|
# control.
|
||||||
|
'FRIEND_NOT_IN_CALL': 3,
|
||||||
|
# Happens if user tried to pause an already paused call or if trying to resume a call that is not paused.
|
||||||
|
'INVALID_TRANSITION': 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
TOXAV_ERR_BIT_RATE_SET = {
|
||||||
|
# The function returned successfully.
|
||||||
|
'OK': 0,
|
||||||
|
# Synchronization error occurred.
|
||||||
|
'SYNC': 1,
|
||||||
|
# The audio bit rate passed was not one of the supported values.
|
||||||
|
'INVALID_AUDIO_BIT_RATE': 2,
|
||||||
|
# The video bit rate passed was not one of the supported values.
|
||||||
|
'INVALID_VIDEO_BIT_RATE': 3,
|
||||||
|
# The friend_number passed did not designate a valid friend.
|
||||||
|
'FRIEND_NOT_FOUND': 4,
|
||||||
|
# This client is currently not in a call with the friend.
|
||||||
|
'FRIEND_NOT_IN_CALL': 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
TOXAV_ERR_SEND_FRAME = {
|
||||||
|
# The function returned successfully.
|
||||||
|
'OK': 0,
|
||||||
|
# In case of video, one of Y, U, or V was NULL. In case of audio, the samples data pointer was NULL.
|
||||||
|
'NULL': 1,
|
||||||
|
# The friend_number passed did not designate a valid friend.
|
||||||
|
'FRIEND_NOT_FOUND': 2,
|
||||||
|
# This client is currently not in a call with the friend.
|
||||||
|
'FRIEND_NOT_IN_CALL': 3,
|
||||||
|
# Synchronization error occurred.
|
||||||
|
'SYNC': 4,
|
||||||
|
# One of the frame parameters was invalid. E.g. the resolution may be too small or too large, or the audio sampling
|
||||||
|
# rate may be unsupported.
|
||||||
|
'INVALID': 5,
|
||||||
|
# Either friend turned off audio or video receiving or we turned off sending for the said payload.
|
||||||
|
'PAYLOAD_TYPE_DISABLED': 6,
|
||||||
|
# Failed to push frame through rtp interface.
|
||||||
|
'RTP_FAILED': 7,
|
||||||
|
}
|
29
src/tox_wrapper/toxencryptsave_enums_and_consts.py
Normal file
29
src/tox_wrapper/toxencryptsave_enums_and_consts.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
TOX_ERR_ENCRYPTION = {
|
||||||
|
# The function returned successfully.
|
||||||
|
'OK': 0,
|
||||||
|
# Some input data, or maybe the output pointer, was null.
|
||||||
|
'NULL': 1,
|
||||||
|
# The crypto lib was unable to derive a key from the given passphrase, which is usually a lack of memory issue. The
|
||||||
|
# functions accepting keys do not produce this error.
|
||||||
|
'KEY_DERIVATION_FAILED': 2,
|
||||||
|
# The encryption itself failed.
|
||||||
|
'FAILED': 3
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_DECRYPTION = {
|
||||||
|
# The function returned successfully.
|
||||||
|
'OK': 0,
|
||||||
|
# Some input data, or maybe the output pointer, was null.
|
||||||
|
'NULL': 1,
|
||||||
|
# The input data was shorter than TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes
|
||||||
|
'INVALID_LENGTH': 2,
|
||||||
|
# The input data is missing the magic number (i.e. wasn't created by this module, or is corrupted)
|
||||||
|
'BAD_FORMAT': 3,
|
||||||
|
# The crypto lib was unable to derive a key from the given passphrase, which is usually a lack of memory issue. The
|
||||||
|
# functions accepting keys do not produce this error.
|
||||||
|
'KEY_DERIVATION_FAILED': 4,
|
||||||
|
# The encrypted byte array could not be decrypted. Either the data was corrupt or the password/key was incorrect.
|
||||||
|
'FAILED': 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_PASS_ENCRYPTION_EXTRA_LENGTH = 80
|
Loading…
Reference in New Issue
Block a user