xtlsapi-ipblacklist 3.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tests/__init__.py +0 -0
- tests/conftest.py +14 -0
- tests/test_base.py +5 -0
- tests/test_block_ips.py +9 -0
- tests/test_stats_online_ip_list.py +14 -0
- xtlsapi/VERSION +1 -0
- xtlsapi/__init__.py +4 -0
- xtlsapi/__main__.py +6 -0
- xtlsapi/__pycache__/__init__.cpython-313.pyc +0 -0
- xtlsapi/api_services/__init__.py +8 -0
- xtlsapi/api_services/_base.py +12 -0
- xtlsapi/api_services/handler/__init__.py +6 -0
- xtlsapi/api_services/handler/add_client.py +66 -0
- xtlsapi/api_services/handler/remove_client.py +27 -0
- xtlsapi/api_services/logger/__init__.py +5 -0
- xtlsapi/api_services/logger/restart_logger.py +17 -0
- xtlsapi/api_services/router/__init__.py +7 -0
- xtlsapi/api_services/router/block_ips.py +60 -0
- xtlsapi/api_services/stats/__init__.py +22 -0
- xtlsapi/api_services/stats/get_client_download_traffic.py +17 -0
- xtlsapi/api_services/stats/get_client_upload_traffic.py +15 -0
- xtlsapi/api_services/stats/get_inbound_download_traffic.py +16 -0
- xtlsapi/api_services/stats/get_inbound_upload_traffic.py +16 -0
- xtlsapi/api_services/stats/get_stats_online_ip_list.py +28 -0
- xtlsapi/api_services/stats/get_statsonline.py +18 -0
- xtlsapi/api_services/stats/get_statsquery.py +17 -0
- xtlsapi/api_services/stats/get_total_download_traffic.py +17 -0
- xtlsapi/api_services/stats/get_total_upload_traffic.py +16 -0
- xtlsapi/base.py +17 -0
- xtlsapi/cli.py +28 -0
- xtlsapi/client/SingboxClient.py +11 -0
- xtlsapi/client/XrayClient.py +11 -0
- xtlsapi/client/__init__.py +1 -0
- xtlsapi/client/__pycache__/XrayClient.cpython-313.pyc +0 -0
- xtlsapi/client/__pycache__/__init__.cpython-313.pyc +0 -0
- xtlsapi/exceptions/__init__.py +4 -0
- xtlsapi/exceptions/_base.py +3 -0
- xtlsapi/exceptions/email_already_exists.py +7 -0
- xtlsapi/exceptions/email_not_found.py +7 -0
- xtlsapi/exceptions/inbound_not_found.py +7 -0
- xtlsapi/ext/__init__.py +0 -0
- xtlsapi/ext/utils.py +49 -0
- xtlsapi/generate_from_xray_proto.py +81 -0
- xtlsapi/singbox_api/__init__.py +0 -0
- xtlsapi/singbox_api/build.sh +6 -0
- xtlsapi/singbox_api/extensions.proto +39 -0
- xtlsapi/singbox_api/extensions_pb2.py +31 -0
- xtlsapi/singbox_api/extensions_pb2_grpc.py +4 -0
- xtlsapi/singbox_api/stats.proto +63 -0
- xtlsapi/singbox_api/stats_old.proto +53 -0
- xtlsapi/singbox_api/stats_pb2.py +45 -0
- xtlsapi/singbox_api/stats_pb2_grpc.py +132 -0
- xtlsapi/singbox_api_services/__init__.py +6 -0
- xtlsapi/singbox_api_services/_base.py +7 -0
- xtlsapi/singbox_api_services/stats/__init__.py +18 -0
- xtlsapi/singbox_api_services/stats/get_client_download_traffic.py +17 -0
- xtlsapi/singbox_api_services/stats/get_client_upload_traffic.py +15 -0
- xtlsapi/singbox_api_services/stats/get_inbound_download_traffic.py +16 -0
- xtlsapi/singbox_api_services/stats/get_inbound_upload_traffic.py +16 -0
- xtlsapi/singbox_api_services/stats/get_statsquery.py +17 -0
- xtlsapi/singbox_api_services/stats/get_total_download_traffic.py +17 -0
- xtlsapi/singbox_api_services/stats/get_total_upload_traffic.py +16 -0
- xtlsapi/xray_api/__init__.py +0 -0
- xtlsapi/xray_api/a.sh +4 -0
- xtlsapi/xray_api/app/__init__.py +0 -0
- xtlsapi/xray_api/app/commander/__init__.py +0 -0
- xtlsapi/xray_api/app/commander/config_pb2.py +40 -0
- xtlsapi/xray_api/app/commander/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/dispatcher/__init__.py +0 -0
- xtlsapi/xray_api/app/dispatcher/config_pb2.py +39 -0
- xtlsapi/xray_api/app/dispatcher/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/dns/__init__.py +0 -0
- xtlsapi/xray_api/app/dns/config_pb2.py +51 -0
- xtlsapi/xray_api/app/dns/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/dns/fakedns/__init__.py +0 -0
- xtlsapi/xray_api/app/dns/fakedns/fakedns_pb2.py +39 -0
- xtlsapi/xray_api/app/dns/fakedns/fakedns_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/log/__init__.py +0 -0
- xtlsapi/xray_api/app/log/command/__init__.py +0 -0
- xtlsapi/xray_api/app/log/command/config_pb2.py +43 -0
- xtlsapi/xray_api/app/log/command/config_pb2_grpc.py +97 -0
- xtlsapi/xray_api/app/log/config_pb2.py +40 -0
- xtlsapi/xray_api/app/log/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/metrics/__init__.py +0 -0
- xtlsapi/xray_api/app/metrics/config_pb2.py +37 -0
- xtlsapi/xray_api/app/metrics/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/observatory/__init__.py +0 -0
- xtlsapi/xray_api/app/observatory/burst/config_pb2.py +39 -0
- xtlsapi/xray_api/app/observatory/burst/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/observatory/command/__init__.py +0 -0
- xtlsapi/xray_api/app/observatory/command/command_pb2.py +44 -0
- xtlsapi/xray_api/app/observatory/command/command_pb2_grpc.py +97 -0
- xtlsapi/xray_api/app/observatory/config_pb2.py +47 -0
- xtlsapi/xray_api/app/observatory/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/policy/__init__.py +0 -0
- xtlsapi/xray_api/app/policy/config_pb2.py +55 -0
- xtlsapi/xray_api/app/policy/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/proxyman/__init__.py +0 -0
- xtlsapi/xray_api/app/proxyman/command/__init__.py +0 -0
- xtlsapi/xray_api/app/proxyman/command/command_pb2.py +76 -0
- xtlsapi/xray_api/app/proxyman/command/command_pb2_grpc.py +398 -0
- xtlsapi/xray_api/app/proxyman/config_pb2.py +61 -0
- xtlsapi/xray_api/app/proxyman/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/reverse/__init__.py +0 -0
- xtlsapi/xray_api/app/reverse/config_pb2.py +45 -0
- xtlsapi/xray_api/app/reverse/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/router/__init__.py +0 -0
- xtlsapi/xray_api/app/router/command/__init__.py +0 -0
- xtlsapi/xray_api/app/router/command/command_pb2.py +73 -0
- xtlsapi/xray_api/app/router/command/command_pb2_grpc.py +312 -0
- xtlsapi/xray_api/app/router/config_pb2.py +70 -0
- xtlsapi/xray_api/app/router/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/app/stats/__init__.py +0 -0
- xtlsapi/xray_api/app/stats/command/__init__.py +0 -0
- xtlsapi/xray_api/app/stats/command/command.proto +62 -0
- xtlsapi/xray_api/app/stats/command/command_pb2.py +59 -0
- xtlsapi/xray_api/app/stats/command/command_pb2_grpc.py +269 -0
- xtlsapi/xray_api/app/stats/config_pb2.py +39 -0
- xtlsapi/xray_api/app/stats/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/common/__init__.py +0 -0
- xtlsapi/xray_api/common/log/__init__.py +0 -0
- xtlsapi/xray_api/common/log/log_pb2.py +37 -0
- xtlsapi/xray_api/common/log/log_pb2_grpc.py +24 -0
- xtlsapi/xray_api/common/net/__init__.py +0 -0
- xtlsapi/xray_api/common/net/address_pb2.py +37 -0
- xtlsapi/xray_api/common/net/address_pb2_grpc.py +24 -0
- xtlsapi/xray_api/common/net/destination_pb2.py +39 -0
- xtlsapi/xray_api/common/net/destination_pb2_grpc.py +24 -0
- xtlsapi/xray_api/common/net/network_pb2.py +39 -0
- xtlsapi/xray_api/common/net/network_pb2_grpc.py +24 -0
- xtlsapi/xray_api/common/net/port_pb2.py +39 -0
- xtlsapi/xray_api/common/net/port_pb2_grpc.py +24 -0
- xtlsapi/xray_api/common/protocol/__init__.py +0 -0
- xtlsapi/xray_api/common/protocol/headers_pb2.py +39 -0
- xtlsapi/xray_api/common/protocol/headers_pb2_grpc.py +24 -0
- xtlsapi/xray_api/common/protocol/server_spec_pb2.py +39 -0
- xtlsapi/xray_api/common/protocol/server_spec_pb2_grpc.py +24 -0
- xtlsapi/xray_api/common/protocol/user_pb2.py +38 -0
- xtlsapi/xray_api/common/protocol/user_pb2_grpc.py +24 -0
- xtlsapi/xray_api/common/serial/__init__.py +0 -0
- xtlsapi/xray_api/common/serial/typed_message_pb2.py +37 -0
- xtlsapi/xray_api/common/serial/typed_message_pb2_grpc.py +24 -0
- xtlsapi/xray_api/core/__init__.py +0 -0
- xtlsapi/xray_api/core/config_pb2.py +42 -0
- xtlsapi/xray_api/core/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/__init__.py +0 -0
- xtlsapi/xray_api/proxy/blackhole/__init__.py +0 -0
- xtlsapi/xray_api/proxy/blackhole/config_pb2.py +42 -0
- xtlsapi/xray_api/proxy/blackhole/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/dns/__init__.py +0 -0
- xtlsapi/xray_api/proxy/dns/config_pb2.py +38 -0
- xtlsapi/xray_api/proxy/dns/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/dokodemo/__init__.py +0 -0
- xtlsapi/xray_api/proxy/dokodemo/config_pb2.py +39 -0
- xtlsapi/xray_api/proxy/dokodemo/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/freedom/__init__.py +0 -0
- xtlsapi/xray_api/proxy/freedom/config_pb2.py +46 -0
- xtlsapi/xray_api/proxy/freedom/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/http/__init__.py +0 -0
- xtlsapi/xray_api/proxy/http/config_pb2.py +48 -0
- xtlsapi/xray_api/proxy/http/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/loopback/__init__.py +0 -0
- xtlsapi/xray_api/proxy/loopback/config_pb2.py +37 -0
- xtlsapi/xray_api/proxy/loopback/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/mtproto/__init__.py +0 -0
- xtlsapi/xray_api/proxy/mtproto/config_pb2.py +32 -0
- xtlsapi/xray_api/proxy/mtproto/config_pb2_grpc.py +4 -0
- xtlsapi/xray_api/proxy/shadowsocks/__init__.py +0 -0
- xtlsapi/xray_api/proxy/shadowsocks/config_pb2.py +46 -0
- xtlsapi/xray_api/proxy/shadowsocks/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/shadowsocks_2022/__init__.py +0 -0
- xtlsapi/xray_api/proxy/shadowsocks_2022/config_pb2.py +50 -0
- xtlsapi/xray_api/proxy/shadowsocks_2022/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/socks/__init__.py +0 -0
- xtlsapi/xray_api/proxy/socks/config_pb2.py +49 -0
- xtlsapi/xray_api/proxy/socks/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/trojan/__init__.py +0 -0
- xtlsapi/xray_api/proxy/trojan/config_pb2.py +45 -0
- xtlsapi/xray_api/proxy/trojan/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/vless/__init__.py +0 -0
- xtlsapi/xray_api/proxy/vless/account_pb2.py +37 -0
- xtlsapi/xray_api/proxy/vless/account_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/vless/encoding/__init__.py +0 -0
- xtlsapi/xray_api/proxy/vless/encoding/addons_pb2.py +37 -0
- xtlsapi/xray_api/proxy/vless/encoding/addons_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/vless/inbound/__init__.py +0 -0
- xtlsapi/xray_api/proxy/vless/inbound/config_pb2.py +40 -0
- xtlsapi/xray_api/proxy/vless/inbound/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/vless/outbound/__init__.py +0 -0
- xtlsapi/xray_api/proxy/vless/outbound/config_pb2.py +38 -0
- xtlsapi/xray_api/proxy/vless/outbound/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/vmess/__init__.py +0 -0
- xtlsapi/xray_api/proxy/vmess/account_pb2.py +38 -0
- xtlsapi/xray_api/proxy/vmess/account_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/vmess/inbound/__init__.py +0 -0
- xtlsapi/xray_api/proxy/vmess/inbound/config_pb2.py +42 -0
- xtlsapi/xray_api/proxy/vmess/inbound/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/vmess/outbound/__init__.py +0 -0
- xtlsapi/xray_api/proxy/vmess/outbound/config_pb2.py +38 -0
- xtlsapi/xray_api/proxy/vmess/outbound/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/proxy/wireguard/__init__.py +0 -0
- xtlsapi/xray_api/proxy/wireguard/config_pb2.py +41 -0
- xtlsapi/xray_api/proxy/wireguard/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/__init__.py +0 -0
- xtlsapi/xray_api/transport/global/__init__.py +0 -0
- xtlsapi/xray_api/transport/global/config_pb2.py +30 -0
- xtlsapi/xray_api/transport/global/config_pb2_grpc.py +4 -0
- xtlsapi/xray_api/transport/internet/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/config_pb2.py +51 -0
- xtlsapi/xray_api/transport/internet/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/domainsocket/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/domainsocket/config_pb2.py +27 -0
- xtlsapi/xray_api/transport/internet/domainsocket/config_pb2_grpc.py +4 -0
- xtlsapi/xray_api/transport/internet/grpc/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/grpc/config_pb2.py +37 -0
- xtlsapi/xray_api/transport/internet/grpc/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/grpc/encoding/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/grpc/encoding/stream_pb2.py +41 -0
- xtlsapi/xray_api/transport/internet/grpc/encoding/stream_pb2_grpc.py +140 -0
- xtlsapi/xray_api/transport/internet/headers/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/headers/dns/config_pb2.py +37 -0
- xtlsapi/xray_api/transport/internet/headers/dns/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/headers/http/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/headers/http/config_pb2.py +49 -0
- xtlsapi/xray_api/transport/internet/headers/http/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/headers/noop/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/headers/noop/config_pb2.py +39 -0
- xtlsapi/xray_api/transport/internet/headers/noop/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/headers/srtp/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/headers/srtp/config_pb2.py +37 -0
- xtlsapi/xray_api/transport/internet/headers/srtp/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/headers/tls/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/headers/tls/config_pb2.py +37 -0
- xtlsapi/xray_api/transport/internet/headers/tls/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/headers/utp/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/headers/utp/config_pb2.py +37 -0
- xtlsapi/xray_api/transport/internet/headers/utp/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/headers/wechat/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/headers/wechat/config_pb2.py +37 -0
- xtlsapi/xray_api/transport/internet/headers/wechat/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/headers/wireguard/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/headers/wireguard/config_pb2.py +37 -0
- xtlsapi/xray_api/transport/internet/headers/wireguard/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/http/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/http/config_pb2.py +38 -0
- xtlsapi/xray_api/transport/internet/http/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/httpupgrade/config_pb2.py +41 -0
- xtlsapi/xray_api/transport/internet/httpupgrade/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/kcp/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/kcp/config_pb2.py +54 -0
- xtlsapi/xray_api/transport/internet/kcp/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/quic/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/quic/config_pb2.py +29 -0
- xtlsapi/xray_api/transport/internet/quic/config_pb2_grpc.py +4 -0
- xtlsapi/xray_api/transport/internet/reality/config_pb2.py +37 -0
- xtlsapi/xray_api/transport/internet/reality/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/splithttp/config_pb2.py +46 -0
- xtlsapi/xray_api/transport/internet/splithttp/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/tcp/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/tcp/config_pb2.py +38 -0
- xtlsapi/xray_api/transport/internet/tcp/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/tls/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/tls/config_pb2.py +41 -0
- xtlsapi/xray_api/transport/internet/tls/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/udp/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/udp/config_pb2.py +37 -0
- xtlsapi/xray_api/transport/internet/udp/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/websocket/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/websocket/config_pb2.py +41 -0
- xtlsapi/xray_api/transport/internet/websocket/config_pb2_grpc.py +24 -0
- xtlsapi/xray_api/transport/internet/xtls/__init__.py +0 -0
- xtlsapi/xray_api/transport/internet/xtls/config_pb2.py +30 -0
- xtlsapi/xray_api/transport/internet/xtls/config_pb2_grpc.py +4 -0
- xtlsapi_ipblacklist-3.3.2.dist-info/METADATA +58 -0
- xtlsapi_ipblacklist-3.3.2.dist-info/RECORD +278 -0
- xtlsapi_ipblacklist-3.3.2.dist-info/WHEEL +5 -0
- xtlsapi_ipblacklist-3.3.2.dist-info/licenses/LICENSE +24 -0
- xtlsapi_ipblacklist-3.3.2.dist-info/top_level.txt +2 -0
tests/__init__.py
ADDED
|
File without changes
|
tests/conftest.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# each test runs on cwd to its temp dir
|
|
6
|
+
@pytest.fixture(autouse=True)
|
|
7
|
+
def go_to_tmpdir(request):
|
|
8
|
+
# Get the fixture dynamically by its name.
|
|
9
|
+
tmpdir = request.getfixturevalue("tmpdir")
|
|
10
|
+
# ensure local test created packages can be imported
|
|
11
|
+
sys.path.insert(0, str(tmpdir))
|
|
12
|
+
# Chdir only for the duration of the test.
|
|
13
|
+
with tmpdir.as_cwd():
|
|
14
|
+
yield
|
tests/test_base.py
ADDED
tests/test_block_ips.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from unittest.mock import patch
|
|
3
|
+
from xtlsapi import XrayClient
|
|
4
|
+
|
|
5
|
+
def test_stats_online_ip_list():
|
|
6
|
+
xray = XrayClient("127.0.0.1", 53357)
|
|
7
|
+
with patch.object(xray, 'stats_online_ip_list', return_value={'212.58.119.246': 1763418412}):
|
|
8
|
+
result = xray.stats_online_ip_list("1")
|
|
9
|
+
assert result == {'212.58.119.246': 1763418412}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from unittest.mock import patch
|
|
3
|
+
from xtlsapi import XrayClient
|
|
4
|
+
from xtlsapi.xray_api.app.router.command import command_pb2
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_stats_online_ip_list():
|
|
8
|
+
xray = XrayClient("127.0.0.1", 53357)
|
|
9
|
+
with patch.object(xray, 'block_ips', return_value=command_pb2.AddRuleResponse()):
|
|
10
|
+
xray.block_ips(
|
|
11
|
+
ips=["103.23.202.74"],
|
|
12
|
+
inbound_tag="vless-in"
|
|
13
|
+
)
|
|
14
|
+
assert xray
|
xtlsapi/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.3.0
|
xtlsapi/__init__.py
ADDED
xtlsapi/__main__.py
ADDED
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from xtlsapi.xray_api.app.log.command import config_pb2_grpc as logger_pb2_grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2_grpc as stats_pb2_grpc
|
|
3
|
+
from xtlsapi.xray_api.app.proxyman.command import command_pb2_grpc as handler_pb2_grpc
|
|
4
|
+
from xtlsapi.xray_api.app.router.command import command_pb2_grpc as router_pb2_grpc
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BaseService:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
self.stats_stub = stats_pb2_grpc.StatsServiceStub(self._channel)
|
|
10
|
+
self.logger_stub = logger_pb2_grpc.LoggerServiceStub(self._channel)
|
|
11
|
+
self.handler_stub = handler_pb2_grpc.HandlerServiceStub(self._channel)
|
|
12
|
+
self.routing_stub = router_pb2_grpc.RoutingServiceStub(self._channel)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from grpc._channel import _InactiveRpcError
|
|
2
|
+
|
|
3
|
+
from xtlsapi.xray_api.common.protocol import user_pb2
|
|
4
|
+
from xtlsapi.xray_api.app.proxyman.command import command_pb2
|
|
5
|
+
from xtlsapi.ext import utils
|
|
6
|
+
from .._base import BaseService
|
|
7
|
+
from xtlsapi import exceptions
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AddClient(BaseService):
|
|
11
|
+
def add_client(self, inbound_tag, user_id_or_password, email,protocol='vless', level=None, alter_id=None,flow=None,cipher=None):
|
|
12
|
+
try:
|
|
13
|
+
if protocol=='vmess':
|
|
14
|
+
from xtlsapi.xray_api.proxy.vmess import account_pb2
|
|
15
|
+
account=account_pb2.Account(id=user_id_or_password)
|
|
16
|
+
elif protocol=='vless':
|
|
17
|
+
from xtlsapi.xray_api.proxy.vless import account_pb2
|
|
18
|
+
account=account_pb2.Account(id=user_id_or_password,flow=flow,encryption="none")
|
|
19
|
+
elif protocol=='trojan':
|
|
20
|
+
from xtlsapi.xray_api.proxy.trojan import config_pb2
|
|
21
|
+
account=config_pb2.Account(password=user_id_or_password,flow=flow)
|
|
22
|
+
elif protocol=='shadowsocks':
|
|
23
|
+
from xtlsapi.xray_api.proxy.shadowsocks import config_pb2
|
|
24
|
+
cipher_map={'aes_128_gcm':config_pb2.CipherType.AES_128_GCM,
|
|
25
|
+
'aes_256_gcm':config_pb2.CipherType.AES_256_GCM,
|
|
26
|
+
'chacha20_poly1305':config_pb2.CipherType.CHACHA20_POLY1305,
|
|
27
|
+
'xchacha20_poly1305':config_pb2.CipherType.XCHACHA20_POLY1305,
|
|
28
|
+
None:config_pb2.CipherType.NONE
|
|
29
|
+
}
|
|
30
|
+
account=config_pb2.Account(password=user_id_or_password,cipher_type=cipher_map.get(cipher,cipher_map[None]))
|
|
31
|
+
# elif protocol=='shadowsocks_2022':
|
|
32
|
+
# from xtlsapi.xray_api.proxy.shadowsocks import config_pb2
|
|
33
|
+
# cipher_map={'aes_128_gcm':config_pb2.CipherType.AES_128_GCM,
|
|
34
|
+
# 'aes_256_gcm':config_pb2.CipherType.AES_256_GCM,
|
|
35
|
+
# 'chacha20_poly1305':config_pb2.CipherType.CHACHA20_POLY1305,
|
|
36
|
+
# 'xchacha20_poly1305':config_pb2.CipherType.XCHACHA20_POLY1305,
|
|
37
|
+
# None:config_pb2.CipherType.NONE
|
|
38
|
+
# }
|
|
39
|
+
# account=config_pb2.Account(password=user_id_or_password,cipher_type=cipher_map.get(cipher,cipher_map[None])
|
|
40
|
+
# raise Exception("not implemented ")
|
|
41
|
+
else:
|
|
42
|
+
raise Exception("not implemented "+protocol )
|
|
43
|
+
|
|
44
|
+
self.handler_stub.AlterInbound(
|
|
45
|
+
command_pb2.AlterInboundRequest(
|
|
46
|
+
tag=inbound_tag,
|
|
47
|
+
operation=utils.to_typed_message(
|
|
48
|
+
command_pb2.AddUserOperation(
|
|
49
|
+
user=user_pb2.User(
|
|
50
|
+
email=email,
|
|
51
|
+
level=level,
|
|
52
|
+
account=utils.to_typed_message(account),
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
),
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
return user_id_or_password
|
|
59
|
+
except _InactiveRpcError as e:
|
|
60
|
+
details = e.details()
|
|
61
|
+
if details.endswith(f"User {email} already exists."):
|
|
62
|
+
raise exceptions.EmailAlreadyExists(details, email)
|
|
63
|
+
elif details.endswith(f"handler not found: {inbound_tag}"):
|
|
64
|
+
raise exceptions.InboundNotFound(details, inbound_tag)
|
|
65
|
+
else:
|
|
66
|
+
raise exceptions.XRayException(details)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from grpc._channel import _InactiveRpcError
|
|
2
|
+
from xtlsapi.ext import utils
|
|
3
|
+
from xtlsapi import exceptions
|
|
4
|
+
from xtlsapi.xray_api.app.proxyman.command import command_pb2
|
|
5
|
+
|
|
6
|
+
from .._base import BaseService
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RemoveClient(BaseService):
|
|
10
|
+
def remove_client(self, inbound_tag, email):
|
|
11
|
+
try:
|
|
12
|
+
self.handler_stub.AlterInbound(
|
|
13
|
+
command_pb2.AlterInboundRequest(
|
|
14
|
+
tag=inbound_tag,
|
|
15
|
+
operation=utils.to_typed_message(
|
|
16
|
+
command_pb2.RemoveUserOperation(email=email)
|
|
17
|
+
),
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
except _InactiveRpcError as e:
|
|
21
|
+
details = e.details()
|
|
22
|
+
if details.endswith(f"User {email} not found."):
|
|
23
|
+
raise exceptions.EmailNotFound(details, email)
|
|
24
|
+
elif details.endswith(f"handler not found: {inbound_tag}"):
|
|
25
|
+
raise exceptions.InboundNotFound(details, inbound_tag)
|
|
26
|
+
else:
|
|
27
|
+
raise exceptions.XRayException(details)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from grpc._channel import _InactiveRpcError
|
|
2
|
+
|
|
3
|
+
from xtlsapi import exceptions
|
|
4
|
+
from xtlsapi.xray_api.app.log.command import config_pb2
|
|
5
|
+
|
|
6
|
+
from .._base import BaseService
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RestartLogger(BaseService):
|
|
10
|
+
def restart_logger(self):
|
|
11
|
+
try:
|
|
12
|
+
self.logger_stub.RestartLogger(
|
|
13
|
+
config_pb2.RestartLoggerRequest()
|
|
14
|
+
)
|
|
15
|
+
except _InactiveRpcError as e:
|
|
16
|
+
details = e.details()
|
|
17
|
+
raise exceptions.XRayException(details)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
import ipaddress
|
|
3
|
+
|
|
4
|
+
from xtlsapi.api_services._base import BaseService
|
|
5
|
+
from xtlsapi.xray_api.app.router.command import command_pb2
|
|
6
|
+
from xtlsapi.xray_api.common.serial import typed_message_pb2
|
|
7
|
+
from xtlsapi.xray_api.app.router import config_pb2
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RouterBlockIps(BaseService):
|
|
11
|
+
|
|
12
|
+
def block_ips(
|
|
13
|
+
self,
|
|
14
|
+
ips: list[str],
|
|
15
|
+
inbound_tag: str,
|
|
16
|
+
rule_tag: str = "sourceIpBlock",
|
|
17
|
+
outbound_tag: str = "blocked",
|
|
18
|
+
):
|
|
19
|
+
try:
|
|
20
|
+
self.routing_stub.RemoveRule(
|
|
21
|
+
command_pb2.RemoveRuleRequest(ruleTag=rule_tag)
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if not ips:
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
rule = config_pb2.RoutingRule()
|
|
28
|
+
rule.rule_tag = rule_tag
|
|
29
|
+
rule.inbound_tag.extend([inbound_tag] if inbound_tag else [])
|
|
30
|
+
rule.tag = outbound_tag
|
|
31
|
+
|
|
32
|
+
for ip in ips:
|
|
33
|
+
net = ipaddress.ip_network(ip, strict=False)
|
|
34
|
+
|
|
35
|
+
cidr = config_pb2.CIDR()
|
|
36
|
+
cidr.ip = net.network_address.packed
|
|
37
|
+
cidr.prefix = net.prefixlen
|
|
38
|
+
|
|
39
|
+
geo = config_pb2.GeoIP()
|
|
40
|
+
geo.cidr.append(cidr)
|
|
41
|
+
|
|
42
|
+
rule.source_geoip.append(geo)
|
|
43
|
+
|
|
44
|
+
config = config_pb2.Config()
|
|
45
|
+
config.rule.append(rule)
|
|
46
|
+
|
|
47
|
+
typed_msg = typed_message_pb2.TypedMessage(
|
|
48
|
+
type="xray.app.router.Config",
|
|
49
|
+
value=config.SerializeToString(),
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
return self.routing_stub.AddRule(
|
|
53
|
+
command_pb2.AddRuleRequest(
|
|
54
|
+
config=typed_msg,
|
|
55
|
+
shouldAppend=True,
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
except grpc.RpcError as e:
|
|
60
|
+
raise e
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .get_client_upload_traffic import GetClientUploadTraffic
|
|
2
|
+
from .get_client_download_traffic import GetClientDownloadTraffic
|
|
3
|
+
from .get_inbound_upload_traffic import GetInboundUploadTraffic
|
|
4
|
+
from .get_inbound_download_traffic import GetInboundDownloadTraffic
|
|
5
|
+
from .get_total_upload_traffic import GetTotalUploadTraffic
|
|
6
|
+
from .get_total_download_traffic import GetTotalDownloadTraffic
|
|
7
|
+
from .get_statsquery import StatsQuery
|
|
8
|
+
from .get_statsonline import StatsOnline
|
|
9
|
+
from .get_stats_online_ip_list import StatsOnlineIpList
|
|
10
|
+
|
|
11
|
+
class StatsAPIService(
|
|
12
|
+
GetClientUploadTraffic,
|
|
13
|
+
GetClientDownloadTraffic,
|
|
14
|
+
GetInboundUploadTraffic,
|
|
15
|
+
GetInboundDownloadTraffic,
|
|
16
|
+
GetTotalUploadTraffic,
|
|
17
|
+
GetTotalDownloadTraffic,
|
|
18
|
+
StatsQuery,
|
|
19
|
+
StatsOnline,
|
|
20
|
+
StatsOnlineIpList
|
|
21
|
+
):
|
|
22
|
+
pass
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2
|
|
3
|
+
|
|
4
|
+
from .._base import BaseService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class GetClientDownloadTraffic(BaseService):
|
|
8
|
+
def get_client_download_traffic(self, email, reset=False):
|
|
9
|
+
try:
|
|
10
|
+
return self.stats_stub.GetStats(
|
|
11
|
+
command_pb2.GetStatsRequest(
|
|
12
|
+
name=f"user>>>{email}>>>traffic>>>downlink", reset=reset
|
|
13
|
+
)
|
|
14
|
+
).stat.value
|
|
15
|
+
except grpc.RpcError:
|
|
16
|
+
# raise
|
|
17
|
+
return None
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2
|
|
3
|
+
from .._base import BaseService
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GetClientUploadTraffic(BaseService):
|
|
7
|
+
def get_client_upload_traffic(self, email, reset=False):
|
|
8
|
+
try:
|
|
9
|
+
return self.stats_stub.GetStats(
|
|
10
|
+
command_pb2.GetStatsRequest(
|
|
11
|
+
name=f"user>>>{email}>>>traffic>>>uplink", reset=reset
|
|
12
|
+
)
|
|
13
|
+
).stat.value
|
|
14
|
+
except grpc.RpcError:
|
|
15
|
+
return None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2
|
|
3
|
+
from .._base import BaseService
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GetInboundDownloadTraffic(BaseService):
|
|
7
|
+
def get_inbound_download_traffic(self, tag, reset=False):
|
|
8
|
+
try:
|
|
9
|
+
return self.stats_stub.GetStats(
|
|
10
|
+
command_pb2.GetStatsRequest(
|
|
11
|
+
name=f"inbound>>>{tag}>>>traffic>>>downlink", reset=reset
|
|
12
|
+
)
|
|
13
|
+
).stat.value
|
|
14
|
+
except grpc.RpcError:
|
|
15
|
+
# raise
|
|
16
|
+
return None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2
|
|
3
|
+
from .._base import BaseService
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GetInboundUploadTraffic(BaseService):
|
|
7
|
+
def get_inbound_upload_traffic(self, tag, reset=False):
|
|
8
|
+
try:
|
|
9
|
+
return self.stats_stub.GetStats(
|
|
10
|
+
command_pb2.GetStatsRequest(
|
|
11
|
+
name=f"inbound>>>{tag}>>>traffic>>>uplink", reset=reset
|
|
12
|
+
)
|
|
13
|
+
).stat.value
|
|
14
|
+
except grpc.RpcError:
|
|
15
|
+
# raise
|
|
16
|
+
return None
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2
|
|
3
|
+
|
|
4
|
+
from .._base import BaseService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StatsOnlineIpList(BaseService):
|
|
8
|
+
def stats_online_ip_list(self, user, reset=False) -> dict:
|
|
9
|
+
"""
|
|
10
|
+
Returns a dictionary of online IPs for the given user.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
user: The email of the user to query.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
A dictionary mapping IP addresses to last cleanup time of expired ip's.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
return self.stats_stub.GetStatsOnlineIpList(
|
|
21
|
+
command_pb2.GetStatsRequest(
|
|
22
|
+
name=f"user>>>{user}>>>online",
|
|
23
|
+
reset=reset
|
|
24
|
+
)
|
|
25
|
+
).ips
|
|
26
|
+
except grpc.RpcError:
|
|
27
|
+
raise
|
|
28
|
+
return None
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2
|
|
3
|
+
|
|
4
|
+
from .._base import BaseService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StatsOnline(BaseService):
|
|
8
|
+
def stats_online(self, user,reset=False):
|
|
9
|
+
try:
|
|
10
|
+
return self.stats_stub.GetStatsOnline(
|
|
11
|
+
command_pb2.GetStatsRequest(
|
|
12
|
+
name=f"user>>>{user}>>>online",
|
|
13
|
+
reset=reset
|
|
14
|
+
)
|
|
15
|
+
).stat.value
|
|
16
|
+
except grpc.RpcError:
|
|
17
|
+
raise
|
|
18
|
+
return None
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2
|
|
3
|
+
|
|
4
|
+
from .._base import BaseService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StatsQuery(BaseService):
|
|
8
|
+
def stats_query(self, pattern,reset=False):
|
|
9
|
+
try:
|
|
10
|
+
return self.stats_stub.QueryStats(
|
|
11
|
+
command_pb2.QueryStatsRequest(
|
|
12
|
+
pattern=pattern,reset=reset
|
|
13
|
+
)
|
|
14
|
+
).stat
|
|
15
|
+
except grpc.RpcError:
|
|
16
|
+
raise
|
|
17
|
+
return None
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2
|
|
3
|
+
from .._base import BaseService
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GetTotalDownloadTraffic(BaseService):
|
|
7
|
+
def get_total_download_traffic(self, reset=False):
|
|
8
|
+
raise Exception('Not Implemented')
|
|
9
|
+
try:
|
|
10
|
+
return self.stats_stub.GetStats(
|
|
11
|
+
command_pb2.GetStatsRequest(
|
|
12
|
+
name=f"outbound>>>statout>>>traffic>>>downlink", reset=reset
|
|
13
|
+
)
|
|
14
|
+
).stat.value
|
|
15
|
+
except grpc.RpcError:
|
|
16
|
+
# raise
|
|
17
|
+
return None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from xtlsapi.xray_api.app.stats.command import command_pb2
|
|
3
|
+
from .._base import BaseService
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GetTotalUploadTraffic(BaseService):
|
|
7
|
+
def get_total_upload_traffic(self, reset=False):
|
|
8
|
+
raise Exception('Not Implemented')
|
|
9
|
+
try:
|
|
10
|
+
return self.stats_stub.GetStats(
|
|
11
|
+
command_pb2.GetStatsRequest(
|
|
12
|
+
name=f"outbound>>>direct>>>traffic>>>uplink", reset=reset
|
|
13
|
+
)
|
|
14
|
+
).stat.value
|
|
15
|
+
except grpc.RpcError:
|
|
16
|
+
return None
|
xtlsapi/base.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
xtlsapi base module.
|
|
3
|
+
|
|
4
|
+
This is the principal module of the xtlsapi project.
|
|
5
|
+
here you put your main classes and objects.
|
|
6
|
+
|
|
7
|
+
Be creative! do whatever you want!
|
|
8
|
+
|
|
9
|
+
If you want to replace this with a Flask application run:
|
|
10
|
+
|
|
11
|
+
$ make init
|
|
12
|
+
|
|
13
|
+
and then choose `flask` as template.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# example constant variable
|
|
17
|
+
NAME = "xtlsapi"
|
xtlsapi/cli.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""CLI interface for xtlsapi project.
|
|
2
|
+
|
|
3
|
+
Be creative! do whatever you want!
|
|
4
|
+
|
|
5
|
+
- Install click or typer and create a CLI app
|
|
6
|
+
- Use builtin argparse
|
|
7
|
+
- Start a web application
|
|
8
|
+
- Import things from your .base module
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main(): # pragma: no cover
|
|
13
|
+
"""
|
|
14
|
+
The main function executes on commands:
|
|
15
|
+
`python -m xtlsapi` and `$ xtlsapi `.
|
|
16
|
+
|
|
17
|
+
This is your program's entry point.
|
|
18
|
+
|
|
19
|
+
You can change this function to do whatever you want.
|
|
20
|
+
Examples:
|
|
21
|
+
* Run a test suite
|
|
22
|
+
* Run a server
|
|
23
|
+
* Do some other stuff
|
|
24
|
+
* Run a command line application (Click, Typer, ArgParse)
|
|
25
|
+
* List all available tasks
|
|
26
|
+
* Run an application (Flask, FastAPI, Django, etc.)
|
|
27
|
+
"""
|
|
28
|
+
print("This will do something")
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from grpc import insecure_channel as grpc_insecure_channel
|
|
2
|
+
|
|
3
|
+
from xtlsapi.singbox_api_services import APIService
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SingboxClient(APIService):
|
|
7
|
+
def __init__(self, host, port):
|
|
8
|
+
self.host = host
|
|
9
|
+
self.port = port
|
|
10
|
+
self._channel = grpc_insecure_channel(f'{host}:{port}')
|
|
11
|
+
super().__init__()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from grpc import insecure_channel as grpc_insecure_channel
|
|
2
|
+
|
|
3
|
+
from xtlsapi.api_services import APIService
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class XrayClient(APIService):
|
|
7
|
+
def __init__(self, host, port):
|
|
8
|
+
self.host = host
|
|
9
|
+
self.port = port
|
|
10
|
+
self._channel = grpc_insecure_channel(f'{host}:{port}')
|
|
11
|
+
super().__init__()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .XrayClient import XrayClient
|
|
Binary file
|
|
Binary file
|
xtlsapi/ext/__init__.py
ADDED
|
File without changes
|
xtlsapi/ext/utils.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
import math
|
|
3
|
+
import socket
|
|
4
|
+
import secrets
|
|
5
|
+
|
|
6
|
+
from xtlsapi.xray_api.common.serial import typed_message_pb2
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def to_typed_message(message):
|
|
10
|
+
return typed_message_pb2.TypedMessage(
|
|
11
|
+
type=message.DESCRIPTOR.full_name, value=message.SerializeToString()
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def ip2bytes(ip: str):
|
|
16
|
+
return bytes([int(i) for i in ip.split('.')])
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def generate_random_tag():
|
|
20
|
+
return secrets.token_urlsafe()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def generate_random_name(hex_count=8):
|
|
24
|
+
return f"{secrets.token_hex(hex_count)}"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def generate_random_user_id():
|
|
28
|
+
return uuid.uuid4().hex
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def generate_random_email(tld='vump.com', hex_count=8):
|
|
32
|
+
return f"{generate_random_name(hex_count)}@{tld}"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def generate_random_port():
|
|
36
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as tcp:
|
|
37
|
+
tcp.bind(('', 0))
|
|
38
|
+
addr, port = tcp.getsockname()
|
|
39
|
+
return port
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def human_readable_bytes(size_bytes):
|
|
43
|
+
if not size_bytes:
|
|
44
|
+
return "0 B"
|
|
45
|
+
size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
|
|
46
|
+
i = int(math.floor(math.log(size_bytes, 1024)))
|
|
47
|
+
p = math.pow(1024, i)
|
|
48
|
+
s = round(size_bytes / p, 2)
|
|
49
|
+
return f"{s} {size_name[i]}"
|