eiskaltdcpp-py 2.5.0.0__tar.gz

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.
Files changed (116) hide show
  1. eiskaltdcpp_py-2.5.0.0/.github/workflows/ci.yml +348 -0
  2. eiskaltdcpp_py-2.5.0.0/.github/workflows/wheels.yml +250 -0
  3. eiskaltdcpp_py-2.5.0.0/.gitignore +38 -0
  4. eiskaltdcpp_py-2.5.0.0/CMakeLists.txt +252 -0
  5. eiskaltdcpp_py-2.5.0.0/LICENSE +675 -0
  6. eiskaltdcpp_py-2.5.0.0/MANIFEST.in +15 -0
  7. eiskaltdcpp_py-2.5.0.0/PKG-INFO +1283 -0
  8. eiskaltdcpp_py-2.5.0.0/README.md +1229 -0
  9. eiskaltdcpp_py-2.5.0.0/TODO.md +51 -0
  10. eiskaltdcpp_py-2.5.0.0/examples/basic_chat.py +170 -0
  11. eiskaltdcpp_py-2.5.0.0/examples/download_progress.py +257 -0
  12. eiskaltdcpp_py-2.5.0.0/examples/file_list_browser.py +242 -0
  13. eiskaltdcpp_py-2.5.0.0/examples/lua/README.md +55 -0
  14. eiskaltdcpp_py-2.5.0.0/examples/lua/auto_greet.lua +146 -0
  15. eiskaltdcpp_py-2.5.0.0/examples/lua/chat_commands.lua +168 -0
  16. eiskaltdcpp_py-2.5.0.0/examples/lua/chat_logger.lua +161 -0
  17. eiskaltdcpp_py-2.5.0.0/examples/lua/hub_monitor.lua +191 -0
  18. eiskaltdcpp_py-2.5.0.0/examples/lua/spam_filter.lua +196 -0
  19. eiskaltdcpp_py-2.5.0.0/examples/multi_hub_bot.py +254 -0
  20. eiskaltdcpp_py-2.5.0.0/examples/remote_client.py +222 -0
  21. eiskaltdcpp_py-2.5.0.0/examples/search_and_download.py +227 -0
  22. eiskaltdcpp_py-2.5.0.0/examples/share_manager.py +195 -0
  23. eiskaltdcpp_py-2.5.0.0/poetry.lock +1442 -0
  24. eiskaltdcpp_py-2.5.0.0/pyproject.toml +109 -0
  25. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/__init__.py +42 -0
  26. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/__init__.py +9 -0
  27. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/__main__.py +148 -0
  28. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/app.py +109 -0
  29. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/auth.py +322 -0
  30. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/client.py +820 -0
  31. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/dashboard.py +948 -0
  32. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/dependencies.py +124 -0
  33. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/models.py +525 -0
  34. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/__init__.py +44 -0
  35. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/adl.py +99 -0
  36. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/auth.py +194 -0
  37. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/chat.py +79 -0
  38. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/connectivity.py +74 -0
  39. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/crypto.py +72 -0
  40. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/favorites.py +189 -0
  41. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/finished.py +54 -0
  42. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/hubs.py +123 -0
  43. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/ipfilter.py +39 -0
  44. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/logs.py +39 -0
  45. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/lua.py +122 -0
  46. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/queue.py +157 -0
  47. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/search.py +101 -0
  48. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/settings.py +117 -0
  49. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/shares.py +117 -0
  50. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/status.py +169 -0
  51. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/routes/throttle.py +61 -0
  52. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/api/websocket.py +406 -0
  53. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/async_client.py +1101 -0
  54. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/cli.py +2203 -0
  55. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/dc_client.py +812 -0
  56. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/event_meta.py +38 -0
  57. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/exceptions.py +34 -0
  58. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/hub_aliases.py +112 -0
  59. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/protocol.py +160 -0
  60. eiskaltdcpp_py-2.5.0.0/python/eiskaltdcpp/search_store.py +134 -0
  61. eiskaltdcpp_py-2.5.0.0/src/CMakeLists.txt +75 -0
  62. eiskaltdcpp_py-2.5.0.0/src/bridge_listeners.cpp +102 -0
  63. eiskaltdcpp_py-2.5.0.0/src/bridge_listeners.h +468 -0
  64. eiskaltdcpp_py-2.5.0.0/src/callbacks.h +176 -0
  65. eiskaltdcpp_py-2.5.0.0/src/dcpp_compat.h +41 -0
  66. eiskaltdcpp_py-2.5.0.0/src/eispy_context.cpp +1325 -0
  67. eiskaltdcpp_py-2.5.0.0/src/eispy_context.h +338 -0
  68. eiskaltdcpp_py-2.5.0.0/src/extra/lunar.h +31 -0
  69. eiskaltdcpp_py-2.5.0.0/src/listener_adapters.h +428 -0
  70. eiskaltdcpp_py-2.5.0.0/src/types.h +114 -0
  71. eiskaltdcpp_py-2.5.0.0/swig/CMakeLists.txt +253 -0
  72. eiskaltdcpp_py-2.5.0.0/swig/copy_runtime_dlls.cmake +52 -0
  73. eiskaltdcpp_py-2.5.0.0/swig/dc_core.i +360 -0
  74. eiskaltdcpp_py-2.5.0.0/swig/dcpp_adl_search.i +77 -0
  75. eiskaltdcpp_py-2.5.0.0/swig/dcpp_client_manager.i +113 -0
  76. eiskaltdcpp_py-2.5.0.0/swig/dcpp_connection_manager.i +55 -0
  77. eiskaltdcpp_py-2.5.0.0/swig/dcpp_connectivity.i +48 -0
  78. eiskaltdcpp_py-2.5.0.0/swig/dcpp_context.i +140 -0
  79. eiskaltdcpp_py-2.5.0.0/swig/dcpp_context_base.i +52 -0
  80. eiskaltdcpp_py-2.5.0.0/swig/dcpp_crypto_manager.i +45 -0
  81. eiskaltdcpp_py-2.5.0.0/swig/dcpp_debug_manager.i +30 -0
  82. eiskaltdcpp_py-2.5.0.0/swig/dcpp_download_manager.i +42 -0
  83. eiskaltdcpp_py-2.5.0.0/swig/dcpp_dyndns.i +29 -0
  84. eiskaltdcpp_py-2.5.0.0/swig/dcpp_favorite_manager.i +92 -0
  85. eiskaltdcpp_py-2.5.0.0/swig/dcpp_finished_manager.i +35 -0
  86. eiskaltdcpp_py-2.5.0.0/swig/dcpp_hash_manager.i +56 -0
  87. eiskaltdcpp_py-2.5.0.0/swig/dcpp_ipfilter.i +52 -0
  88. eiskaltdcpp_py-2.5.0.0/swig/dcpp_listeners.i +128 -0
  89. eiskaltdcpp_py-2.5.0.0/swig/dcpp_log_manager.i +37 -0
  90. eiskaltdcpp_py-2.5.0.0/swig/dcpp_queue_manager.i +115 -0
  91. eiskaltdcpp_py-2.5.0.0/swig/dcpp_search_manager.i +61 -0
  92. eiskaltdcpp_py-2.5.0.0/swig/dcpp_settings.i +235 -0
  93. eiskaltdcpp_py-2.5.0.0/swig/dcpp_share_manager.i +80 -0
  94. eiskaltdcpp_py-2.5.0.0/swig/dcpp_throttle_manager.i +46 -0
  95. eiskaltdcpp_py-2.5.0.0/swig/dcpp_types.i +529 -0
  96. eiskaltdcpp_py-2.5.0.0/swig/dcpp_upload_manager.i +62 -0
  97. eiskaltdcpp_py-2.5.0.0/swig/eispy_context.i +164 -0
  98. eiskaltdcpp_py-2.5.0.0/tests/CMakeLists.txt +28 -0
  99. eiskaltdcpp_py-2.5.0.0/tests/conftest.py +43 -0
  100. eiskaltdcpp_py-2.5.0.0/tests/dc_worker.py +452 -0
  101. eiskaltdcpp_py-2.5.0.0/tests/test_api.py +1248 -0
  102. eiskaltdcpp_py-2.5.0.0/tests/test_cli.py +415 -0
  103. eiskaltdcpp_py-2.5.0.0/tests/test_cli_remote.py +1300 -0
  104. eiskaltdcpp_py-2.5.0.0/tests/test_client.py +701 -0
  105. eiskaltdcpp_py-2.5.0.0/tests/test_dashboard.py +192 -0
  106. eiskaltdcpp_py-2.5.0.0/tests/test_dc_core.py +633 -0
  107. eiskaltdcpp_py-2.5.0.0/tests/test_file_transfer.py +514 -0
  108. eiskaltdcpp_py-2.5.0.0/tests/test_hub_aliases.py +455 -0
  109. eiskaltdcpp_py-2.5.0.0/tests/test_integration.py +734 -0
  110. eiskaltdcpp_py-2.5.0.0/tests/test_lua_integration.py +458 -0
  111. eiskaltdcpp_py-2.5.0.0/tests/test_remote_client_integration.py +906 -0
  112. eiskaltdcpp_py-2.5.0.0/tests/test_rest_phase2.py +316 -0
  113. eiskaltdcpp_py-2.5.0.0/tests/test_search_store.py +375 -0
  114. eiskaltdcpp_py-2.5.0.0/tests/test_swig_listeners.py +373 -0
  115. eiskaltdcpp_py-2.5.0.0/tests/test_swig_managers.py +494 -0
  116. eiskaltdcpp_py-2.5.0.0/tests/test_websocket.py +940 -0
@@ -0,0 +1,348 @@
1
+ #
2
+ # CI — build + test on every PR and push to master
3
+ #
4
+ name: CI
5
+
6
+ on:
7
+ push:
8
+ branches: [master]
9
+ pull_request:
10
+ branches: [master]
11
+
12
+ concurrency:
13
+ group: ci-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ build-and-test:
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ python-version: ["3.10", "3.12"]
22
+ build-type: [Release]
23
+ runner:
24
+ - ubuntu-24.04
25
+ - [self-hosted, linux, x64]
26
+
27
+ runs-on: ${{ matrix.runner }}
28
+ continue-on-error: ${{ !contains(toJSON(matrix.runner), 'ubuntu') }}
29
+
30
+ steps:
31
+ - name: Checkout
32
+ uses: actions/checkout@v4
33
+ with:
34
+ submodules: recursive
35
+
36
+ - name: Set up Python ${{ matrix.python-version }}
37
+ uses: actions/setup-python@v5
38
+ with:
39
+ python-version: ${{ matrix.python-version }}
40
+
41
+ - name: Install system dependencies
42
+ run: |
43
+ sudo apt-get update -qq
44
+ sudo apt-get install -y --no-install-recommends \
45
+ build-essential gettext \
46
+ cmake swig python3-dev \
47
+ libssl-dev zlib1g-dev libbz2-dev \
48
+ libminiupnpc-dev libidn2-dev libpcre2-dev \
49
+ liblua5.4-dev || \
50
+ sudo apt-get install -y --no-install-recommends \
51
+ build-essential gettext \
52
+ cmake swig python3-dev \
53
+ libssl-dev zlib1g-dev libbz2-dev \
54
+ libminiupnpc-dev libidn2-dev libpcre2-dev \
55
+ liblua5.3-dev
56
+
57
+ - name: Install Python dependencies
58
+ run: |
59
+ python -m pip install --upgrade pip
60
+ python -m pip install pytest pytest-asyncio pytest-timeout click \
61
+ fastapi uvicorn[standard] python-jose[cryptography] bcrypt pydantic httpx
62
+
63
+ - name: Configure
64
+ run: |
65
+ cmake -B build \
66
+ -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \
67
+ -DUSE_SYSTEM_EISKALTDCPP=OFF \
68
+ -DBUILD_TESTS=ON \
69
+ -DPython3_EXECUTABLE=$(which python)
70
+
71
+ - name: Build
72
+ run: cmake --build build -j$(nproc)
73
+
74
+ - name: Run tests (CTest)
75
+ working-directory: build
76
+ run: ctest --output-on-failure -j$(nproc)
77
+
78
+ - name: Run tests (pytest direct)
79
+ run: |
80
+ PYTHONPATH=build/python python -m pytest tests/ -v --tb=short \
81
+ --ignore=tests/test_integration.py
82
+
83
+ - name: Compute artifact name
84
+ id: artifact
85
+ run: |
86
+ VERSION=$(grep 'project.*VERSION' CMakeLists.txt | head -1 | sed 's/.*VERSION *\([^ )]*\).*/\1/')
87
+ SHA=$(git rev-parse --short HEAD)
88
+ ARCH=$(uname -m)
89
+ if ${{ contains(toJSON(matrix.runner), 'ubuntu') }}; then
90
+ OS=linux
91
+ else
92
+ OS=linux-selfhosted
93
+ fi
94
+ PYVER=$(echo "${{ matrix.python-version }}" | tr -d '.')
95
+ echo "name=eiskaltdcpp-py-${VERSION}~dev-${SHA}-${OS}-${ARCH}-py${PYVER}" >> "$GITHUB_OUTPUT"
96
+
97
+ - name: Upload build artifact
98
+ if: contains(toJSON(matrix.runner), 'ubuntu')
99
+ uses: actions/upload-artifact@v4
100
+ with:
101
+ name: ${{ steps.artifact.outputs.name }}
102
+ path: build/python/
103
+ retention-days: 14
104
+
105
+ build-and-test-windows:
106
+ name: Windows (${{ matrix.python-version }})
107
+ runs-on: windows-latest
108
+
109
+ strategy:
110
+ fail-fast: false
111
+ matrix:
112
+ python-version: ["3.10", "3.12"]
113
+
114
+ env:
115
+ VCPKG_DEFAULT_TRIPLET: x64-windows
116
+ VCPKG_BINARY_SOURCES: 'clear;x-gha,readwrite'
117
+
118
+ steps:
119
+ - uses: actions/checkout@v4
120
+ with:
121
+ submodules: recursive
122
+
123
+ - uses: actions/github-script@v7
124
+ with:
125
+ script: |
126
+ core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
127
+ core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
128
+
129
+ - name: Set up MSVC
130
+ uses: ilammy/msvc-dev-cmd@v1
131
+ with:
132
+ arch: x64
133
+
134
+ - name: Set up Python ${{ matrix.python-version }}
135
+ uses: actions/setup-python@v5
136
+ with:
137
+ python-version: ${{ matrix.python-version }}
138
+
139
+ - name: Install vcpkg dependencies
140
+ run: |
141
+ vcpkg install --triplet x64-windows `
142
+ openssl bzip2 zlib miniupnpc pcre2 lua `
143
+ libiconv libidn2 gettext
144
+
145
+ - name: Install gettext tools (MSYS2)
146
+ shell: pwsh
147
+ run: |
148
+ # vcpkg provides libintl for linking; MSYS2 provides the CLI tools
149
+ # (xgettext, msgfmt, msgmerge, etc.) needed by FindGettext.cmake
150
+ C:\msys64\usr\bin\pacman.exe -S --noconfirm --needed gettext
151
+ echo "C:\msys64\usr\bin" >> $env:GITHUB_PATH
152
+
153
+ - name: Install SWIG
154
+ run: choco install swig -y --no-progress
155
+
156
+ - name: Install Python dependencies
157
+ run: |
158
+ python -m pip install --upgrade pip
159
+ python -m pip install pytest pytest-asyncio pytest-timeout click `
160
+ fastapi "uvicorn[standard]" "python-jose[cryptography]" bcrypt pydantic httpx
161
+
162
+ - name: Configure
163
+ run: |
164
+ cmake -B build -G Ninja `
165
+ -DCMAKE_BUILD_TYPE=Release `
166
+ -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" `
167
+ -DUSE_SYSTEM_EISKALTDCPP=OFF `
168
+ -DBUILD_TESTS=ON `
169
+ -DPython3_EXECUTABLE="$(Get-Command python | Select-Object -ExpandProperty Source)"
170
+
171
+ - name: Build
172
+ run: cmake --build build
173
+
174
+ - name: Run tests (CTest)
175
+ working-directory: build
176
+ run: |
177
+ $env:PATH = "$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin;$($env:PATH -replace 'C:\\msys64\\usr\\bin;?','')"
178
+ ctest --output-on-failure
179
+
180
+ - name: Run tests (pytest direct)
181
+ run: |
182
+ # Ensure vcpkg DLLs are found before any MSYS2 DLLs (ABI mismatch).
183
+ # MSYS2's libintl-8.dll (MinGW ABI) shadows vcpkg's (MSVC ABI) and
184
+ # causes a hard crash inside dcpp::startup() → bindtextdomain().
185
+ $env:PATH = "$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin;$($env:PATH -replace 'C:\\msys64\\usr\\bin;?','')"
186
+ $env:PYTHONPATH = "build/python"
187
+ python -m pytest tests/ -v -s --tb=short `
188
+ --ignore=tests/test_integration.py `
189
+ --ignore=tests/test_file_transfer.py
190
+
191
+ - name: Compute artifact name
192
+ id: artifact
193
+ shell: pwsh
194
+ run: |
195
+ $version = (Select-String -Path CMakeLists.txt -Pattern 'project.*VERSION\s+([^ )]+)').Matches[0].Groups[1].Value
196
+ $sha = git rev-parse --short HEAD
197
+ $pyver = '${{ matrix.python-version }}' -replace '\.',''
198
+ $name = "eiskaltdcpp-py-${version}~dev-${sha}-windows-x64-py${pyver}"
199
+ echo "name=$name" >> $env:GITHUB_OUTPUT
200
+
201
+ - name: Upload build artifact
202
+ uses: actions/upload-artifact@v4
203
+ with:
204
+ name: ${{ steps.artifact.outputs.name }}
205
+ path: build/python/
206
+ retention-days: 14
207
+
208
+ build-and-test-macos:
209
+ name: macOS (${{ matrix.python-version }})
210
+ runs-on: macos-latest
211
+
212
+ strategy:
213
+ fail-fast: false
214
+ matrix:
215
+ python-version: ["3.10", "3.12"]
216
+
217
+ steps:
218
+ - uses: actions/checkout@v4
219
+ with:
220
+ submodules: recursive
221
+
222
+ - name: Set up Python ${{ matrix.python-version }}
223
+ uses: actions/setup-python@v5
224
+ with:
225
+ python-version: ${{ matrix.python-version }}
226
+
227
+ - name: Install system dependencies
228
+ run: |
229
+ brew install cmake swig openssl@3 miniupnpc libidn2 pcre2 lua bzip2 gettext gcc
230
+
231
+ - name: Install Python dependencies
232
+ run: |
233
+ python -m pip install --upgrade pip
234
+ python -m pip install pytest pytest-asyncio pytest-timeout click \
235
+ fastapi "uvicorn[standard]" "python-jose[cryptography]" bcrypt pydantic httpx
236
+
237
+ - name: Configure
238
+ run: |
239
+ # Apple Clang lacks std::jthread — use Homebrew GCC for full C++20
240
+ GCC_VER=$(ls /opt/homebrew/bin/g++-* 2>/dev/null | grep -oE '[0-9]+$' | sort -n | tail -1)
241
+ # Homebrew GCC doesn't search Homebrew paths by default
242
+ BREW_PREFIX=$(brew --prefix)
243
+ export CPATH="${BREW_PREFIX}/include"
244
+ export LIBRARY_PATH="${BREW_PREFIX}/lib"
245
+ cmake -B build \
246
+ -DCMAKE_BUILD_TYPE=Release \
247
+ -DCMAKE_C_COMPILER="$(brew --prefix gcc)/bin/gcc-${GCC_VER}" \
248
+ -DCMAKE_CXX_COMPILER="$(brew --prefix gcc)/bin/g++-${GCC_VER}" \
249
+ -DUSE_SYSTEM_EISKALTDCPP=OFF \
250
+ -DBUILD_TESTS=ON \
251
+ -DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)" \
252
+ -DCMAKE_PREFIX_PATH="$(brew --prefix openssl@3);$(brew --prefix bzip2);$(brew --prefix pcre2);$(brew --prefix miniupnpc);$(brew --prefix libidn2);$(brew --prefix lua);$(brew --prefix gettext)" \
253
+ -DPython3_EXECUTABLE=$(which python)
254
+
255
+ - name: Build
256
+ run: |
257
+ BREW_PREFIX=$(brew --prefix)
258
+ export CPATH="${BREW_PREFIX}/include"
259
+ export LIBRARY_PATH="${BREW_PREFIX}/lib"
260
+ cmake --build build -j$(sysctl -n hw.ncpu)
261
+
262
+ - name: Run tests (CTest)
263
+ working-directory: build
264
+ run: ctest --output-on-failure -j$(sysctl -n hw.ncpu)
265
+
266
+ - name: Run tests (pytest direct)
267
+ run: |
268
+ PYTHONPATH=build/python python -m pytest tests/ -v --tb=short \
269
+ --ignore=tests/test_integration.py \
270
+ --ignore=tests/test_file_transfer.py
271
+
272
+ - name: Compute artifact name
273
+ id: artifact
274
+ run: |
275
+ VERSION=$(grep 'project.*VERSION' CMakeLists.txt | head -1 | sed 's/.*VERSION *\([^ )]*\).*/\1/')
276
+ SHA=$(git rev-parse --short HEAD)
277
+ ARCH=$(uname -m)
278
+ PYVER=$(echo "${{ matrix.python-version }}" | tr -d '.')
279
+ echo "name=eiskaltdcpp-py-${VERSION}~dev-${SHA}-macos-${ARCH}-py${PYVER}" >> "$GITHUB_OUTPUT"
280
+
281
+ - name: Upload build artifact
282
+ uses: actions/upload-artifact@v4
283
+ with:
284
+ name: ${{ steps.artifact.outputs.name }}
285
+ path: build/python/
286
+ retention-days: 14
287
+
288
+ integration:
289
+ name: Integration tests
290
+ needs:
291
+ - build-and-test
292
+ - build-and-test-windows
293
+ - build-and-test-macos
294
+ runs-on: [self-hosted, linux, x64]
295
+ timeout-minutes: 15
296
+
297
+ # Network issues with live hubs should not block merging.
298
+ continue-on-error: true
299
+
300
+ steps:
301
+ - name: Checkout
302
+ uses: actions/checkout@v4
303
+ with:
304
+ submodules: recursive
305
+
306
+ - name: Set up Python
307
+ uses: actions/setup-python@v5
308
+ with:
309
+ python-version: "3.12"
310
+
311
+ - name: Install system dependencies
312
+ run: |
313
+ sudo apt-get update -qq
314
+ sudo apt-get install -y --no-install-recommends \
315
+ build-essential gettext \
316
+ cmake swig python3-dev \
317
+ libssl-dev zlib1g-dev libbz2-dev \
318
+ libminiupnpc-dev libidn2-dev libpcre2-dev \
319
+ liblua5.4-dev || \
320
+ sudo apt-get install -y --no-install-recommends \
321
+ build-essential gettext \
322
+ cmake swig python3-dev \
323
+ libssl-dev zlib1g-dev libbz2-dev \
324
+ libminiupnpc-dev libidn2-dev libpcre2-dev \
325
+ liblua5.3-dev
326
+
327
+ - name: Install Python dependencies
328
+ run: |
329
+ python -m pip install --upgrade pip
330
+ python -m pip install pytest pytest-asyncio pytest-timeout click \
331
+ fastapi uvicorn[standard] python-jose[cryptography] bcrypt pydantic httpx
332
+
333
+ - name: Build
334
+ run: |
335
+ cmake -B build \
336
+ -DCMAKE_BUILD_TYPE=Release \
337
+ -DUSE_SYSTEM_EISKALTDCPP=OFF \
338
+ -DBUILD_TESTS=ON \
339
+ -DPython3_EXECUTABLE=$(which python)
340
+ cmake --build build -j$(nproc)
341
+
342
+ - name: Run integration tests
343
+ env:
344
+ PYTHONPATH: build/python
345
+ run: |
346
+ python -m pytest tests/test_integration.py tests/test_file_transfer.py \
347
+ -v --tb=long --timeout=300 -x \
348
+ -o "addopts="
@@ -0,0 +1,250 @@
1
+ #
2
+ # Build wheels for Linux, Windows, macOS + publish to PyPI
3
+ #
4
+ # Triggers:
5
+ # - Manual dispatch (workflow_dispatch)
6
+ # - Git tag push (v*)
7
+ #
8
+ # The wheel build uses FetchContent to compile eiskaltdcpp from source,
9
+ # so no system libeiskaltdcpp-dev is needed.
10
+ #
11
+ name: Wheels
12
+
13
+ on:
14
+ workflow_dispatch:
15
+ push:
16
+ tags:
17
+ - "v*"
18
+
19
+ concurrency:
20
+ group: wheels-${{ github.ref }}
21
+ cancel-in-progress: true
22
+
23
+ permissions:
24
+ actions: write
25
+
26
+ env:
27
+ # Core release tag whose prebuilt SDK archives are consumed (best-effort).
28
+ # If the matching SDK asset is missing, the build falls back to compiling
29
+ # the core from source via FetchContent (see CMakeLists.txt).
30
+ EISKALTDCPP_CORE_TAG: v2.5.0
31
+
32
+ jobs:
33
+ # ─── Build wheels ───────────────────────────────────────────────
34
+ build-wheels:
35
+ name: Wheel ${{ matrix.os }} / ${{ matrix.arch }}
36
+ runs-on: ${{ matrix.runner }}
37
+ strategy:
38
+ fail-fast: false
39
+ matrix:
40
+ include:
41
+ - os: linux
42
+ arch: x86_64
43
+ runner: ubuntu-24.04
44
+ - os: windows
45
+ arch: AMD64
46
+ runner: windows-latest
47
+ - os: macos
48
+ arch: arm64
49
+ runner: macos-14
50
+
51
+ steps:
52
+ - uses: actions/checkout@v4
53
+ with:
54
+ submodules: recursive
55
+
56
+ - uses: actions/setup-python@v5
57
+ with:
58
+ python-version: "3.12"
59
+
60
+ # vcpkg caching for Windows
61
+ - name: Export GitHub Actions cache variables
62
+ if: matrix.os == 'windows'
63
+ uses: actions/github-script@v7
64
+ with:
65
+ script: |
66
+ core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
67
+ core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
68
+
69
+ - name: Set up MSVC
70
+ if: matrix.os == 'windows'
71
+ uses: ilammy/msvc-dev-cmd@v1
72
+ with:
73
+ arch: x64
74
+
75
+ - name: Install cibuildwheel
76
+ run: python -m pip install cibuildwheel==2.23.0
77
+
78
+ - name: Install delvewheel (Windows)
79
+ if: matrix.os == 'windows'
80
+ run: python -m pip install delvewheel
81
+
82
+ - name: Build wheels
83
+ run: python -m cibuildwheel --output-dir wheelhouse
84
+ env:
85
+ # ── Build matrix ────────────────────────────────────────
86
+ CIBW_BUILD: "cp310-* cp311-* cp312-* cp313-*"
87
+ CIBW_SKIP: "*-musllinux_* *-win32 *-manylinux_i686"
88
+ CIBW_ARCHS_LINUX: x86_64
89
+ CIBW_ARCHS_WINDOWS: AMD64
90
+ CIBW_ARCHS_MACOS: ${{ matrix.arch }}
91
+
92
+ # ── Linux ───────────────────────────────────────────────
93
+ CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
94
+ CIBW_BEFORE_ALL_LINUX: >
95
+ dnf install -y
96
+ openssl-devel zlib-devel bzip2-devel
97
+ pcre-devel pcre2-devel lua-devel
98
+ libidn-devel libidn2-devel miniupnpc-devel
99
+ gettext-devel
100
+ swig cmake gcc-c++ ninja-build tar gzip
101
+ &&
102
+ ( SDKD="$HOME/.eiskaltdcpp-sdk"; mkdir -p "$SDKD";
103
+ URL="https://github.com/transfix/eiskaltdcpp/releases/download/${EISKALTDCPP_CORE_TAG}/eiskaltdcpp-core-${EISKALTDCPP_CORE_TAG}-linux-x64.tar.gz";
104
+ if curl -fSL "$URL" -o /tmp/edcpp-sdk.tgz;
105
+ then tar xzf /tmp/edcpp-sdk.tgz -C "$SDKD"
106
+ && ln -sfn "$SDKD/eiskaltdcpp-core-${EISKALTDCPP_CORE_TAG}-linux-x64" "$SDKD/core"
107
+ && echo "Using prebuilt core SDK at $SDKD/core";
108
+ else echo "No prebuilt SDK for ${EISKALTDCPP_CORE_TAG}; core will be built from source."; fi )
109
+ CIBW_ENVIRONMENT_PASS_LINUX: EISKALTDCPP_CORE_TAG
110
+ CIBW_REPAIR_WHEEL_COMMAND_LINUX: >
111
+ auditwheel repair -w {dest_dir} {wheel}
112
+
113
+ # ── Windows ─────────────────────────────────────────────
114
+ CIBW_BEFORE_ALL_WINDOWS: >
115
+ vcpkg install --triplet x64-windows
116
+ openssl bzip2 zlib miniupnpc pcre2 lua libiconv libidn2 gettext &&
117
+ C:\msys64\usr\bin\pacman.exe -S --noconfirm --needed gettext &&
118
+ choco install swig -y --no-progress
119
+ CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >
120
+ delvewheel repair -w {dest_dir} {wheel}
121
+ --add-path "C:/vcpkg/installed/x64-windows/bin"
122
+ CIBW_ENVIRONMENT_WINDOWS: >
123
+ VCPKG_BINARY_SOURCES="clear;x-gha,readwrite"
124
+ PATH="C:\\msys64\\usr\\bin;$PATH"
125
+ CMAKE_ARGS="-DUSE_SYSTEM_EISKALTDCPP=OFF
126
+ -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake"
127
+
128
+ # ── macOS ───────────────────────────────────────────────
129
+ CIBW_BEFORE_ALL_MACOS: >
130
+ brew install swig openssl@3 miniupnpc libidn2 pcre2 lua bzip2 gettext gcc
131
+ &&
132
+ ( SDKD="$HOME/.eiskaltdcpp-sdk"; mkdir -p "$SDKD"; ARCH=$(uname -m);
133
+ URL="https://github.com/transfix/eiskaltdcpp/releases/download/${EISKALTDCPP_CORE_TAG}/eiskaltdcpp-core-${EISKALTDCPP_CORE_TAG}-macos-${ARCH}.tar.gz";
134
+ if curl -fSL "$URL" -o /tmp/edcpp-sdk.tgz;
135
+ then tar xzf /tmp/edcpp-sdk.tgz -C "$SDKD"
136
+ && ln -sfn "$SDKD/eiskaltdcpp-core-${EISKALTDCPP_CORE_TAG}-macos-${ARCH}" "$SDKD/core"
137
+ && echo "Using prebuilt core SDK at $SDKD/core";
138
+ else echo "No prebuilt SDK for ${EISKALTDCPP_CORE_TAG}; core will be built from source."; fi )
139
+ &&
140
+ ( mkdir -p "$HOME/.gccwrap";
141
+ ln -sfn "$(ls $(brew --prefix gcc)/bin/gcc-[0-9]* | sort -V | tail -1)" "$HOME/.gccwrap/gcc";
142
+ ln -sfn "$(ls $(brew --prefix gcc)/bin/g++-[0-9]* | sort -V | tail -1)" "$HOME/.gccwrap/g++" )
143
+ CIBW_REPAIR_WHEEL_COMMAND_MACOS: >
144
+ delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}
145
+ # NOTE: cibuildwheel evaluates CIBW_ENVIRONMENT with its own bashlex
146
+ # evaluator, which does NOT support pipelines inside $(...). The
147
+ # highest-versioned GCC is therefore resolved in CIBW_BEFORE_ALL_MACOS
148
+ # (real bash) and exposed via stable symlinks under $HOME/.gccwrap.
149
+ CIBW_ENVIRONMENT_MACOS: >
150
+ MACOSX_DEPLOYMENT_TARGET="14.0"
151
+ CPATH="$(brew --prefix)/include"
152
+ LIBRARY_PATH="$(brew --prefix)/lib"
153
+ CMAKE_ARGS="-DUSE_SYSTEM_EISKALTDCPP=OFF
154
+ -DOPENSSL_ROOT_DIR=$(brew --prefix openssl@3)
155
+ -DCMAKE_PREFIX_PATH=$(brew --prefix openssl@3);$(brew --prefix bzip2);$(brew --prefix pcre2);$(brew --prefix miniupnpc);$(brew --prefix libidn2);$(brew --prefix lua);$(brew --prefix gettext)
156
+ -DCMAKE_C_COMPILER=$HOME/.gccwrap/gcc
157
+ -DCMAKE_CXX_COMPILER=$HOME/.gccwrap/g++
158
+ -DEISKALTDCPP_SDK_DIR=$HOME/.eiskaltdcpp-sdk/core"
159
+
160
+ # ── Common (applies to Linux) ───────────────────────────
161
+ CIBW_ENVIRONMENT: >
162
+ LD_LIBRARY_PATH="$HOME/.eiskaltdcpp-sdk/core/lib"
163
+ CMAKE_ARGS="-DUSE_SYSTEM_EISKALTDCPP=OFF
164
+ -DEISKALTDCPP_SDK_DIR=$HOME/.eiskaltdcpp-sdk/core"
165
+ # Install the wheel's own test-related extras (fastapi, httpx,
166
+ # bcrypt, pydantic, pytest, ...) so the test suite's imports resolve.
167
+ CIBW_TEST_EXTRAS: "api,test,api-test"
168
+ # pytest's pythonpath=["."] (see pyproject.toml) puts the project
169
+ # root on sys.path so `from tests.test_websocket import ...` resolves
170
+ # on every platform without relying on the working directory.
171
+ CIBW_TEST_COMMAND: >
172
+ python -m pytest {project}/tests/ -v --tb=short
173
+ --ignore={project}/tests/test_integration.py
174
+
175
+ - name: Compute artifact name
176
+ id: artifact
177
+ shell: bash
178
+ run: |
179
+ VERSION=$(grep 'project.*VERSION' CMakeLists.txt | head -1 | sed 's/.*VERSION *\([^ )]*\).*/\1/')
180
+ SHA=$(git rev-parse --short HEAD)
181
+ if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
182
+ echo "name=eiskaltdcpp-py-${VERSION}-${SHA}-${{ matrix.os }}-${{ matrix.arch }}-wheels" >> "$GITHUB_OUTPUT"
183
+ else
184
+ echo "name=eiskaltdcpp-py-${VERSION}~dev-${SHA}-${{ matrix.os }}-${{ matrix.arch }}-wheels" >> "$GITHUB_OUTPUT"
185
+ fi
186
+
187
+ - uses: actions/upload-artifact@v4
188
+ with:
189
+ name: ${{ steps.artifact.outputs.name }}
190
+ path: wheelhouse/*.whl
191
+
192
+ # ─── Build source distribution ──────────────────────────────────
193
+ build-sdist:
194
+ name: Source distribution
195
+ runs-on: ubuntu-24.04
196
+
197
+ steps:
198
+ - uses: actions/checkout@v4
199
+ with:
200
+ submodules: recursive
201
+
202
+ - uses: actions/setup-python@v5
203
+ with:
204
+ python-version: "3.12"
205
+
206
+ - name: Build sdist
207
+ run: python -m pip install build && python -m build --sdist --outdir dist
208
+
209
+ - name: Compute artifact name
210
+ id: artifact
211
+ run: |
212
+ VERSION=$(grep 'project.*VERSION' CMakeLists.txt | head -1 | sed 's/.*VERSION *\([^ )]*\).*/\1/')
213
+ SHA=$(git rev-parse --short HEAD)
214
+ if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
215
+ echo "name=eiskaltdcpp-py-${VERSION}-${SHA}-sdist" >> "$GITHUB_OUTPUT"
216
+ else
217
+ echo "name=eiskaltdcpp-py-${VERSION}~dev-${SHA}-sdist" >> "$GITHUB_OUTPUT"
218
+ fi
219
+
220
+ - uses: actions/upload-artifact@v4
221
+ with:
222
+ name: ${{ steps.artifact.outputs.name }}
223
+ path: dist/*.tar.gz
224
+
225
+ # ─── Publish to PyPI (only on tag push) ─────────────────────────
226
+ publish:
227
+ name: Publish to PyPI
228
+ needs: [build-wheels, build-sdist]
229
+ runs-on: ubuntu-24.04
230
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
231
+
232
+ # PyPI trusted publishing (OIDC) — no API tokens needed
233
+ # Configure at https://pypi.org/manage/project/eiskaltdcpp-py/settings/publishing/
234
+ permissions:
235
+ id-token: write
236
+
237
+ environment:
238
+ name: pypi
239
+ url: https://pypi.org/p/eiskaltdcpp-py
240
+
241
+ steps:
242
+ - uses: actions/download-artifact@v4
243
+ with:
244
+ path: dist
245
+ merge-multiple: true
246
+
247
+ - name: Publish to PyPI
248
+ uses: pypa/gh-action-pypi-publish@release/v1
249
+ with:
250
+ packages-dir: dist
@@ -0,0 +1,38 @@
1
+ # Build
2
+ build/
3
+ build_test/
4
+ _build/
5
+ *.o
6
+ *.so
7
+ *.dylib
8
+ *.a
9
+
10
+ # SWIG generated
11
+ swig/*_wrap.cxx
12
+ swig/*_wrap.cpp
13
+ swig/*.py
14
+ !swig/*.i
15
+
16
+ # SWIG build artifacts symlinked into source tree for dev/poetry installs
17
+ python/eiskaltdcpp/dc_core.py
18
+ python/eiskaltdcpp/_dc_core.so
19
+ python/eiskaltdcpp/_version.py
20
+
21
+ # Python
22
+ __pycache__/
23
+ *.py[cod]
24
+ *.egg-info/
25
+ dist/
26
+ *.egg
27
+
28
+ # IDE
29
+ .vscode/
30
+ .idea/
31
+ *.swp
32
+ *~
33
+
34
+ # OS
35
+ .DS_Store
36
+ Thumbs.db
37
+ .venv/
38
+ FULL_SWIG_WRAP_PLAN.md