mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-21 07:57:22 -06:00
Compare commits
201 Commits
release-4.
...
release-4.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7e6b96493 | ||
|
|
88bf6f11c7 | ||
|
|
90e2236990 | ||
|
|
6ad7cadc4b | ||
|
|
0499111156 | ||
|
|
ae44e59c9a | ||
|
|
1de52f9bcf | ||
|
|
448e55031e | ||
|
|
3b748178c2 | ||
|
|
a4a54ce712 | ||
|
|
d19b524d2d | ||
|
|
1e2bf50e66 | ||
|
|
e7f3409053 | ||
|
|
9758633eeb | ||
|
|
3def5e40c4 | ||
|
|
ca923ed02c | ||
|
|
e4c3bad93a | ||
|
|
3b52c5ce97 | ||
|
|
44b94803a4 | ||
|
|
5d4644c4fc | ||
|
|
a2ef115c66 | ||
|
|
1356f200b8 | ||
|
|
3c68896b1d | ||
|
|
265da50791 | ||
|
|
4037143f4e | ||
|
|
8cae8ad5c5 | ||
|
|
50bd845682 | ||
|
|
ed5aa07526 | ||
|
|
437b51b3a5 | ||
|
|
c2ccc9dfa4 | ||
|
|
b2c7d8211f | ||
|
|
726455ac3e | ||
|
|
ae2bb4efeb | ||
|
|
9971329121 | ||
|
|
d0ec1c4a86 | ||
|
|
9c55600d81 | ||
|
|
b45fb74e01 | ||
|
|
f16c585a77 | ||
|
|
9c664d04ae | ||
|
|
3d0ca83474 | ||
|
|
e713ffb064 | ||
|
|
cf1e61bcf5 | ||
|
|
42b22d6645 | ||
|
|
2d607f8c1a | ||
|
|
69256905c2 | ||
|
|
305316b1fc | ||
|
|
27e222455b | ||
|
|
2b18318e0c | ||
|
|
49cadce253 | ||
|
|
f1b908b95b | ||
|
|
4acfcef8da | ||
|
|
69f2196a22 | ||
|
|
b20a3c5b8e | ||
|
|
2c5271b3b2 | ||
|
|
7696895a88 | ||
|
|
c1ae5d2572 | ||
|
|
0e635c7fdd | ||
|
|
58345e5bbf | ||
|
|
89382d4ec2 | ||
|
|
372f5af36b | ||
|
|
f38736729d | ||
|
|
bf67ef21c6 | ||
|
|
cfd40adcb5 | ||
|
|
8210f9841e | ||
|
|
ae3d17ec01 | ||
|
|
349e958be3 | ||
|
|
42acc75394 | ||
|
|
8b91dcedb0 | ||
|
|
a454a0303d | ||
|
|
789c6de2e8 | ||
|
|
c2fb51159f | ||
|
|
bfb0afe3cf | ||
|
|
26a2d4f24d | ||
|
|
f6e88c8c55 | ||
|
|
51033c212a | ||
|
|
16c858cf61 | ||
|
|
0496543fce | ||
|
|
746e8a7be1 | ||
|
|
6d301ccf55 | ||
|
|
d441b18da0 | ||
|
|
13023ba70a | ||
|
|
ecb7c02d4c | ||
|
|
fd1ac43157 | ||
|
|
c6d4a1f7d4 | ||
|
|
01110690da | ||
|
|
c998c7d38d | ||
|
|
230f98da4a | ||
|
|
c86db0004f | ||
|
|
e645514c8f | ||
|
|
f3c9dbd512 | ||
|
|
ef650293e3 | ||
|
|
05e217537c | ||
|
|
13cb3b5ca1 | ||
|
|
da0b276d5f | ||
|
|
2d73bc9e7d | ||
|
|
fdd54fe568 | ||
|
|
e5ce24e55e | ||
|
|
d90349709b | ||
|
|
adb0fe6582 | ||
|
|
5ed81580c9 | ||
|
|
86d6fb86d7 | ||
|
|
ddec247d4f | ||
|
|
d431ecbe00 | ||
|
|
be929ed88c | ||
|
|
2e1f9bf8be | ||
|
|
7fff393b0e | ||
|
|
a669ec49ad | ||
|
|
1880082017 | ||
|
|
0cbd15890a | ||
|
|
7fe7c6c277 | ||
|
|
e4c177fec7 | ||
|
|
77f4e6c2cf | ||
|
|
4563b11a2e | ||
|
|
cb477f9a29 | ||
|
|
58ac07667e | ||
|
|
74bf3af41c | ||
|
|
9317071122 | ||
|
|
dab32f2090 | ||
|
|
dc464d4d41 | ||
|
|
e7e3f6a9db | ||
|
|
5a1c4e79b3 | ||
|
|
c6d9ab6810 | ||
|
|
d7afad835e | ||
|
|
8608d7b9da | ||
|
|
72970602af | ||
|
|
86579ca87d | ||
|
|
e55582124c | ||
|
|
bd8b06c607 | ||
|
|
230fedf069 | ||
|
|
7bea10f507 | ||
|
|
7cde969b90 | ||
|
|
a3b8f6880b | ||
|
|
ad79fc8d43 | ||
|
|
fb4bf94a56 | ||
|
|
1c184944fd | ||
|
|
ec420f6617 | ||
|
|
d908227619 | ||
|
|
ac8167410b | ||
|
|
26ce187b30 | ||
|
|
2c4e04e537 | ||
|
|
b418f65c2f | ||
|
|
dd3a8d5d56 | ||
|
|
49e54a55df | ||
|
|
8cd0a7ae85 | ||
|
|
442f0df613 | ||
|
|
f9ee5bdb59 | ||
|
|
b9602cc6ab | ||
|
|
abb854a1e6 | ||
|
|
4ee17a73d0 | ||
|
|
faf6e82274 | ||
|
|
c08ec1ac5e | ||
|
|
cd0b6d9a43 | ||
|
|
b8f1142abe | ||
|
|
78859415d6 | ||
|
|
ef92c17192 | ||
|
|
22f3abc4b5 | ||
|
|
a56e6294c1 | ||
|
|
77909e0093 | ||
|
|
2c2bb14b2a | ||
|
|
73c8b77464 | ||
|
|
042238db87 | ||
|
|
6e267f8e81 | ||
|
|
fdc64d9b38 | ||
|
|
0b42425db5 | ||
|
|
e5d7738127 | ||
|
|
422489e2a1 | ||
|
|
7de983b4e5 | ||
|
|
e4e55d2a80 | ||
|
|
926012ce71 | ||
|
|
487eb554c9 | ||
|
|
5a96e1fc7a | ||
|
|
2fe698ee60 | ||
|
|
177ac32a5e | ||
|
|
5f34d1555b | ||
|
|
7cfe68f46c | ||
|
|
f94f4d2391 | ||
|
|
73b18d7ef3 | ||
|
|
817e9c4747 | ||
|
|
28844eff44 | ||
|
|
389664213b | ||
|
|
953b6fd6f8 | ||
|
|
9b4f3fcbf8 | ||
|
|
80743180be | ||
|
|
b2847b2381 | ||
|
|
eb657ec032 | ||
|
|
fc2be601df | ||
|
|
5786c7ff11 | ||
|
|
4a183dd968 | ||
|
|
7c10dba10c | ||
|
|
894446d308 | ||
|
|
47e9c5ac08 | ||
|
|
7f47ac11f1 | ||
|
|
67b17891fa | ||
|
|
dd5b7ba05b | ||
|
|
61aa4d9f1c | ||
|
|
6e924b668e | ||
|
|
618ce33fa0 | ||
|
|
ac413c76b9 | ||
|
|
f266184514 | ||
|
|
8c48bf4a70 | ||
|
|
8bee69c9fc |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
custom: "https://www.qbittorrent.org/donate.php"
|
||||||
38
.github/workflows/ci.yaml
vendored
38
.github/workflows/ci.yaml
vendored
@@ -8,16 +8,13 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [edited, opened, reopened, synchronize]
|
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# Qt: 5.15.0
|
VCPKG_COMMIT: e4ce66eecfd3e5cca5eac06c971921bf8e37cf88
|
||||||
# libtorrent: RC_1_2 HEAD, 1.2.10
|
|
||||||
VCPKG_COMMIT: 32eccc18191fbb57b159784a1724d2d00613ae82
|
|
||||||
VCPKG_DEST_MACOS: /Users/runner/qbt_tools/vcpkg
|
VCPKG_DEST_MACOS: /Users/runner/qbt_tools/vcpkg
|
||||||
VCPKG_DEST_WIN: C:\qbt_tools\vcpkg
|
VCPKG_DEST_WIN: C:\qbt_tools\vcpkg
|
||||||
LIBTORRENT_VERSION_TAG: libtorrent-1.2.10
|
LIBTORRENT_VERSION_TAG: v1.2.12
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@@ -26,7 +23,7 @@ jobs:
|
|||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04, ubuntu-18.04]
|
os: [ubuntu-20.04]
|
||||||
qbt_gui: ["GUI=ON", "GUI=OFF"]
|
qbt_gui: ["GUI=ON", "GUI=OFF"]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
||||||
@@ -72,7 +69,7 @@ jobs:
|
|||||||
- name: upload artifact as zip
|
- name: upload artifact as zip
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: qBittorrent-CI-Ubuntu_${{ matrix.os }}-${{ matrix.qbt_gui }}
|
name: qBittorrent-CI_${{ matrix.os }}-x64_${{ matrix.qbt_gui }}
|
||||||
path: |
|
path: |
|
||||||
build/compile_commands.json
|
build/compile_commands.json
|
||||||
build/target_graph.dot
|
build/target_graph.dot
|
||||||
@@ -125,10 +122,15 @@ jobs:
|
|||||||
"qt5-svg:x64-windows-static-release",
|
"qt5-svg:x64-windows-static-release",
|
||||||
"qt5-tools:x64-windows-static-release",
|
"qt5-tools:x64-windows-static-release",
|
||||||
"qt5-winextras:x64-windows-static-release"
|
"qt5-winextras:x64-windows-static-release"
|
||||||
|
${{ env.RUNVCPKG_VCPKG_ROOT }}/vcpkg.exe upgrade `
|
||||||
|
--overlay-triplets=${{ github.workspace }}/triplets_overlay `
|
||||||
|
--overlay-ports=${{ github.workspace }}/vcpkg `
|
||||||
|
--no-dry-run
|
||||||
foreach($package in $packages)
|
foreach($package in $packages)
|
||||||
{
|
{
|
||||||
${{ env.RUNVCPKG_VCPKG_ROOT }}/vcpkg.exe install $package `
|
${{ env.RUNVCPKG_VCPKG_ROOT }}/vcpkg.exe install $package `
|
||||||
--overlay-triplets=${{ github.workspace }}/triplets_overlay `
|
--overlay-triplets=${{ github.workspace }}/triplets_overlay `
|
||||||
|
--overlay-ports=${{ github.workspace }}/vcpkg `
|
||||||
--clean-after-build
|
--clean-after-build
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +153,7 @@ jobs:
|
|||||||
- name: upload artifact as zip
|
- name: upload artifact as zip
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: qBittorrent-CI-Windows_x64-static-release
|
name: qBittorrent-CI_Windows-x64
|
||||||
path: |
|
path: |
|
||||||
build/compile_commands.json
|
build/compile_commands.json
|
||||||
build/target_graph.dot
|
build/target_graph.dot
|
||||||
@@ -178,11 +180,11 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
# - ninja is needed for building qBittorrent (because it's preferrable, not a hard requirement)
|
# - ninja is needed for building qBittorrent (because it's preferrable, not a hard requirement)
|
||||||
# - pkg-config is needed for some vcpkg installations
|
# - automake is needed for the installation the vcpkg installation of fontconfig, a dependency of qt5-base
|
||||||
- name: install additional required packages with homebrew
|
- name: install additional required packages with homebrew
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
brew install ninja pkg-config
|
brew install automake ninja
|
||||||
|
|
||||||
- name: setup vcpkg (cached, if possible)
|
- name: setup vcpkg (cached, if possible)
|
||||||
uses: lukka/run-vcpkg@v4
|
uses: lukka/run-vcpkg@v4
|
||||||
@@ -197,14 +199,7 @@ jobs:
|
|||||||
Copy-Item ${{ env.RUNVCPKG_VCPKG_ROOT }}/triplets/x64-osx.cmake `
|
Copy-Item ${{ env.RUNVCPKG_VCPKG_ROOT }}/triplets/x64-osx.cmake `
|
||||||
${{ github.workspace }}/triplets_overlay/x64-osx-release.cmake
|
${{ github.workspace }}/triplets_overlay/x64-osx-release.cmake
|
||||||
Add-Content ${{ github.workspace }}/triplets_overlay/x64-osx-release.cmake `
|
Add-Content ${{ github.workspace }}/triplets_overlay/x64-osx-release.cmake `
|
||||||
-Value "set(VCPKG_BUILD_TYPE release)"
|
-Value "set(VCPKG_BUILD_TYPE release)","set(VCPKG_OSX_DEPLOYMENT_TARGET 10.15)"
|
||||||
|
|
||||||
# NOTE: Avoids a libtorrent ABI issue. See https://github.com/arvidn/libtorrent/issues/4965
|
|
||||||
- name: force AppleClang to compile libtorrent with C++14
|
|
||||||
run: |
|
|
||||||
(Get-Content -path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake).Replace( `
|
|
||||||
'${FEATURE_OPTIONS}', '${FEATURE_OPTIONS} -DCMAKE_CXX_STANDARD=14') `
|
|
||||||
| Set-Content -Path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake
|
|
||||||
|
|
||||||
- name: install dependencies via vcpkg
|
- name: install dependencies via vcpkg
|
||||||
run: |
|
run: |
|
||||||
@@ -215,10 +210,15 @@ jobs:
|
|||||||
"qt5-svg:x64-osx-release",
|
"qt5-svg:x64-osx-release",
|
||||||
"qt5-tools:x64-osx-release",
|
"qt5-tools:x64-osx-release",
|
||||||
"qt5-macextras:x64-osx-release"
|
"qt5-macextras:x64-osx-release"
|
||||||
|
${{ env.RUNVCPKG_VCPKG_ROOT }}/vcpkg upgrade `
|
||||||
|
--overlay-triplets=${{ github.workspace }}/triplets_overlay `
|
||||||
|
--overlay-ports=${{ github.workspace }}/vcpkg `
|
||||||
|
--no-dry-run
|
||||||
foreach($package in $packages)
|
foreach($package in $packages)
|
||||||
{
|
{
|
||||||
${{ env.RUNVCPKG_VCPKG_ROOT }}/vcpkg install $package `
|
${{ env.RUNVCPKG_VCPKG_ROOT }}/vcpkg install $package `
|
||||||
--overlay-triplets=${{ github.workspace }}/triplets_overlay `
|
--overlay-triplets=${{ github.workspace }}/triplets_overlay `
|
||||||
|
--overlay-ports=${{ github.workspace }}/vcpkg `
|
||||||
--clean-after-build
|
--clean-after-build
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ jobs:
|
|||||||
- name: upload artifact as zip
|
- name: upload artifact as zip
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: qBittorrent-CI-macOS_x64-static-release_${{ matrix.qbt_gui }}
|
name: qBittorrent-CI_macOS_${{ matrix.qbt_gui }}
|
||||||
path: |
|
path: |
|
||||||
build/compile_commands.json
|
build/compile_commands.json
|
||||||
build/target_graph.dot
|
build/target_graph.dot
|
||||||
|
|||||||
36
.github/workflows/file_health.sh
vendored
36
.github/workflows/file_health.sh
vendored
@@ -12,62 +12,72 @@ regressions=0
|
|||||||
exclusions_nonutf8='(.*(7z|gif|ic(ns|o)|png|qm|zip))'
|
exclusions_nonutf8='(.*(7z|gif|ic(ns|o)|png|qm|zip))'
|
||||||
exclusions_bom='src/base/unicodestrings.h'
|
exclusions_bom='src/base/unicodestrings.h'
|
||||||
exclusions_tw='(*.ts)|src/webui/www/private/scripts/lib/mootools-1.2-more.js'
|
exclusions_tw='(*.ts)|src/webui/www/private/scripts/lib/mootools-1.2-more.js'
|
||||||
|
exclusions_trailing_newline='configure'
|
||||||
exclusions_no_lf='(*.ts)|(.*svg)|compile_commands.json|src/webui/www/private/scripts/lib/mootools-1.2-(core-yc.js|more.js)'
|
exclusions_no_lf='(*.ts)|(.*svg)|compile_commands.json|src/webui/www/private/scripts/lib/mootools-1.2-(core-yc.js|more.js)'
|
||||||
|
|
||||||
echo -e "*** Detect files not encoded in UTF-8 ***\n"
|
echo -e "\n*** Detect files not encoded in UTF-8 ***\n"
|
||||||
|
|
||||||
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
|
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
|
||||||
| grep -v -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
|
| grep -v -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
|
||||||
| grep -E -v -e "${exclusions_nonutf8}" \
|
| grep -E -v -e "${exclusions_nonutf8}" \
|
||||||
| tee >(echo -e "\n--> Files not encoded in UTF-8: found" "$(wc -l < /dev/stdin)" "regression(s)") \
|
| tee >(echo -e "--> Files not encoded in UTF-8: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
|
||||||
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
||||||
regressions=$((regressions+$?))
|
regressions=$((regressions+$?))
|
||||||
|
|
||||||
echo -e "*** Detect files encoded in UTF-8 with BOM ***\n"
|
echo -e "\n*** Detect files encoded in UTF-8 with BOM ***\n"
|
||||||
|
|
||||||
grep --exclude-dir={.git,build} -rIl $'\xEF\xBB\xBF' | sort \
|
grep --exclude-dir={.git,build} -rIl $'\xEF\xBB\xBF' | sort \
|
||||||
| grep -E -v -e "${exclusions_bom}" \
|
| grep -E -v -e "${exclusions_bom}" \
|
||||||
| tee >(echo -e "\n--> Files encoded in UTF-8 with BOM: found" "$(wc -l < /dev/stdin)" "regression(s)") \
|
| tee >(echo -e "--> Files encoded in UTF-8 with BOM: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
|
||||||
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
||||||
regressions=$((regressions+$?))
|
regressions=$((regressions+$?))
|
||||||
|
|
||||||
echo -e "*** Detect usage of CR byte ***\n"
|
echo -e "\n*** Detect usage of CR byte ***\n"
|
||||||
|
|
||||||
grep --exclude-dir={.git,build} -rIlU $'\x0D' | sort \
|
grep --exclude-dir={.git,build} -rIlU $'\x0D' | sort \
|
||||||
| tee >(echo -e "\n--> Usage of CR byte: found" "$(wc -l < /dev/stdin)" "regression(s)") \
|
| tee >(echo -e "--> Usage of CR byte: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
|
||||||
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
||||||
regressions=$((regressions+$?))
|
regressions=$((regressions+$?))
|
||||||
|
|
||||||
echo -e "*** Detect trailing whitespace in lines ***\n"
|
echo -e "\n*** Detect trailing whitespace in lines ***\n"
|
||||||
|
|
||||||
grep --exclude-dir={.git,build} -rIl "[[:blank:]]$" | sort \
|
grep --exclude-dir={.git,build} -rIl "[[:blank:]]$" | sort \
|
||||||
| grep -E -v -e "${exclusions_tw}" \
|
| grep -E -v -e "${exclusions_tw}" \
|
||||||
| tee >(echo -e "\n--> Trailing whitespace in lines: found" "$(wc -l < /dev/stdin)" "regression(s)") \
|
| tee >(echo -e "--> Trailing whitespace in lines: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
|
||||||
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0';
|
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0';
|
||||||
regressions=$((regressions+$?))
|
regressions=$((regressions+$?))
|
||||||
|
|
||||||
echo -e "*** Detect too many trailing newlines ***\n"
|
echo -e "\n*** Detect too many trailing newlines ***\n"
|
||||||
|
|
||||||
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
|
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
|
||||||
| grep -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
|
| grep -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
|
||||||
|
| grep -E -v -e "${exclusions_trailing_newline}" \
|
||||||
| xargs -L1 -I my_input bash -c 'test "$(tail -q -c2 "my_input" | hexdump -C | grep "0a 0a")" && echo "my_input"' \
|
| xargs -L1 -I my_input bash -c 'test "$(tail -q -c2 "my_input" | hexdump -C | grep "0a 0a")" && echo "my_input"' \
|
||||||
| tee >(echo -e "\n--> Too many trailing newlines: found" "$(wc -l < /dev/stdin)" "regression(s)") \
|
| tee >(echo -e "--> Too many trailing newlines: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
|
||||||
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
||||||
regressions=$((regressions+$?))
|
regressions=$((regressions+$?))
|
||||||
|
|
||||||
echo -e "*** Detect no trailing newline ***\n"
|
echo -e "\n*** Detect no trailing newline ***\n"
|
||||||
|
|
||||||
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
|
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
|
||||||
| grep -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
|
| grep -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
|
||||||
| grep -E -v -e "${exclusions_no_lf}" \
|
| grep -E -v -e "${exclusions_no_lf}" \
|
||||||
| xargs -L1 -I my_input bash -c 'test "$(tail -q -c1 "my_input" | hexdump -C | grep "0a")" || echo "my_input"' \
|
| xargs -L1 -I my_input bash -c 'test "$(tail -q -c1 "my_input" | hexdump -C | grep "0a")" || echo "my_input"' \
|
||||||
| tee >(echo -e "\n--> No trailing newline: found" "$(wc -l < /dev/stdin)" "regression(s)") \
|
| tee >(echo -e "--> No trailing newline: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
|
||||||
|
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
||||||
|
regressions=$((regressions+$?))
|
||||||
|
|
||||||
|
echo -e "\n*** Detect translation closing tag in new line ***\n"
|
||||||
|
|
||||||
|
grep --exclude-dir={.git,build} -nri "^</translation>" | sort \
|
||||||
|
| cut -d ":" -f 1,2 \
|
||||||
|
| tee >(echo -e "--> Translation closing tag in new line: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
|
||||||
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
||||||
regressions=$((regressions+$?))
|
regressions=$((regressions+$?))
|
||||||
|
|
||||||
if [ "$regressions" -ne 0 ]; then
|
if [ "$regressions" -ne 0 ]; then
|
||||||
regressions=1
|
regressions=1
|
||||||
echo "File health regressions found. Please fix them (or add them as exclusions)."
|
echo "\nFile health regressions found. Please fix them (or add them as exclusions)."
|
||||||
else
|
else
|
||||||
echo "All OK, no file health regressions found."
|
echo "All OK, no file health regressions found."
|
||||||
fi
|
fi
|
||||||
|
|||||||
9
.github/workflows/file_health.yaml
vendored
9
.github/workflows/file_health.yaml
vendored
@@ -1,17 +1,12 @@
|
|||||||
name: GitHub Actions file health check
|
name: GitHub Actions file health check
|
||||||
|
|
||||||
on:
|
on: [pull_request, push]
|
||||||
push:
|
|
||||||
branches: [ '**' ]
|
|
||||||
pull_request:
|
|
||||||
types: [edited, opened, reopened, synchronize]
|
|
||||||
branches: [ '**' ]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check_file_health:
|
check_file_health:
|
||||||
name: Check file health
|
name: Check file health
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@ src/qbittorrent
|
|||||||
src/qbittorrent-nox
|
src/qbittorrent-nox
|
||||||
src/release
|
src/release
|
||||||
src/debug
|
src/debug
|
||||||
|
src/base/version.h
|
||||||
CMakeLists.txt.user*
|
CMakeLists.txt.user*
|
||||||
qbittorrent.pro.user*
|
qbittorrent.pro.user*
|
||||||
conf.pri
|
conf.pri
|
||||||
|
|||||||
51
.travis.yml
51
.travis.yml
@@ -4,7 +4,8 @@ os:
|
|||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
|
|
||||||
dist: bionic
|
dist: focal
|
||||||
|
osx_image: xcode12.2
|
||||||
|
|
||||||
env:
|
env:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -16,6 +17,11 @@ env:
|
|||||||
- secure: "OI9CUjj4lTb0HwwIZU5PbECU3hLlAL6KC8KsbwohG8/O3j5fLcnmDsK4Ad9us5cC39sS11Jcd1kDP2qRcCuST/glVNhLkcjKkiQerOfd5nQ/qL4JYfz/1mfP5mdpz9jHKzpLUIG+TXkbSTjP6VVmsb5KPT+3pKEdRFZB+Pu9+J8="
|
- secure: "OI9CUjj4lTb0HwwIZU5PbECU3hLlAL6KC8KsbwohG8/O3j5fLcnmDsK4Ad9us5cC39sS11Jcd1kDP2qRcCuST/glVNhLkcjKkiQerOfd5nQ/qL4JYfz/1mfP5mdpz9jHKzpLUIG+TXkbSTjP6VVmsb5KPT+3pKEdRFZB+Pu9+J8="
|
||||||
- coverity_branch: coverity_scan
|
- coverity_branch: coverity_scan
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- env: libt_branch=RC_2_0 gui=true build_system=qmake
|
||||||
|
os: linux
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email:
|
email:
|
||||||
on_success: change
|
on_success: change
|
||||||
@@ -39,8 +45,7 @@ addons:
|
|||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
# sources list: https://github.com/travis-ci/apt-source-safelist/blob/master/ubuntu.json
|
# sources list: https://github.com/travis-ci/apt-source-safelist/blob/master/ubuntu.json
|
||||||
- sourceline: 'ppa:qbittorrent-team/qbt-libtorrent-travisci'
|
- sourceline: 'deb https://apt.kitware.com/ubuntu/ focal main'
|
||||||
- sourceline: 'deb https://apt.kitware.com/ubuntu/ bionic main'
|
|
||||||
key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc'
|
key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc'
|
||||||
packages:
|
packages:
|
||||||
# packages list: https://github.com/travis-ci/apt-package-safelist/blob/master/ubuntu-trusty
|
# packages list: https://github.com/travis-ci/apt-package-safelist/blob/master/ubuntu-trusty
|
||||||
@@ -69,6 +74,8 @@ before_install:
|
|||||||
# TravisCI installs its own cmake to another location which ovverides other installations
|
# TravisCI installs its own cmake to another location which ovverides other installations
|
||||||
# if they don't call the new binary directly
|
# if they don't call the new binary directly
|
||||||
alias cmake="/usr/bin/cmake"
|
alias cmake="/usr/bin/cmake"
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib"
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||||
@@ -99,8 +106,8 @@ install:
|
|||||||
|
|
||||||
brew update > /dev/null
|
brew update > /dev/null
|
||||||
brew upgrade cmake
|
brew upgrade cmake
|
||||||
brew install ccache colormake boost openssl qt zlib
|
brew install ccache colormake boost openssl qt@5 zlib
|
||||||
brew link --force qt zlib
|
brew link --force qt@5 zlib
|
||||||
|
|
||||||
if [ "$build_system" = "cmake" ]; then
|
if [ "$build_system" = "cmake" ]; then
|
||||||
sudo ln -s /usr/local/opt/qt/mkspecs /usr/local/mkspecs
|
sudo ln -s /usr/local/opt/qt/mkspecs /usr/local/mkspecs
|
||||||
@@ -114,20 +121,34 @@ install:
|
|||||||
ccache -V && ccache --show-stats && ccache --zero-stats
|
ccache -V && ccache --show-stats && ccache --zero-stats
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
if [ "$libt_branch" = "RC_1_2" ] && [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
if [ "$libt_branch" = "RC_1_2" ]; then
|
||||||
# Will install latest 1.2.x daily build from the PPA
|
|
||||||
sudo apt-get -y install libtorrent-rasterbar-dev
|
|
||||||
fi
|
|
||||||
- |
|
|
||||||
if [ "$libt_branch" = "RC_1_2" ] && [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
|
||||||
# building libtorrent manually should be faster than using the official bottle
|
|
||||||
# because the bottle will also pull in a lot of updated dependencies and prolong the overall time
|
|
||||||
pushd "$HOME"
|
pushd "$HOME"
|
||||||
git clone --single-branch --branch RC_1_2 https://github.com/arvidn/libtorrent.git
|
git clone --single-branch --branch RC_1_2 https://github.com/arvidn/libtorrent.git
|
||||||
cd libtorrent
|
cd libtorrent
|
||||||
git checkout tags/v1.2.10
|
git checkout tags/v1.2.12
|
||||||
|
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=14 -Ddeprecated-functions=OFF -DOPENSSL_ROOT_DIR="$openssl_root_path" ./
|
cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
|
-Ddeprecated-functions=OFF \
|
||||||
|
-DOPENSSL_ROOT_DIR="$openssl_root_path" \
|
||||||
|
./
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
popd
|
||||||
|
elif [ "$libt_branch" = "RC_2_0" ]; then
|
||||||
|
pushd "$HOME"
|
||||||
|
git clone --single-branch --branch RC_2_0 https://github.com/arvidn/libtorrent.git
|
||||||
|
cd libtorrent
|
||||||
|
git checkout tags/v2.0.2
|
||||||
|
git submodule update --init --recursive
|
||||||
|
|
||||||
|
cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
|
-Ddeprecated-functions=OFF \
|
||||||
|
-DOPENSSL_ROOT_DIR="$openssl_root_path" \
|
||||||
|
./
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
popd
|
popd
|
||||||
|
|||||||
2
AUTHORS
2
AUTHORS
@@ -119,7 +119,7 @@ Translations authors:
|
|||||||
- German: Niels Hoffmann (zentralmaschine@users.sourceforge.net)
|
- German: Niels Hoffmann (zentralmaschine@users.sourceforge.net)
|
||||||
- Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net), Stephanos Antaris (santaris@csd.auth.gr), sledgehammer999(hammered999@gmail.com) and Γιάννης Ανθυμίδης Evropi(Transifex)
|
- Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net), Stephanos Antaris (santaris@csd.auth.gr), sledgehammer999(hammered999@gmail.com) and Γιάννης Ανθυμίδης Evropi(Transifex)
|
||||||
- Hebrew: David Deutsch (d.deffo@gmail.com)
|
- Hebrew: David Deutsch (d.deffo@gmail.com)
|
||||||
- Hungarian: Majoros Péter (majoros.j.p@t-online.hu)
|
- Hungarian: Majoros Péter
|
||||||
- Italian: bovirus (bovirus@live.it) and Matteo Sechi (bu17714@gmail.com)
|
- Italian: bovirus (bovirus@live.it) and Matteo Sechi (bu17714@gmail.com)
|
||||||
- Japanese: Masato Hashimoto (cabezon.hashimoto@gmail.com)
|
- Japanese: Masato Hashimoto (cabezon.hashimoto@gmail.com)
|
||||||
- Korean: Jin Woo Sin (jin828sin@users.sourceforge.net)
|
- Korean: Jin Woo Sin (jin828sin@users.sourceforge.net)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.16 FATAL_ERROR) # Policies <= CMP0097 default t
|
|||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
||||||
|
|
||||||
project(qBittorrent
|
project(qBittorrent
|
||||||
VERSION 4.3.1.0
|
|
||||||
DESCRIPTION "The qBittorrent BitTorrent client"
|
DESCRIPTION "The qBittorrent BitTorrent client"
|
||||||
HOMEPAGE_URL "https://www.qbittorrent.org/"
|
HOMEPAGE_URL "https://www.qbittorrent.org/"
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
@@ -11,14 +10,15 @@ project(qBittorrent
|
|||||||
|
|
||||||
# use CONFIG mode first in find_package
|
# use CONFIG mode first in find_package
|
||||||
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
|
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
|
||||||
# version requirements
|
# version requirements - older vesions may work, but you are on your own
|
||||||
set(requiredBoostVersion 1.40)
|
set(minBoostVersion 1.65)
|
||||||
set(requiredQtVersion 5.9.0)
|
set(minQtVersion 5.12)
|
||||||
set(requiredOpenSSLVersion 1.0)
|
set(minOpenSSLVersion 1.1.1)
|
||||||
set(requiredLibtorrentVersion 1.2.0)
|
set(minLibtorrentVersion 1.2.12)
|
||||||
set(requiredZlibVersion 1.2.5.2)
|
set(minZlibVersion 1.2.11)
|
||||||
|
|
||||||
# features (some are platform-specific)
|
# features (some are platform-specific)
|
||||||
|
include(CheckCXXSourceCompiles) # TODO: migrate to CheckSourceCompiles in CMake >= 3.19
|
||||||
include(FeatureSummary)
|
include(FeatureSummary)
|
||||||
include(FeatureOptionsSetup)
|
include(FeatureOptionsSetup)
|
||||||
feature_option(STACKTRACE "Enable stacktraces" ON)
|
feature_option(STACKTRACE "Enable stacktraces" ON)
|
||||||
@@ -34,12 +34,22 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|||||||
"Install systemd service file to a directory manually overridable with Systemd_SERVICES_INSTALL_DIR"
|
"Install systemd service file to a directory manually overridable with Systemd_SERVICES_INSTALL_DIR"
|
||||||
OFF "NOT GUI" OFF
|
OFF "NOT GUI" OFF
|
||||||
)
|
)
|
||||||
|
if (STACKTRACE)
|
||||||
|
check_cxx_source_compiles(
|
||||||
|
"#include <execinfo.h>
|
||||||
|
int main(){return 0;}"
|
||||||
|
QBITTORRENT_HAS_EXECINFO_H
|
||||||
|
)
|
||||||
|
if (NOT QBITTORRENT_HAS_EXECINFO_H)
|
||||||
|
message(FATAL_ERROR "execinfo.h header file not found.\n"
|
||||||
|
"Please either disable the STACKTRACE feature or use a libc that has this header file, such as glibc (GNU libc)."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
elseif (MSVC)
|
elseif (MSVC)
|
||||||
feature_option(MSVC_RUNTIME_DYNAMIC "Use MSVC dynamic runtime library (-MD) instead of static (-MT)" ON)
|
feature_option(MSVC_RUNTIME_DYNAMIC "Use MSVC dynamic runtime library (-MD) instead of static (-MT)" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(QBT_VER_STATUS "alpha1" CACHE STRING "Project status version. Should be empty for release builds.")
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(dist)
|
add_subdirectory(dist)
|
||||||
@@ -49,3 +59,6 @@ if (VERBOSE_CONFIGURE)
|
|||||||
else()
|
else()
|
||||||
feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
|
feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Generate version header
|
||||||
|
configure_file("src/base/version.h.in" "${CMAKE_CURRENT_SOURCE_DIR}/src/base/version.h" @ONLY)
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ Example:
|
|||||||
|
|
||||||
## 8. Include guard
|
## 8. Include guard
|
||||||
|
|
||||||
`#pragma once` should be used instead of "include guard" in new code:
|
`#pragma once` must be used instead of a "classic include guard":
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
// examplewidget.h
|
// examplewidget.h
|
||||||
|
|||||||
84
Changelog
84
Changelog
@@ -1,3 +1,87 @@
|
|||||||
|
Tue Mar 23 2021 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.4
|
||||||
|
- FEATURE: Add ability to prioritize selected items by shown file order (Chocobo1)
|
||||||
|
- FEATURE: Allow tab to escape the text box in "Edit trackers" dialog (Christoph Rackwitz)
|
||||||
|
- FEATURE: Support sub-sorting in Transferlist (jagannatharjun)
|
||||||
|
- FEATURE: Expose ToS setting from libtorrent (Chocobo1)
|
||||||
|
- FEATURE: Improve tracker entries handling (glassez)
|
||||||
|
- BUGFIX: Drop extension from generated content folder name (glassez)
|
||||||
|
- BUGFIX: Change qBittorrent Updater window title (xavier2k6)
|
||||||
|
- BUGFIX: Validate HTTPS Tracker Certificate by default (an0n666)
|
||||||
|
- BUGFIX: Don't let "program update" dialog steal focus (Chocobo1)
|
||||||
|
- BUGFIX: Disable expand on double click in TorrentContentTreeView (jagannatharjun)
|
||||||
|
- BUGFIX: Add hyperlink to Transifex on translator list (Si Yong Kim)
|
||||||
|
- BUGFIX: Enlarge "speed limit" icon slightly (Chocobo1)
|
||||||
|
- BUGFIX: Don't prevent system sleep due to errored torrents (dyumin)
|
||||||
|
- BUGFIX: Use stable sorting in transfer list (Chocobo1)
|
||||||
|
- BUGFIX: Allow "missing files" torrents to save more resume data (glassez)
|
||||||
|
- BUGFIX: Restart "missing files" torrents after changing location (glassez)
|
||||||
|
- BUGFIX: Show proper string when torrent availability is not available (Chocobo1)
|
||||||
|
- BUGFIX: Apply "Hide zero/infinity values" to "Time Active", "Down/Up Limit" and ETA columns (Chocobo1)
|
||||||
|
- BUGFIX: Fix potential out-of-bounds access (Chocobo1)
|
||||||
|
- BUGFIX: Make SpeedPlotView averager time aware (jagannatharjun)
|
||||||
|
- BUGFIX: Add a 3-Hour graph (jagannatharjun)
|
||||||
|
- BUGFIX: Add an option to disable icons in menus (always disabled on MacOS) (Michał Kopeć)
|
||||||
|
- BUGFIX: Improve detection of filename extension of audio/video files (Chocobo1)
|
||||||
|
- BUGFIX: Various drawing improvements of progress bar (Chocobo1)
|
||||||
|
- BUGFIX: Properly stop torrent creation if aborted (Chocobo1)
|
||||||
|
- BUGFIX: Replace external program parameters in one step (Chocobo1)
|
||||||
|
- BUGFIX: Improve "save resume data" handling (glassez)
|
||||||
|
- BUGFIX: Fix bad IPv6 address format for outgoingInterfaces (treysis)
|
||||||
|
- WEBUI: Properly decode strings (brvphoenix)
|
||||||
|
- WEBUI: Accept "share limits" when adding torrent using WebAPI (glassez)
|
||||||
|
- WEBUI: Add seeding time to the active time column (thalieht)
|
||||||
|
- WEBUI: Fix incorrect seeding time string in General tab (thalieht)
|
||||||
|
- WEBUI: Allow >100 days in WebUI function "friendlyDuration" (thalieht)
|
||||||
|
- WEBUI: Avoid decoding strings repeatedly (brvphoenix)
|
||||||
|
- RSS: Add category button on AutomatedRSSDownloader on GUI (Si Yong Kim)
|
||||||
|
- WINDOWS: NSIS: Update Czech translation (slrslr)
|
||||||
|
- WINDOWS: NSIS: Update Portuguese BR translation (Alex)
|
||||||
|
- WINDOWS: NSIS: Add Estonian translation (PriitUring)
|
||||||
|
- WINDOWS: Allow change-case-only file renaming (glassez)
|
||||||
|
- LINUX: Systemd: wait for mounting of local filesystems (Juraj Oršulić)
|
||||||
|
- OTHER: Raise minimum libtorrent version to 1.2.12 (glassez)
|
||||||
|
- OTHER: Raise minimum Qt version to 5.12 (glassez)
|
||||||
|
|
||||||
|
Tue Jan 19 2021 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.3
|
||||||
|
- FEATURE: New languages: Azerbaijani, Estonian
|
||||||
|
- BUGFIX: Unify global speed dialogs for normal/alternative speeds (thalieht)
|
||||||
|
- BUGFIX: Increase maximum global speed limits ~2 GiB/s (thalieht)
|
||||||
|
- BUGFIX: Save fastresume when setting torrent speed limits (thalieht)
|
||||||
|
- BUGFIX: Group several torrent options into one dialog (thalieht)
|
||||||
|
- BUGFIX: Capitalize locale names (Chocobo1)
|
||||||
|
- BUGFIX: Improve content file/folder names handling (glassez)
|
||||||
|
- BUGFIX: Drop notification about move storage finished or failed (glassez)
|
||||||
|
- BUGFIX: Reload "missing files" torrent instead of re-checking (glassez)
|
||||||
|
- BUGFIX: Remember dialog sizes (Chocobo1)
|
||||||
|
- BUGFIX: Improve detection of file extension string (Chocobo1)
|
||||||
|
- WEBUI: Don't call non-existent elements (glassez)
|
||||||
|
- WEBUI: Update "Keep top-level folder" in WebUI options (thalieht)
|
||||||
|
- MACOS: QMake: Raise minimal macOS target version to 10.14 (glassez)
|
||||||
|
- LINUX: Use legacy 'data' directory only as a fallback (lbilli)
|
||||||
|
- OTHER: Bump project requirement to C++17 (Chocobo1)
|
||||||
|
|
||||||
|
Sun Dec 27 2020 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.2
|
||||||
|
- FEATURE: Allow to add root folder to torrent content (glassez)
|
||||||
|
- FEATURE: "HTTPS tracker validation" option is available on all platforms with latest libtorrent (Chocobo1)
|
||||||
|
- FEATURE: Option for supporting internationalized domain names (IDNs) (Chocobo1)
|
||||||
|
- BUGFIX: Fix broken sorting on some columns (Chocobo1)
|
||||||
|
- BUGFIX: Fix availability per file value (Chocobo1)
|
||||||
|
- BUGFIX: Fix status of torrents without metadata (sledgehammer999)
|
||||||
|
- BUGFIX: Don't try to remove folders for a torrent without metadata (sledgehammer999)
|
||||||
|
- BUGFIX: Lift upper limit of "Max concurrent HTTP announces" option (Chocobo1)
|
||||||
|
- BUGFIX: Add links to libtorrent documentation (Chocobo1)
|
||||||
|
- BUGFIX: Move "embedded tracker" options to qbt section (Chocobo1)
|
||||||
|
- BUGFIX: Properly handle "Append extension" option changing (glassez)
|
||||||
|
- BUGFIX: Correctly save paused torrent state (glassez)
|
||||||
|
- BUGFIX: Fix bug of "move storage job" can be performed multiple times (glassez)
|
||||||
|
- WEBUI: Add ability to use 'shift+delete' to delete torrents (Chocobo1)
|
||||||
|
- WEBUI: Allow to attach tags while adding torrents (Jesse Chan)
|
||||||
|
- WEBUI: Bump version to 2.6.2 (Jesse Chan)
|
||||||
|
- WEBUI: Remove unnecessary restriction on input length (Chocobo1)
|
||||||
|
- WINDOWS: NSIS: Update Russian translation (Andrei Stepanov)
|
||||||
|
- WINDOWS: NSIS: Update Italian translation (Alessandro Simonelli)
|
||||||
|
- OTHER: Drop support for building with libtorrent < 1.2.11 (Vladimir Golovnev)
|
||||||
|
|
||||||
Wed Nov 25 2020 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.1
|
Wed Nov 25 2020 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.1
|
||||||
- FEATURE: Allow progress bar styling from custom themes (jagannatharjun)
|
- FEATURE: Allow progress bar styling from custom themes (jagannatharjun)
|
||||||
- FEATURE: Allow adding torrents using "Paste" key sequence (Chocobo1)
|
- FEATURE: Allow adding torrents using "Paste" key sequence (Chocobo1)
|
||||||
|
|||||||
16
INSTALL
16
INSTALL
@@ -3,23 +3,27 @@ qBittorrent - A BitTorrent client in C++ / Qt
|
|||||||
|
|
||||||
1) Install these dependencies:
|
1) Install these dependencies:
|
||||||
|
|
||||||
- Boost >= 1.40
|
- Boost >= 1.65
|
||||||
|
|
||||||
- libtorrent-rasterbar >= 1.2 (by Arvid Norberg)
|
- libtorrent-rasterbar >= 1.2.12 (by Arvid Norberg)
|
||||||
* https://www.libtorrent.org/
|
* https://www.libtorrent.org/
|
||||||
* Be careful: another library (the one used by rTorrent) uses a similar name
|
* Be careful: another library (the one used by rTorrent) uses a similar name
|
||||||
|
|
||||||
- OpenSSL >= 1.0
|
- OpenSSL >= 1.1.1
|
||||||
|
|
||||||
- Qt >= 5.9.0
|
- Qt >= 5.12
|
||||||
|
|
||||||
- zlib >= 1.2.5.2
|
- zlib >= 1.2.11
|
||||||
|
|
||||||
- pkg-config (compile-time only)
|
- pkg-config (compile-time only on *nix systems)
|
||||||
|
|
||||||
- Python >= 3.5.0 (optional, runtime only)
|
- Python >= 3.5.0 (optional, runtime only)
|
||||||
* Required by the internal search engine
|
* Required by the internal search engine
|
||||||
|
|
||||||
|
Dependency version numbers are bumped every once in a while to keep the range of properly tested configurations manageable, even if not strictly required to build.
|
||||||
|
You may be able to build with older versions of (some of) the dependencies other than the minimum versions specified in the build scripts, but support for such builds is not provided - you are on your own.
|
||||||
|
Please ensure you are building with an officially supported configuration when reporting bugs.
|
||||||
|
|
||||||
2a) Compile and install qBittorrent with Qt graphical interface
|
2a) Compile and install qBittorrent with Qt graphical interface
|
||||||
|
|
||||||
$ ./configure
|
$ ./configure
|
||||||
|
|||||||
19
build_dist.sh
Executable file
19
build_dist.sh
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# get version numbers
|
||||||
|
versionSrc="src/base/version.h.in"
|
||||||
|
versionMajor="$(grep -Po '(?<=QBT_VERSION_MAJOR )\d+' "$versionSrc")"
|
||||||
|
versionMinor="$(grep -Po '(?<=QBT_VERSION_MINOR )\d+' "$versionSrc")"
|
||||||
|
versionBugfix="$(grep -Po '(?<=QBT_VERSION_BUGFIX )\d+' "$versionSrc")"
|
||||||
|
versionBuild="$(grep -Po '(?<=QBT_VERSION_BUILD )\d+' "$versionSrc")"
|
||||||
|
versionStatus="$(grep -Po '(?<=QBT_VERSION_STATUS ")\w+' "$versionSrc")"
|
||||||
|
|
||||||
|
if [ "$versionBuild" != "0" ]; then
|
||||||
|
projectVersion="$versionMajor.$versionMinor.$versionBugfix.$versionBuild$versionStatus"
|
||||||
|
else
|
||||||
|
projectVersion="$versionMajor.$versionMinor.$versionBugfix$versionStatus"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# pack archives
|
||||||
|
git archive --format=tar --prefix="qbittorrent-$projectVersion/" HEAD | gzip -9 > "qbittorrent-$projectVersion.tar.gz"
|
||||||
|
git archive --format=tar --prefix="qbittorrent-$projectVersion/" HEAD | xz -9 > "qbittorrent-$projectVersion.tar.xz"
|
||||||
@@ -7,47 +7,16 @@ macro(qbt_common_config)
|
|||||||
# treat value specified by the CXX_STANDARD target property as a requirement by default
|
# treat value specified by the CXX_STANDARD target property as a requirement by default
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# these definitions are only needed for calls to
|
|
||||||
# lt::generate_fingerprint and for the qbittorrent.rc file on Windows
|
|
||||||
add_library(qbt_version_definitions INTERFACE)
|
|
||||||
|
|
||||||
target_compile_definitions(qbt_version_definitions INTERFACE
|
|
||||||
QBT_VERSION_MAJOR=${qBittorrent_VERSION_MAJOR}
|
|
||||||
QBT_VERSION_MINOR=${qBittorrent_VERSION_MINOR}
|
|
||||||
QBT_VERSION_BUGFIX=${qBittorrent_VERSION_PATCH}
|
|
||||||
QBT_VERSION_BUILD=${qBittorrent_VERSION_TWEAK}
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(qbt_common_cfg INTERFACE)
|
add_library(qbt_common_cfg INTERFACE)
|
||||||
|
|
||||||
# Full C++ 14 support is required
|
# Full C++ 17 support is required
|
||||||
# See also https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
|
# See also https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
|
||||||
# for a breakdown of the features that CMake recognizes for each C++ standard
|
# for a breakdown of the features that CMake recognizes for each C++ standard
|
||||||
target_compile_features(qbt_common_cfg INTERFACE
|
target_compile_features(qbt_common_cfg INTERFACE
|
||||||
cxx_std_14
|
cxx_std_17
|
||||||
cxx_aggregate_default_initializers
|
|
||||||
cxx_attribute_deprecated
|
|
||||||
cxx_binary_literals
|
|
||||||
cxx_contextual_conversions
|
|
||||||
cxx_decltype_auto
|
|
||||||
cxx_digit_separators
|
|
||||||
cxx_generic_lambdas
|
|
||||||
cxx_lambda_init_captures
|
|
||||||
cxx_relaxed_constexpr
|
|
||||||
cxx_return_type_deduction
|
|
||||||
cxx_variable_templates
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(QBT_PROJECT_VERSION "${qBittorrent_VERSION_MAJOR}.${qBittorrent_VERSION_MINOR}.${qBittorrent_VERSION_PATCH}")
|
|
||||||
if (NOT ${qBittorrent_VERSION_TWEAK} EQUAL 0)
|
|
||||||
set(QBT_PROJECT_VERSION "${QBT_PROJECT_VERSION}.${qBittorrent_VERSION_TWEAK}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(QBT_FULL_VERSION "${QBT_PROJECT_VERSION}${QBT_VER_STATUS}")
|
|
||||||
|
|
||||||
target_compile_definitions(qbt_common_cfg INTERFACE
|
target_compile_definitions(qbt_common_cfg INTERFACE
|
||||||
QBT_VERSION="v${QBT_FULL_VERSION}"
|
|
||||||
QBT_VERSION_2="${QBT_FULL_VERSION}"
|
|
||||||
QT_DEPRECATED_WARNINGS
|
QT_DEPRECATED_WARNINGS
|
||||||
QT_NO_CAST_TO_ASCII
|
QT_NO_CAST_TO_ASCII
|
||||||
QT_NO_CAST_FROM_BYTEARRAY
|
QT_NO_CAST_FROM_BYTEARRAY
|
||||||
@@ -90,6 +59,12 @@ macro(qbt_common_config)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if ((CXX_COMPILER_ID STREQUAL "Clang") OR (CXX_COMPILER_ID STREQUAL "AppleClang"))
|
||||||
|
target_compile_options(qbt_common_cfg INTERFACE
|
||||||
|
-Wno-range-loop-analysis
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
target_link_options(qbt_common_cfg INTERFACE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:LINKER:--dynamicbase>)
|
target_link_options(qbt_common_cfg INTERFACE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:LINKER:--dynamicbase>)
|
||||||
endif()
|
endif()
|
||||||
@@ -101,8 +76,12 @@ macro(qbt_common_config)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(qbt_common_cfg INTERFACE /guard:cf)
|
target_compile_options(qbt_common_cfg INTERFACE
|
||||||
target_link_options(qbt_common_cfg INTERFACE /guard:cf
|
/guard:cf
|
||||||
|
/utf-8
|
||||||
|
)
|
||||||
|
target_link_options(qbt_common_cfg INTERFACE
|
||||||
|
/guard:cf
|
||||||
$<$<NOT:$<CONFIG:Debug>>:/OPT:REF /OPT:ICF>
|
$<$<NOT:$<CONFIG:Debug>>:/OPT:REF /OPT:ICF>
|
||||||
# suppress linking warning due to /INCREMENTAL and /OPT:ICF being both ON
|
# suppress linking warning due to /INCREMENTAL and /OPT:ICF being both ON
|
||||||
$<$<CONFIG:RelWithDebInfo>:/INCREMENTAL:NO>
|
$<$<CONFIG:RelWithDebInfo>:/INCREMENTAL:NO>
|
||||||
|
|||||||
56
configure.ac
56
configure.ac
@@ -1,6 +1,8 @@
|
|||||||
AC_INIT([qbittorrent], [v4.3.1], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
|
AC_INIT([qbittorrent], [v4.3.4], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
: ${CFLAGS=""}
|
||||||
|
: ${CXXFLAGS=""}
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AC_PROG_SED
|
AC_PROG_SED
|
||||||
@@ -139,7 +141,7 @@ AS_IF([test "x$QT_QMAKE" = "x"],
|
|||||||
[AC_MSG_ERROR([Could not find qmake])
|
[AC_MSG_ERROR([Could not find qmake])
|
||||||
])
|
])
|
||||||
AS_IF([test "x$enable_gui" = "xyes"],
|
AS_IF([test "x$enable_gui" = "xyes"],
|
||||||
[PKG_CHECK_MODULES(Qt5Svg, [Qt5Svg >= 5.5.1])
|
[PKG_CHECK_MODULES(Qt5Svg, [Qt5Svg >= 5.12])
|
||||||
])
|
])
|
||||||
AC_MSG_CHECKING([whether QtDBus should be enabled])
|
AC_MSG_CHECKING([whether QtDBus should be enabled])
|
||||||
AS_CASE(["x$enable_qt_dbus"],
|
AS_CASE(["x$enable_qt_dbus"],
|
||||||
@@ -157,7 +159,7 @@ AS_CASE(["x$enable_qt_dbus"],
|
|||||||
AC_MSG_ERROR([Unknown option "$enable_qt_dbus". Use either "yes" or "no".])])
|
AC_MSG_ERROR([Unknown option "$enable_qt_dbus". Use either "yes" or "no".])])
|
||||||
|
|
||||||
|
|
||||||
AX_BOOST_BASE([1.40],
|
AX_BOOST_BASE([1.65],
|
||||||
[AC_MSG_NOTICE([Boost CXXFLAGS: "$BOOST_CPPFLAGS"])
|
[AC_MSG_NOTICE([Boost CXXFLAGS: "$BOOST_CPPFLAGS"])
|
||||||
AC_MSG_NOTICE([Boost LDFLAGS: "$BOOST_LDFLAGS"])],
|
AC_MSG_NOTICE([Boost LDFLAGS: "$BOOST_LDFLAGS"])],
|
||||||
[AC_MSG_ERROR([Could not find Boost])])
|
[AC_MSG_ERROR([Could not find Boost])])
|
||||||
@@ -178,48 +180,48 @@ AC_MSG_NOTICE([Boost.System LIB: "$BOOST_SYSTEM_LIB"])
|
|||||||
LIBS="$BOOST_SYSTEM_LIB $LIBS"
|
LIBS="$BOOST_SYSTEM_LIB $LIBS"
|
||||||
|
|
||||||
PKG_CHECK_MODULES(libtorrent,
|
PKG_CHECK_MODULES(libtorrent,
|
||||||
[libtorrent-rasterbar >= 1.2],
|
[libtorrent-rasterbar >= 1.2.12],
|
||||||
[CXXFLAGS="$libtorrent_CFLAGS $CXXFLAGS"
|
[CXXFLAGS="$libtorrent_CFLAGS $CXXFLAGS"
|
||||||
LIBS="$libtorrent_LIBS $LIBS"])
|
LIBS="$libtorrent_LIBS $LIBS"])
|
||||||
|
|
||||||
PKG_CHECK_MODULES(openssl,
|
PKG_CHECK_MODULES(openssl,
|
||||||
[openssl >= 1.0],
|
[openssl >= 1.1.1],
|
||||||
[CXXFLAGS="$openssl_CFLAGS $CXXFLAGS"
|
[CXXFLAGS="$openssl_CFLAGS $CXXFLAGS"
|
||||||
LIBS="$openssl_LIBS $LIBS"])
|
LIBS="$openssl_LIBS $LIBS"])
|
||||||
|
|
||||||
PKG_CHECK_MODULES(zlib,
|
PKG_CHECK_MODULES(zlib,
|
||||||
[zlib >= 1.2.5.2],
|
[zlib >= 1.2.11],
|
||||||
[CXXFLAGS="$zlib_CFLAGS $CXXFLAGS"
|
[CXXFLAGS="$zlib_CFLAGS $CXXFLAGS"
|
||||||
LIBS="$zlib_LIBS $LIBS"])
|
LIBS="$zlib_LIBS $LIBS"])
|
||||||
|
|
||||||
# Check if already in >= C++14 mode because of the flags returned by one of the above packages
|
# Check if already in >= C++17 mode because of the flags returned by one of the above packages
|
||||||
TMP_CXXFLAGS="$CXXFLAGS"
|
TMP_CXXFLAGS="$CXXFLAGS"
|
||||||
CXXFLAGS=""
|
CXXFLAGS=""
|
||||||
AC_MSG_CHECKING([if compiler defaults to C++14 or later mode])
|
AC_MSG_CHECKING([if compiler defaults to C++17 or later mode])
|
||||||
AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()],
|
AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()],
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
QBT_CXX14_FOUND="yes"],
|
QBT_CXX17_FOUND="yes"],
|
||||||
[AC_MSG_RESULT([no])
|
[AC_MSG_RESULT([no])
|
||||||
QBT_CXX14_FOUND="no"])
|
QBT_CXX17_FOUND="no"])
|
||||||
|
|
||||||
# In case of no, check if the compiler can support at least C++14
|
# In case of no, check if the compiler can support at least C++17
|
||||||
# and if yes, enable it leaving a warning to the user
|
# and if yes, enable it leaving a warning to the user
|
||||||
AS_IF([test "x$QBT_CXX14_FOUND" = "xno"],
|
AS_IF([test "x$QBT_CXX17_FOUND" = "xno"],
|
||||||
[AC_MSG_CHECKING([if compiler supports C++14])
|
[AC_MSG_CHECKING([if compiler supports C++17])
|
||||||
CXXFLAGS="-std=c++14"
|
CXXFLAGS="-std=c++17"
|
||||||
AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()],
|
AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()],
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
AC_MSG_CHECKING([if C++14 is disabled by the set compiler flags])
|
AC_MSG_CHECKING([if C++17 is disabled by the set compiler flags])
|
||||||
# prepend the flag so it won't override conflicting user defined flags
|
# prepend the flag so it won't override conflicting user defined flags
|
||||||
CXXFLAGS="-std=c++14 $TMP_CXXFLAGS"
|
CXXFLAGS="-std=c++17 $TMP_CXXFLAGS"
|
||||||
AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()],
|
AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()],
|
||||||
[AC_MSG_RESULT([no])
|
[AC_MSG_RESULT([no])
|
||||||
QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++14"
|
QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++1z"
|
||||||
AC_MSG_WARN([C++14 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors.])],
|
AC_MSG_WARN([C++17 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors.])],
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
AC_MSG_ERROR([The compiler supports C++14 but the user or a dependency has explicitly enabled a lower mode.])])],
|
AC_MSG_ERROR([The compiler supports C++17 but the user or a dependency has explicitly enabled a lower mode.])])],
|
||||||
[AC_MSG_RESULT([no])
|
[AC_MSG_RESULT([no])
|
||||||
AC_MSG_ERROR([A compiler supporting C++14 is required.])])
|
AC_MSG_ERROR([A compiler supporting C++17 is required.])])
|
||||||
])
|
])
|
||||||
CXXFLAGS="$TMP_CXXFLAGS"
|
CXXFLAGS="$TMP_CXXFLAGS"
|
||||||
|
|
||||||
@@ -270,9 +272,13 @@ AC_SUBST(QBT_REMOVE_CONFIG)
|
|||||||
AC_SUBST(QBT_ADD_DEFINES)
|
AC_SUBST(QBT_ADD_DEFINES)
|
||||||
AC_SUBST(QBT_REMOVE_DEFINES)
|
AC_SUBST(QBT_REMOVE_DEFINES)
|
||||||
|
|
||||||
AC_OUTPUT(conf.pri)
|
QBT_CONFIG_FILES="conf.pri"
|
||||||
|
|
||||||
AS_IF([test "x$enable_systemd" = "xyes"],
|
AS_IF([test "x$enable_systemd" = "xyes"],
|
||||||
[AC_OUTPUT(dist/unix/systemd/qbittorrent-nox@.service)])
|
[QBT_CONFIG_FILES="$QBT_CONFIG_FILES dist/unix/systemd/qbittorrent-nox@.service"])
|
||||||
|
|
||||||
|
AC_CONFIG_FILES(["$QBT_CONFIG_FILES"])
|
||||||
|
AC_OUTPUT
|
||||||
|
|
||||||
AC_MSG_NOTICE([Running qmake to generate the makefile...])
|
AC_MSG_NOTICE([Running qmake to generate the makefile...])
|
||||||
TOPDIR="$(cd "$(dirname "$0")" && pwd)"
|
TOPDIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|||||||
4
dist/mac/Info.plist
vendored
4
dist/mac/Info.plist
vendored
@@ -55,7 +55,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>4.3.0</string>
|
<string>4.3.4</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>@EXECUTABLE@</string>
|
<string>@EXECUTABLE@</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
<key>NSAppleScriptEnabled</key>
|
<key>NSAppleScriptEnabled</key>
|
||||||
<string>YES</string>
|
<string>YES</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2006-2020 The qBittorrent project</string>
|
<string>Copyright © 2006-2021 The qBittorrent project</string>
|
||||||
<key>UTExportedTypeDeclarations</key>
|
<key>UTExportedTypeDeclarations</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
|
|||||||
@@ -74,6 +74,6 @@
|
|||||||
<url type="translate">https://github.com/qbittorrent/qBittorrent/wiki/How-to-translate-qBittorrent</url>
|
<url type="translate">https://github.com/qbittorrent/qBittorrent/wiki/How-to-translate-qBittorrent</url>
|
||||||
<content_rating type="oars-1.1"/>
|
<content_rating type="oars-1.1"/>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="4.3.1" date="2020-11-25"/>
|
<release version="4.3.4" date="2021-03-23"/>
|
||||||
</releases>
|
</releases>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
42
dist/unix/org.qbittorrent.qBittorrent.desktop
vendored
42
dist/unix/org.qbittorrent.qBittorrent.desktop
vendored
@@ -11,6 +11,11 @@ Type=Application
|
|||||||
StartupNotify=false
|
StartupNotify=false
|
||||||
StartupWMClass=qbittorrent
|
StartupWMClass=qbittorrent
|
||||||
Keywords=bittorrent;torrent;magnet;download;p2p;
|
Keywords=bittorrent;torrent;magnet;download;p2p;
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
|
# Translations
|
||||||
Comment[oc]=Telecargar e partejar de fichièrs amb BitTorrent
|
Comment[oc]=Telecargar e partejar de fichièrs amb BitTorrent
|
||||||
GenericName[oc]=Client BitTorrent
|
GenericName[oc]=Client BitTorrent
|
||||||
Name[oc]=qBittorrent
|
Name[oc]=qBittorrent
|
||||||
@@ -53,6 +58,9 @@ Name[en_GB]=qBittorrent
|
|||||||
Comment[es]=Descargue y comparta archivos por BitTorrent
|
Comment[es]=Descargue y comparta archivos por BitTorrent
|
||||||
GenericName[es]=Cliente BitTorrent
|
GenericName[es]=Cliente BitTorrent
|
||||||
Name[es]=qBittorrent
|
Name[es]=qBittorrent
|
||||||
|
Comment[et]=Lae alla ja jaga faile üle BitTorrenti
|
||||||
|
GenericName[et]=BitTorrent klient
|
||||||
|
Name[et]=qBittorrent
|
||||||
Comment[eu]=Jeitsi eta elkarbanatu agiriak BitTorrent bidez
|
Comment[eu]=Jeitsi eta elkarbanatu agiriak BitTorrent bidez
|
||||||
GenericName[eu]=BitTorrent bezeroa
|
GenericName[eu]=BitTorrent bezeroa
|
||||||
Name[eu]=qBittorrent
|
Name[eu]=qBittorrent
|
||||||
@@ -80,13 +88,16 @@ Name[hr]=qBittorrent
|
|||||||
Comment[hu]=Fájlok letöltése és megosztása a BitTorrent hálózaton keresztül
|
Comment[hu]=Fájlok letöltése és megosztása a BitTorrent hálózaton keresztül
|
||||||
GenericName[hu]=BitTorrent kliens
|
GenericName[hu]=BitTorrent kliens
|
||||||
Name[hu]=qBittorrent
|
Name[hu]=qBittorrent
|
||||||
|
Comment[hy]=Նիշքերի փոխանցում BitTorrent-ի միջոցով
|
||||||
|
GenericName[hy]=BitTorrent սպասառու
|
||||||
|
Name[hy]=qBittorrent
|
||||||
Comment[id]=Unduh dan berbagi berkas melalui BitTorrent
|
Comment[id]=Unduh dan berbagi berkas melalui BitTorrent
|
||||||
GenericName[id]=Klien BitTorrent
|
GenericName[id]=Klien BitTorrent
|
||||||
Name[id]=qBittorrent
|
Name[id]=qBittorrent
|
||||||
Comment[is]=Sækja og deila skrám yfir BitTorrent
|
Comment[is]=Sækja og deila skrám yfir BitTorrent
|
||||||
GenericName[is]=BitTorrent biðlarar
|
GenericName[is]=BitTorrent biðlarar
|
||||||
Name[is]=qBittorrent
|
Name[is]=qBittorrent
|
||||||
Comment[it]=Client BitTorrent per il download di file via internet
|
Comment[it]=Scarica e condividi file tramite BitTorrent
|
||||||
GenericName[it]=Client BitTorrent
|
GenericName[it]=Client BitTorrent
|
||||||
Name[it]=qBittorrent
|
Name[it]=qBittorrent
|
||||||
Comment[ja]=BitTorrent でファイルをダウンロードおよび共有します
|
Comment[ja]=BitTorrent でファイルをダウンロードおよび共有します
|
||||||
@@ -95,8 +106,8 @@ Name[ja]=qBittorrent
|
|||||||
Comment[ka]=ჩამოტვირთე და გააზიარე ფაილები Bittorrent-ის საშუალებით
|
Comment[ka]=ჩამოტვირთე და გააზიარე ფაილები Bittorrent-ის საშუალებით
|
||||||
GenericName[ka]=BitTorrent კლიენტი
|
GenericName[ka]=BitTorrent კლიენტი
|
||||||
Name[ka]=qBittorrent
|
Name[ka]=qBittorrent
|
||||||
Comment[ko]=비트토런트를 통해 파일을 받고 공유합니다
|
Comment[ko]=비트토렌트를 통해 파일을 받고 공유합니다
|
||||||
GenericName[ko]=비트토런트 클라이언트
|
GenericName[ko]=비트토렌트 클라이언트
|
||||||
Name[ko]=qBittorrent
|
Name[ko]=qBittorrent
|
||||||
Comment[zh]=通过 BitTorrent 下载和分享文件
|
Comment[zh]=通过 BitTorrent 下载和分享文件
|
||||||
GenericName[zh]=BitTorrent 客户端
|
GenericName[zh]=BitTorrent 客户端
|
||||||
@@ -107,6 +118,9 @@ Name[lt]=qBittorrent
|
|||||||
Comment[mk]=Превземајте и споделувајте фајлови преку BitTorrent
|
Comment[mk]=Превземајте и споделувајте фајлови преку BitTorrent
|
||||||
GenericName[mk]=BitTorrent клиент
|
GenericName[mk]=BitTorrent клиент
|
||||||
Name[mk]=qBittorrent
|
Name[mk]=qBittorrent
|
||||||
|
Comment[en_AU]=Download and share files over BitTorrent
|
||||||
|
GenericName[en_AU]=BitTorrent client
|
||||||
|
Name[en_AU]=qBittorrent
|
||||||
Comment[nb]=Last ned og del filer over BitTorrent
|
Comment[nb]=Last ned og del filer over BitTorrent
|
||||||
GenericName[nb]=BitTorrent-klient
|
GenericName[nb]=BitTorrent-klient
|
||||||
Name[nb]=qBittorrent
|
Name[nb]=qBittorrent
|
||||||
@@ -137,6 +151,7 @@ Name[sk]=qBittorrent
|
|||||||
Comment[sl]=Prenesite in delite datoteke preko BitTorrenta
|
Comment[sl]=Prenesite in delite datoteke preko BitTorrenta
|
||||||
GenericName[sl]=BitTorrent odjemalec
|
GenericName[sl]=BitTorrent odjemalec
|
||||||
Name[sl]=qBittorrent
|
Name[sl]=qBittorrent
|
||||||
|
Comment[sr]=Преузимајте и делите фајлове преко BitTorrent протокола
|
||||||
GenericName[sr]=BitTorrent-клијент
|
GenericName[sr]=BitTorrent-клијент
|
||||||
Comment[sr@latin]=Preuzimanje i deljenje fajlova preko BitTorrent-a
|
Comment[sr@latin]=Preuzimanje i deljenje fajlova preko BitTorrent-a
|
||||||
GenericName[sr@latin]=BitTorrent klijent
|
GenericName[sr@latin]=BitTorrent klijent
|
||||||
@@ -150,9 +165,9 @@ Name[uz@Latn]=qBittorrent
|
|||||||
Comment[ltg]=Atsasyuteit i daleit failus ar BitTorrent
|
Comment[ltg]=Atsasyuteit i daleit failus ar BitTorrent
|
||||||
GenericName[ltg]=BitTorrent klients
|
GenericName[ltg]=BitTorrent klients
|
||||||
Name[ltg]=qBittorrent
|
Name[ltg]=qBittorrent
|
||||||
Comment[hi_IN]= अपनी फाइलें BitTorrent के माध्यम से डाउनलोड आैर साॅझा करें
|
Comment[hi_IN]=बिटटौरेंट द्वारा फाइल डाउनलोड व सहभाजन
|
||||||
GenericName[hi_IN]=BitTorrent उपभोक्ता
|
GenericName[hi_IN]=बिटटौरेंट साधन
|
||||||
Name[hi_IN]=qBittorrent
|
Name[hi_IN]=क्यूबिटटौरेंट
|
||||||
Comment[tr]=Dosyaları BitTorrent üzerinden indirin ve paylaşın
|
Comment[tr]=Dosyaları BitTorrent üzerinden indirin ve paylaşın
|
||||||
GenericName[tr]=BitTorrent istemcisi
|
GenericName[tr]=BitTorrent istemcisi
|
||||||
Name[tr]=qBittorrent
|
Name[tr]=qBittorrent
|
||||||
@@ -165,6 +180,9 @@ Name[uk]=qBittorrent
|
|||||||
Comment[vi]=Tải về và chia sẻ các tập tin thông qua BitTorrent
|
Comment[vi]=Tải về và chia sẻ các tập tin thông qua BitTorrent
|
||||||
GenericName[vi]=Máy trạm dạng BitTorrent
|
GenericName[vi]=Máy trạm dạng BitTorrent
|
||||||
Name[vi]=qBittorrent
|
Name[vi]=qBittorrent
|
||||||
|
Comment[az@latin]=Faylları BitTorrent vasitəsilə göndərin və paylaşın
|
||||||
|
GenericName[az@latin]=BitTorrent client
|
||||||
|
Name[az@latin]=qBittorrent
|
||||||
Comment[zh_HK]=經由BitTorrent下載並分享檔案
|
Comment[zh_HK]=經由BitTorrent下載並分享檔案
|
||||||
GenericName[zh_HK]=BitTorrent用戶端
|
GenericName[zh_HK]=BitTorrent用戶端
|
||||||
Name[zh_HK]=qBittorrent
|
Name[zh_HK]=qBittorrent
|
||||||
@@ -180,8 +198,8 @@ Name[ms_MY]=qBittorrent
|
|||||||
Comment[eo]=Elŝutu kaj kunhavigu dosierojn per BitTorrent
|
Comment[eo]=Elŝutu kaj kunhavigu dosierojn per BitTorrent
|
||||||
GenericName[eo]=BitTorrent-kliento
|
GenericName[eo]=BitTorrent-kliento
|
||||||
Name[eo]=qBittorrent
|
Name[eo]=qBittorrent
|
||||||
Comment[mn_MN]=BitTorrent ашиглан файлуудыг татаж түгээх
|
Comment[mn_MN]=BitTorrent-оор файлуудаа тат, түгээ
|
||||||
GenericName[mn_MN]=BitTorrent үйлчлүүлэгч
|
GenericName[mn_MN]=BitTorrent татагч
|
||||||
Name[mn_MN]=qBittorrent
|
Name[mn_MN]=qBittorrent
|
||||||
Comment[ta]=BitTorrent வழியாக கோப்புகளை பதிவிறக்க மற்றும் பகிர
|
Comment[ta]=BitTorrent வழியாக கோப்புகளை பதிவிறக்க மற்றும் பகிர
|
||||||
GenericName[ta]=BitTorrent வாடிக்கையாளர்
|
GenericName[ta]=BitTorrent வாடிக்கையாளர்
|
||||||
@@ -192,9 +210,9 @@ Name[ne_NP]=qBittorrent
|
|||||||
Comment[te]=క్యు బిట్ టొరెంట్ తో ఫైల్స్ దిగుమతి చేసుకోండి , పంచుకోండి
|
Comment[te]=క్యు బిట్ టొరెంట్ తో ఫైల్స్ దిగుమతి చేసుకోండి , పంచుకోండి
|
||||||
GenericName[te]=క్యు బిట్ టొరెంట్ క్లయింట్
|
GenericName[te]=క్యు బిట్ టొరెంట్ క్లయింట్
|
||||||
Name[te]=క్యు బిట్ టొరెంట్
|
Name[te]=క్యు బిట్ టొరెంట్
|
||||||
Comment[en_AU]=Download and share files over BitTorrent
|
Comment[pt_PT]=Transferir e partilhar ficheiros por BitTorrent
|
||||||
GenericName[en_AU]=BitTorrent client
|
GenericName[pt_PT]=Cliente BitTorrent
|
||||||
Name[en_AU]=qBittorrent
|
Name[pt_PT]=qBittorrent
|
||||||
Comment[th]=ดาว์นโหลดและแชร์ไฟล์ด้วยบิททอเร้น
|
Comment[th]=ดาวน์โหลดและแชร์ไฟล์ด้วยบิททอเร้น
|
||||||
GenericName[th]=โปรแกรมบิททอเร้น
|
GenericName[th]=โปรแกรมบิททอเร้น
|
||||||
Name[th]=qBittorrent
|
Name[th]=qBittorrent
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
Description=qBittorrent-nox service for user %I
|
Description=qBittorrent-nox service for user %I
|
||||||
Documentation=man:qbittorrent-nox(1)
|
Documentation=man:qbittorrent-nox(1)
|
||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
After=network-online.target nss-lookup.target
|
After=local-fs.target network-online.target nss-lookup.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ LangString inst_dekstop ${LANG_CZECH} "Vytvořit zástupce na ploše"
|
|||||||
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
||||||
LangString inst_startmenu ${LANG_CZECH} "Vytvořit zástupce v nabídce Start"
|
LangString inst_startmenu ${LANG_CZECH} "Vytvořit zástupce v nabídce Start"
|
||||||
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
|
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
|
||||||
LangString inst_startup ${LANG_CZECH} "Spusťte aplikaci qBittorrent ve Windows"
|
LangString inst_startup ${LANG_CZECH} "Spustit qBittorrent při startu Windows"
|
||||||
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
||||||
LangString inst_torrent ${LANG_CZECH} "Otevírat .torrent soubory pomocí qBittorrent"
|
LangString inst_torrent ${LANG_CZECH} "Otevírat .torrent soubory pomocí qBittorrent"
|
||||||
;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent"
|
;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent"
|
||||||
@@ -15,9 +15,9 @@ LangString inst_magnet ${LANG_CZECH} "Otevírat odkazy Magnet pomocí qBittorren
|
|||||||
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
||||||
LangString inst_firewall ${LANG_CZECH} "Vytvořit pravidlo ve Windows Firewall"
|
LangString inst_firewall ${LANG_CZECH} "Vytvořit pravidlo ve Windows Firewall"
|
||||||
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
||||||
LangString inst_pathlimit ${LANG_CZECH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
LangString inst_pathlimit ${LANG_CZECH} "Vypnout MAX_PATH limit 260 znaků pro cesty (vyžaduje Windows 10 1607 a novější)"
|
||||||
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
||||||
LangString inst_firewallinfo ${LANG_CZECH} "Vytváření pravidla ve Windows Firewall"
|
LangString inst_firewallinfo ${LANG_CZECH} "Přidávání pravidla do Windows Firewall"
|
||||||
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
||||||
LangString inst_warning ${LANG_CZECH} "qBittorrent je spuštěn. Před instalací aplikaci ukončete, prosím."
|
LangString inst_warning ${LANG_CZECH} "qBittorrent je spuštěn. Před instalací aplikaci ukončete, prosím."
|
||||||
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
|
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
|
||||||
|
|||||||
52
dist/windows/installer-translations/estonian.nsi
vendored
52
dist/windows/installer-translations/estonian.nsi
vendored
@@ -1,59 +1,59 @@
|
|||||||
;Installer strings
|
;Installer strings
|
||||||
|
|
||||||
;LangString inst_qbt_req ${LANG_ENGLISH} "qBittorrent (required)"
|
;LangString inst_qbt_req ${LANG_ENGLISH} "qBittorrent (required)"
|
||||||
LangString inst_qbt_req ${LANG_ESTONIAN} "qBittorrent (required)"
|
LangString inst_qbt_req ${LANG_ESTONIAN} "qBittorrent (vajalik)"
|
||||||
;LangString inst_dekstop ${LANG_ENGLISH} "Create Desktop Shortcut"
|
;LangString inst_dekstop ${LANG_ENGLISH} "Create Desktop Shortcut"
|
||||||
LangString inst_dekstop ${LANG_ESTONIAN} "Create Desktop Shortcut"
|
LangString inst_dekstop ${LANG_ESTONIAN} "Loo Töölaua Otsetee"
|
||||||
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
||||||
LangString inst_startmenu ${LANG_ESTONIAN} "Create Start Menu Shortcut"
|
LangString inst_startmenu ${LANG_ESTONIAN} "Loo Start Menüü Otsetee"
|
||||||
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
|
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
|
||||||
LangString inst_startup ${LANG_ESTONIAN} "Start qBittorrent on Windows start up"
|
LangString inst_startup ${LANG_ESTONIAN} "Käivita qBittorrent Windowsi käivitamisel"
|
||||||
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
||||||
LangString inst_torrent ${LANG_ESTONIAN} "Open .torrent files with qBittorrent"
|
LangString inst_torrent ${LANG_ESTONIAN} "Ava .torrent failid qBittorrentiga"
|
||||||
;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent"
|
;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent"
|
||||||
LangString inst_magnet ${LANG_ESTONIAN} "Open magnet links with qBittorrent"
|
LangString inst_magnet ${LANG_ESTONIAN} "Ava magnet lingid qBittorrentiga"
|
||||||
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
||||||
LangString inst_firewall ${LANG_ESTONIAN} "Add Windows Firewall rule"
|
LangString inst_firewall ${LANG_ESTONIAN} "Lisa reegel Windowsi Tulemüüri"
|
||||||
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
||||||
LangString inst_pathlimit ${LANG_ESTONIAN} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
LangString inst_pathlimit ${LANG_ESTONIAN} "Keela Windowsi kaustade pikkuse limiit (260 karakterit MAX_PATH limiit, vajalik Windows 10 1607 või uuemat)"
|
||||||
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
||||||
LangString inst_firewallinfo ${LANG_ESTONIAN} "Adding Windows Firewall rule"
|
LangString inst_firewallinfo ${LANG_ESTONIAN} "Lisatakse Windowsi Tulemüüri reegel"
|
||||||
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
||||||
LangString inst_warning ${LANG_ESTONIAN} "qBittorrent is running. Please close the application before installing."
|
LangString inst_warning ${LANG_ESTONIAN} "qBittorrent töötab. Palun sulge see programm, enne installi."
|
||||||
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
|
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
|
||||||
LangString inst_uninstall_question ${LANG_ESTONIAN} "Current version will be uninstalled. User settings and torrents will remain intact."
|
LangString inst_uninstall_question ${LANG_ESTONIAN} "Praegune versioon uninstallitakse. Kasutaja sätted ja torrenti failid jäetakse alles."
|
||||||
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
||||||
LangString inst_unist ${LANG_ESTONIAN} "Uninstalling previous version."
|
LangString inst_unist ${LANG_ESTONIAN} "Uninstallitakse eelmist versiooni."
|
||||||
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
||||||
LangString launch_qbt ${LANG_ESTONIAN} "Launch qBittorrent."
|
LangString launch_qbt ${LANG_ESTONIAN} "Käivita qBittorrent."
|
||||||
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
|
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
|
||||||
LangString inst_requires_64bit ${LANG_ESTONIAN} "This installer works only in 64-bit Windows versions."
|
LangString inst_requires_64bit ${LANG_ESTONIAN} "See installer töötab ainult 64-bit Windowsi versioonides."
|
||||||
;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7."
|
;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7."
|
||||||
LangString inst_requires_win7 ${LANG_ESTONIAN} "This qBittorrent version requires at least Windows 7."
|
LangString inst_requires_win7 ${LANG_ESTONIAN} "Selle qBittorrenti versiooni jaoks on vajalik vähemalt Windows 7."
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------
|
;------------------------------------
|
||||||
;Uninstaller strings
|
;Uninstaller strings
|
||||||
|
|
||||||
;LangString remove_files ${LANG_ENGLISH} "Remove files"
|
;LangString remove_files ${LANG_ENGLISH} "Remove files"
|
||||||
LangString remove_files ${LANG_ESTONIAN} "Remove files"
|
LangString remove_files ${LANG_ESTONIAN} "Eemalda failid"
|
||||||
;LangString remove_shortcuts ${LANG_ENGLISH} "Remove shortcuts"
|
;LangString remove_shortcuts ${LANG_ENGLISH} "Remove shortcuts"
|
||||||
LangString remove_shortcuts ${LANG_ESTONIAN} "Remove shortcuts"
|
LangString remove_shortcuts ${LANG_ESTONIAN} "Eemalda otseteed"
|
||||||
;LangString remove_associations ${LANG_ENGLISH} "Remove file associations"
|
;LangString remove_associations ${LANG_ENGLISH} "Remove file associations"
|
||||||
LangString remove_associations ${LANG_ESTONIAN} "Remove file associations"
|
LangString remove_associations ${LANG_ESTONIAN} "Eemalda failide seotus"
|
||||||
;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys"
|
;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys"
|
||||||
LangString remove_registry ${LANG_ESTONIAN} "Remove registry keys"
|
LangString remove_registry ${LANG_ESTONIAN} "Eemalda registri võtmed"
|
||||||
;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files"
|
;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files"
|
||||||
LangString remove_conf ${LANG_ESTONIAN} "Remove configuration files"
|
LangString remove_conf ${LANG_ESTONIAN} "Eemalda seadistuste failid"
|
||||||
;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule"
|
;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule"
|
||||||
LangString remove_firewall ${LANG_ESTONIAN} "Remove Windows Firewall rule"
|
LangString remove_firewall ${LANG_ESTONIAN} "Eemalda Windowsi Tulemüüri reegel"
|
||||||
;LangString remove_firewallinfo ${LANG_ENGLISH} "Removing Windows Firewall rule"
|
;LangString remove_firewallinfo ${LANG_ENGLISH} "Removing Windows Firewall rule"
|
||||||
LangString remove_firewallinfo ${LANG_ESTONIAN} "Removing Windows Firewall rule"
|
LangString remove_firewallinfo ${LANG_ESTONIAN} "Eemaldatakse Windowsi Tulemüüri reegel"
|
||||||
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
|
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
|
||||||
LangString remove_cache ${LANG_ESTONIAN} "Remove torrents and cached data"
|
LangString remove_cache ${LANG_ESTONIAN} "Eemalda torrentid ja ajutised andmed"
|
||||||
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
|
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
|
||||||
LangString uninst_warning ${LANG_ESTONIAN} "qBittorrent is running. Please close the application before uninstalling."
|
LangString uninst_warning ${LANG_ESTONIAN} "qBittorrent töötab. Palun sulge programm, enne uninstallimist."
|
||||||
;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:"
|
;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:"
|
||||||
LangString uninst_tor_warn ${LANG_ESTONIAN} "Not removing .torrent association. It is associated with:"
|
LangString uninst_tor_warn ${LANG_ESTONIAN} "Ei eemaldata .torrent seotust. Mis on seotud:"
|
||||||
;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:"
|
;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:"
|
||||||
LangString uninst_mag_warn ${LANG_ESTONIAN} "Not removing magnet association. It is associated with:"
|
LangString uninst_mag_warn ${LANG_ESTONIAN} "Ei eemaldata magnetitega seotust. Mis on seotud:"
|
||||||
|
|||||||
20
dist/windows/installer-translations/italian.nsi
vendored
20
dist/windows/installer-translations/italian.nsi
vendored
@@ -3,9 +3,9 @@
|
|||||||
;LangString inst_qbt_req ${LANG_ENGLISH} "qBittorrent (required)"
|
;LangString inst_qbt_req ${LANG_ENGLISH} "qBittorrent (required)"
|
||||||
LangString inst_qbt_req ${LANG_ITALIAN} "qBittorrent (necessario)"
|
LangString inst_qbt_req ${LANG_ITALIAN} "qBittorrent (necessario)"
|
||||||
;LangString inst_dekstop ${LANG_ENGLISH} "Create Desktop Shortcut"
|
;LangString inst_dekstop ${LANG_ENGLISH} "Create Desktop Shortcut"
|
||||||
LangString inst_dekstop ${LANG_ITALIAN} "Crea icone sul desktop"
|
LangString inst_dekstop ${LANG_ITALIAN} "Crea collegamento sul Desktop"
|
||||||
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
||||||
LangString inst_startmenu ${LANG_ITALIAN} "Crea gruppo programmi"
|
LangString inst_startmenu ${LANG_ITALIAN} "Aggiungi al menu Start"
|
||||||
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
|
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
|
||||||
LangString inst_startup ${LANG_ITALIAN} "Esegui qBittorrent all'avvio di Windows"
|
LangString inst_startup ${LANG_ITALIAN} "Esegui qBittorrent all'avvio di Windows"
|
||||||
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
||||||
@@ -15,19 +15,19 @@ LangString inst_magnet ${LANG_ITALIAN} "Apri collegamenti magnet con qBittorrent
|
|||||||
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
||||||
LangString inst_firewall ${LANG_ITALIAN} "Aggiungi regola al firewall di Windows"
|
LangString inst_firewall ${LANG_ITALIAN} "Aggiungi regola al firewall di Windows"
|
||||||
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
||||||
LangString inst_pathlimit ${LANG_ITALIAN} "Disabilita limite percorso Windows (limite MAX_PATH max 260 caratterin, richiede Windows 10 versione 1607 o successive)"
|
LangString inst_pathlimit ${LANG_ITALIAN} "Disabilita limite lunghezza percorsi Windows (limite MAX_PATH di 260 caratteri, richiede Windows 10 versione 1607 o successive)"
|
||||||
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
||||||
LangString inst_firewallinfo ${LANG_ITALIAN} "Aggiunta regola al firewall di Windows"
|
LangString inst_firewallinfo ${LANG_ITALIAN} "Aggiunta regola al firewall di Windows"
|
||||||
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
||||||
LangString inst_warning ${LANG_ITALIAN} "qBittorrent è in esecuzione.%n%nChiudi l'applicazione qBittorrent prima della nuova installazione."
|
LangString inst_warning ${LANG_ITALIAN} "qBittorrent è in esecuzione. Chiudilo prima di procedere con l'installazione."
|
||||||
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
|
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
|
||||||
LangString inst_uninstall_question ${LANG_ITALIAN} "L'attuale versione di qBittorrent verrà disinstallata.%n%nLe impostazioni utente e i torrent rimanno invariati."
|
LangString inst_uninstall_question ${LANG_ITALIAN} "La versione attuale verrà disinstallata. Le impostazioni utente e i torrent rimarranno invariati."
|
||||||
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
||||||
LangString inst_unist ${LANG_ITALIAN} "Disinstallazione versione precedente di qBittorrent."
|
LangString inst_unist ${LANG_ITALIAN} "Disinstallazione versione precedente."
|
||||||
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
||||||
LangString launch_qbt ${LANG_ITALIAN} "Esegui qBittorrent"
|
LangString launch_qbt ${LANG_ITALIAN} "Esegui qBittorrent."
|
||||||
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
|
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
|
||||||
LangString inst_requires_64bit ${LANG_ITALIAN} "Questo installer di qBittorrent funziona solo con Windows a 64bit."
|
LangString inst_requires_64bit ${LANG_ITALIAN} "Questo installer funziona solo con versioni di Windows a 64bit."
|
||||||
;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7."
|
;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7."
|
||||||
LangString inst_requires_win7 ${LANG_ITALIAN} "Questa versione di qBittorrent richiede Windows 7 o versioni successive."
|
LangString inst_requires_win7 ${LANG_ITALIAN} "Questa versione di qBittorrent richiede Windows 7 o versioni successive."
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ LangString remove_shortcuts ${LANG_ITALIAN} "Rimuovi collegamenti"
|
|||||||
;LangString remove_associations ${LANG_ENGLISH} "Remove file associations"
|
;LangString remove_associations ${LANG_ENGLISH} "Remove file associations"
|
||||||
LangString remove_associations ${LANG_ITALIAN} "Rimuovi associazione file"
|
LangString remove_associations ${LANG_ITALIAN} "Rimuovi associazione file"
|
||||||
;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys"
|
;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys"
|
||||||
LangString remove_registry ${LANG_ITALIAN} "Rimuovi chiavi registro"
|
LangString remove_registry ${LANG_ITALIAN} "Rimuovi chiavi di registro"
|
||||||
;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files"
|
;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files"
|
||||||
LangString remove_conf ${LANG_ITALIAN} "Rimuovi file di configurazione"
|
LangString remove_conf ${LANG_ITALIAN} "Rimuovi file di configurazione"
|
||||||
;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule"
|
;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule"
|
||||||
@@ -52,7 +52,7 @@ LangString remove_firewallinfo ${LANG_ITALIAN} "Rimozione regola dal firewall di
|
|||||||
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
|
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
|
||||||
LangString remove_cache ${LANG_ITALIAN} "Rimuovi torrent e dati nella cache"
|
LangString remove_cache ${LANG_ITALIAN} "Rimuovi torrent e dati nella cache"
|
||||||
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
|
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
|
||||||
LangString uninst_warning ${LANG_ITALIAN} "qBittorrent è in esecuzione.%n%nChiudi qBittorrent prima della disinstallazione."
|
LangString uninst_warning ${LANG_ITALIAN} "qBittorrent è in esecuzione. Chiudilo prima di procedere con la disinstallazione."
|
||||||
;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:"
|
;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:"
|
||||||
LangString uninst_tor_warn ${LANG_ITALIAN} "Associazione file .torrent non rimossa. File associati con:"
|
LangString uninst_tor_warn ${LANG_ITALIAN} "Associazione file .torrent non rimossa. File associati con:"
|
||||||
;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:"
|
;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ LangString inst_magnet ${LANG_PORTUGUESEBR} "Abrir links magnéticos com qBittor
|
|||||||
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
||||||
LangString inst_firewall ${LANG_PORTUGUESEBR} "Adicionar regra no firewall do Windows"
|
LangString inst_firewall ${LANG_PORTUGUESEBR} "Adicionar regra no firewall do Windows"
|
||||||
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
||||||
LangString inst_pathlimit ${LANG_PORTUGUESEBR} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
LangString inst_pathlimit ${LANG_PORTUGUESEBR} "Desativar limite de caracteres em caminhos do Windows (limite MAX_PATH de 260 caracteres, requer Windows 10 1067 ou superior)"
|
||||||
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
||||||
LangString inst_firewallinfo ${LANG_PORTUGUESEBR} "Adicionando regra no firewall do Windows"
|
LangString inst_firewallinfo ${LANG_PORTUGUESEBR} "Adicionando regra no firewall do Windows"
|
||||||
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
||||||
@@ -27,9 +27,9 @@ LangString inst_unist ${LANG_PORTUGUESEBR} "Desinstalando versão anterior."
|
|||||||
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
||||||
LangString launch_qbt ${LANG_PORTUGUESEBR} "Executar qBittorrent."
|
LangString launch_qbt ${LANG_PORTUGUESEBR} "Executar qBittorrent."
|
||||||
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
|
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
|
||||||
LangString inst_requires_64bit ${LANG_PORTUGUESEBR} "This installer works only in 64-bit Windows versions."
|
LangString inst_requires_64bit ${LANG_PORTUGUESEBR} "Este instalador apenas funciona em versões 64-bit do Windows."
|
||||||
;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7."
|
;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7."
|
||||||
LangString inst_requires_win7 ${LANG_PORTUGUESEBR} "This qBittorrent version requires at least Windows 7."
|
LangString inst_requires_win7 ${LANG_PORTUGUESEBR} "Esta versão do qBittorrent requer no mínimo o Windows 7."
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------
|
;------------------------------------
|
||||||
@@ -42,13 +42,13 @@ LangString remove_shortcuts ${LANG_PORTUGUESEBR} "Remover atalhos"
|
|||||||
;LangString remove_associations ${LANG_ENGLISH} "Remove file associations"
|
;LangString remove_associations ${LANG_ENGLISH} "Remove file associations"
|
||||||
LangString remove_associations ${LANG_PORTUGUESEBR} "Remover associação de arquivos"
|
LangString remove_associations ${LANG_PORTUGUESEBR} "Remover associação de arquivos"
|
||||||
;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys"
|
;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys"
|
||||||
LangString remove_registry ${LANG_PORTUGUESEBR} "Remover registros"
|
LangString remove_registry ${LANG_PORTUGUESEBR} "Remover chaves do registro"
|
||||||
;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files"
|
;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files"
|
||||||
LangString remove_conf ${LANG_PORTUGUESEBR} "Remover configurações"
|
LangString remove_conf ${LANG_PORTUGUESEBR} "Remover configurações"
|
||||||
;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule"
|
;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule"
|
||||||
LangString remove_firewall ${LANG_PORTUGUESEBR} "Remover regras do firewall do Windows"
|
LangString remove_firewall ${LANG_PORTUGUESEBR} "Remover regra do Firewall do Windows"
|
||||||
;LangString remove_firewallinfo ${LANG_ENGLISH} "Removing Windows Firewall rule"
|
;LangString remove_firewallinfo ${LANG_ENGLISH} "Removing Windows Firewall rule"
|
||||||
LangString remove_firewallinfo ${LANG_PORTUGUESEBR} "Removendo regras do firewall do Windows"
|
LangString remove_firewallinfo ${LANG_PORTUGUESEBR} "Removendo regra do Firewall do Windows"
|
||||||
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
|
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
|
||||||
LangString remove_cache ${LANG_PORTUGUESEBR} "Remover torrents e dados em cache"
|
LangString remove_cache ${LANG_PORTUGUESEBR} "Remover torrents e dados em cache"
|
||||||
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
|
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ LangString inst_firewallinfo ${LANG_RUSSIAN} "Добавление в списо
|
|||||||
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
||||||
LangString inst_warning ${LANG_RUSSIAN} "qBittorrent запущен. Пожалуйста, закройте qBittorrent и перезапустите программу установки."
|
LangString inst_warning ${LANG_RUSSIAN} "qBittorrent запущен. Пожалуйста, закройте qBittorrent и перезапустите программу установки."
|
||||||
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
|
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
|
||||||
LangString inst_uninstall_question ${LANG_RUSSIAN} "Обнаружена предыдущая установка. Она будет деинсталлирована без удаления пользовательских настроек."
|
LangString inst_uninstall_question ${LANG_RUSSIAN} "Текущая версия будет деинсталлирована. Пользовательские настройки и торренты останутся нетронутыми."
|
||||||
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
||||||
LangString inst_unist ${LANG_RUSSIAN} "Деинсталлируется старая версия."
|
LangString inst_unist ${LANG_RUSSIAN} "Деинсталлируется старая версия."
|
||||||
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
||||||
|
|||||||
4
dist/windows/options.nsi
vendored
4
dist/windows/options.nsi
vendored
@@ -28,7 +28,7 @@ XPStyle on
|
|||||||
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
|
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
|
||||||
|
|
||||||
; Program specific
|
; Program specific
|
||||||
!define PROG_VERSION "4.3.1"
|
!define PROG_VERSION "4.3.4"
|
||||||
|
|
||||||
!define MUI_FINISHPAGE_RUN
|
!define MUI_FINISHPAGE_RUN
|
||||||
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
|
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
|
||||||
@@ -51,7 +51,7 @@ XPStyle on
|
|||||||
;Installer Version Information
|
;Installer Version Information
|
||||||
VIAddVersionKey "ProductName" "qBittorrent"
|
VIAddVersionKey "ProductName" "qBittorrent"
|
||||||
VIAddVersionKey "CompanyName" "The qBittorrent project"
|
VIAddVersionKey "CompanyName" "The qBittorrent project"
|
||||||
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2020 The qBittorrent project"
|
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2021 The qBittorrent project"
|
||||||
VIAddVersionKey "FileDescription" "qBittorrent - A Bittorrent Client"
|
VIAddVersionKey "FileDescription" "qBittorrent - A Bittorrent Client"
|
||||||
VIAddVersionKey "FileVersion" "${PROG_VERSION}"
|
VIAddVersionKey "FileVersion" "${PROG_VERSION}"
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
# Sets the QT_QMAKE variable to the path of Qt5 qmake if found.
|
# Sets the QT_QMAKE variable to the path of Qt5 qmake if found.
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
AC_DEFUN([FIND_QT5],
|
AC_DEFUN([FIND_QT5],
|
||||||
[PKG_CHECK_EXISTS([Qt5Core >= 5.9.0],
|
[PKG_CHECK_EXISTS([Qt5Core >= 5.12],
|
||||||
[PKG_CHECK_VAR(QT_QMAKE,
|
[PKG_CHECK_VAR(QT_QMAKE,
|
||||||
[Qt5Core >= 5.9.0],
|
[Qt5Core >= 5.12],
|
||||||
[host_bins])
|
[host_bins])
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ AS_IF([test -f "$QT_QMAKE/qmake"],
|
|||||||
[QT_QMAKE=""])
|
[QT_QMAKE=""])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_MSG_CHECKING([for Qt5 qmake >= 5.9.0])
|
AC_MSG_CHECKING([for Qt5 qmake >= 5.12])
|
||||||
AS_IF([test "x$QT_QMAKE" != "x"],
|
AS_IF([test "x$QT_QMAKE" != "x"],
|
||||||
[AC_MSG_RESULT([$QT_QMAKE])],
|
[AC_MSG_RESULT([$QT_QMAKE])],
|
||||||
[AC_MSG_RESULT([not found])]
|
[AC_MSG_RESULT([not found])]
|
||||||
@@ -29,23 +29,23 @@ AS_IF([test "x$QT_QMAKE" != "x"],
|
|||||||
# Sets the HAVE_QTDBUS variable to true or false.
|
# Sets the HAVE_QTDBUS variable to true or false.
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
AC_DEFUN([FIND_QTDBUS],
|
AC_DEFUN([FIND_QTDBUS],
|
||||||
[AC_MSG_CHECKING([for Qt5DBus >= 5.9.0])
|
[AC_MSG_CHECKING([for Qt5DBus >= 5.12])
|
||||||
PKG_CHECK_EXISTS([Qt5DBus >= 5.9.0],
|
PKG_CHECK_EXISTS([Qt5DBus >= 5.12],
|
||||||
[AC_MSG_RESULT([found])
|
[AC_MSG_RESULT([found])
|
||||||
HAVE_QTDBUS=[true]],
|
HAVE_QTDBUS=[true]],
|
||||||
[AC_MSG_RESULT([not found])
|
[AC_MSG_RESULT([not found])
|
||||||
HAVE_QTDBUS=[false]])
|
HAVE_QTDBUS=[false]])
|
||||||
])
|
])
|
||||||
|
|
||||||
# DETECT_CPP14_PROGRAM()
|
# DETECT_CPP17_PROGRAM()
|
||||||
# Detects if at least C++14 mode is enabled.
|
# Detects if at least C++17 mode is enabled.
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
AC_DEFUN([DETECT_CPP14_PROGRAM],
|
AC_DEFUN([DETECT_CPP17_PROGRAM],
|
||||||
[AC_LANG_PROGRAM([[
|
[AC_LANG_PROGRAM([[
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
#error "This is not a C++ compiler"
|
#error "This is not a C++ compiler"
|
||||||
#elif __cplusplus < 201402L
|
#elif __cplusplus < 201703L
|
||||||
#error "This is not a C++14 compiler"
|
#error "This is not a C++17 compiler"
|
||||||
#endif]],
|
#endif]],
|
||||||
[[]])
|
[[]])
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ else {
|
|||||||
include(conf.pri)
|
include(conf.pri)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.14
|
||||||
|
|
||||||
LIBS += -framework Carbon -framework IOKit -framework AppKit
|
LIBS += -framework Carbon -framework IOKit -framework AppKit
|
||||||
|
|
||||||
QT_LANG_PATH = ../dist/qt-translations
|
QT_LANG_PATH = ../dist/qt-translations
|
||||||
|
|||||||
@@ -4,19 +4,6 @@ SUBDIRS += src
|
|||||||
|
|
||||||
include(version.pri)
|
include(version.pri)
|
||||||
|
|
||||||
# Make target to create release tarball. Use 'make tarball'
|
|
||||||
tarball.commands += rm -fR ../$${PROJECT_NAME}-$${PROJECT_VERSION}/ &&
|
|
||||||
tarball.commands += git clone . ../$${PROJECT_NAME}-$${PROJECT_VERSION} &&
|
|
||||||
tarball.commands += rm -fR ../$${PROJECT_NAME}-$${PROJECT_VERSION}/.git &&
|
|
||||||
tarball.commands += rm -f ../$${PROJECT_NAME}-$${PROJECT_VERSION}/.gitignore &&
|
|
||||||
tarball.commands += cd .. &&
|
|
||||||
tarball.commands += tar czf $${PROJECT_NAME}-$${PROJECT_VERSION}.tar.gz $${PROJECT_NAME}-$${PROJECT_VERSION} &&
|
|
||||||
tarball.commands += tar cf $${PROJECT_NAME}-$${PROJECT_VERSION}.tar $${PROJECT_NAME}-$${PROJECT_VERSION} &&
|
|
||||||
tarball.commands += xz -f $${PROJECT_NAME}-$${PROJECT_VERSION}.tar &&
|
|
||||||
tarball.commands += rm -fR $${PROJECT_NAME}-$${PROJECT_VERSION}
|
|
||||||
|
|
||||||
QMAKE_EXTRA_TARGETS += tarball
|
|
||||||
|
|
||||||
# For Qt Creator beautifier
|
# For Qt Creator beautifier
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
uncrustify.cfg
|
uncrustify.cfg
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
if (UNIX AND (NOT APPLE) AND (NOT CYGWIN))
|
if (UNIX AND (NOT APPLE) AND (NOT CYGWIN))
|
||||||
find_package(LibtorrentRasterbar QUIET ${requiredLibtorrentVersion} COMPONENTS torrent-rasterbar)
|
find_package(LibtorrentRasterbar QUIET ${minLibtorrentVersion} COMPONENTS torrent-rasterbar)
|
||||||
if (NOT LibtorrentRasterbar_FOUND)
|
if (NOT LibtorrentRasterbar_FOUND)
|
||||||
include(FindPkgConfig)
|
include(FindPkgConfig)
|
||||||
pkg_check_modules(LIBTORRENT_RASTERBAR IMPORTED_TARGET GLOBAL "libtorrent-rasterbar>=${requiredLibtorrentVersion}")
|
pkg_check_modules(LIBTORRENT_RASTERBAR IMPORTED_TARGET GLOBAL "libtorrent-rasterbar>=${minLibtorrentVersion}")
|
||||||
if (NOT LIBTORRENT_RASTERBAR_FOUND)
|
if (NOT LIBTORRENT_RASTERBAR_FOUND)
|
||||||
message(
|
message(
|
||||||
FATAL_ERROR
|
FATAL_ERROR
|
||||||
"Package LibtorrentRasterbar >= ${requiredLibtorrentVersion} not found"
|
"Package LibtorrentRasterbar >= ${minLibtorrentVersion} not found"
|
||||||
" with CMake or pkg-config.\n- Set LibtorrentRasterbar_DIR to a directory containing"
|
" with CMake or pkg-config.\n- Set LibtorrentRasterbar_DIR to a directory containing"
|
||||||
" a LibtorrentRasterbarConfig.cmake file or add the installation prefix of LibtorrentRasterbar"
|
" a LibtorrentRasterbarConfig.cmake file or add the installation prefix of LibtorrentRasterbar"
|
||||||
" to CMAKE_PREFIX_PATH.\n- Alternatively, make sure there is a valid libtorrent-rasterbar.pc"
|
" to CMAKE_PREFIX_PATH.\n- Alternatively, make sure there is a valid libtorrent-rasterbar.pc"
|
||||||
@@ -18,9 +18,9 @@ if (UNIX AND (NOT APPLE) AND (NOT CYGWIN))
|
|||||||
# force a fake package to show up in the feature summary
|
# force a fake package to show up in the feature summary
|
||||||
set_property(GLOBAL APPEND PROPERTY
|
set_property(GLOBAL APPEND PROPERTY
|
||||||
PACKAGES_FOUND
|
PACKAGES_FOUND
|
||||||
"LibtorrentRasterbar via pkg-config (required version >= ${requiredLibtorrentVersion})"
|
"LibtorrentRasterbar via pkg-config (version >= ${minLibtorrentVersion})"
|
||||||
)
|
)
|
||||||
set_package_properties("LibtorrentRasterbar via pkg-config (required version >= ${requiredLibtorrentVersion})"
|
set_package_properties("LibtorrentRasterbar via pkg-config (version >= ${minLibtorrentVersion})"
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
)
|
)
|
||||||
@@ -28,16 +28,16 @@ if (UNIX AND (NOT APPLE) AND (NOT CYGWIN))
|
|||||||
set_package_properties(LibtorrentRasterbar PROPERTIES TYPE REQUIRED)
|
set_package_properties(LibtorrentRasterbar PROPERTIES TYPE REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
find_package(LibtorrentRasterbar ${requiredLibtorrentVersion} REQUIRED COMPONENTS torrent-rasterbar)
|
find_package(LibtorrentRasterbar ${minLibtorrentVersion} REQUIRED COMPONENTS torrent-rasterbar)
|
||||||
endif()
|
endif()
|
||||||
# force variable type so that it always shows up in ccmake/cmake-gui frontends
|
# force variable type so that it always shows up in ccmake/cmake-gui frontends
|
||||||
set_property(CACHE LibtorrentRasterbar_DIR PROPERTY TYPE PATH)
|
set_property(CACHE LibtorrentRasterbar_DIR PROPERTY TYPE PATH)
|
||||||
find_package(Boost ${requiredBoostVersion} REQUIRED)
|
find_package(Boost ${minBoostVersion} REQUIRED)
|
||||||
find_package(OpenSSL ${requiredOpenSSLVersion} REQUIRED)
|
find_package(OpenSSL ${minOpenSSLVersion} REQUIRED)
|
||||||
find_package(ZLIB ${requiredZlibVersion} REQUIRED)
|
find_package(ZLIB ${minZlibVersion} REQUIRED)
|
||||||
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS Core Network Xml LinguistTools)
|
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS Core Network Xml LinguistTools)
|
||||||
if (DBUS)
|
if (DBUS)
|
||||||
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS DBus)
|
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS DBus)
|
||||||
set_package_properties(Qt5DBus PROPERTIES
|
set_package_properties(Qt5DBus PROPERTIES
|
||||||
DESCRIPTION "Qt5 module for inter-process communication over the D-Bus protocol"
|
DESCRIPTION "Qt5 module for inter-process communication over the D-Bus protocol"
|
||||||
PURPOSE "Required by the DBUS feature"
|
PURPOSE "Required by the DBUS feature"
|
||||||
@@ -60,11 +60,11 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
|||||||
add_subdirectory(base)
|
add_subdirectory(base)
|
||||||
|
|
||||||
if (GUI)
|
if (GUI)
|
||||||
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS Widgets Svg)
|
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS Widgets Svg)
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS MacExtras)
|
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS MacExtras)
|
||||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS WinExtras)
|
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS WinExtras)
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(gui)
|
add_subdirectory(gui)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -4,22 +4,14 @@
|
|||||||
# Based on https://gist.github.com/giraldeau/546ba5512a74dfe9d8ea0862d66db412
|
# Based on https://gist.github.com/giraldeau/546ba5512a74dfe9d8ea0862d66db412
|
||||||
file(GLOB QBT_TS_FILES "${qBittorrent_SOURCE_DIR}/src/lang/*.ts")
|
file(GLOB QBT_TS_FILES "${qBittorrent_SOURCE_DIR}/src/lang/*.ts")
|
||||||
set_source_files_properties(${QBT_TS_FILES} PROPERTIES OUTPUT_LOCATION "${qBittorrent_BINARY_DIR}/src/lang")
|
set_source_files_properties(${QBT_TS_FILES} PROPERTIES OUTPUT_LOCATION "${qBittorrent_BINARY_DIR}/src/lang")
|
||||||
if (Qt5_VERSION VERSION_LESS 5.12)
|
qt5_add_translation(QBT_QM_FILES ${QBT_TS_FILES} OPTIONS -silent)
|
||||||
qt5_add_translation(QBT_QM_FILES ${QBT_TS_FILES})
|
|
||||||
else()
|
|
||||||
qt5_add_translation(QBT_QM_FILES ${QBT_TS_FILES} OPTIONS -silent)
|
|
||||||
endif()
|
|
||||||
configure_file("${qBittorrent_SOURCE_DIR}/src/lang/lang.qrc" "${qBittorrent_BINARY_DIR}/src/lang/lang.qrc" COPYONLY)
|
configure_file("${qBittorrent_SOURCE_DIR}/src/lang/lang.qrc" "${qBittorrent_BINARY_DIR}/src/lang/lang.qrc" COPYONLY)
|
||||||
|
|
||||||
if (WEBUI)
|
if (WEBUI)
|
||||||
file(GLOB QBT_WEBUI_TS_FILES "${qBittorrent_SOURCE_DIR}/src/webui/www/translations/*.ts")
|
file(GLOB QBT_WEBUI_TS_FILES "${qBittorrent_SOURCE_DIR}/src/webui/www/translations/*.ts")
|
||||||
set_source_files_properties(${QBT_WEBUI_TS_FILES}
|
set_source_files_properties(${QBT_WEBUI_TS_FILES}
|
||||||
PROPERTIES OUTPUT_LOCATION "${qBittorrent_BINARY_DIR}/src/webui/www/translations")
|
PROPERTIES OUTPUT_LOCATION "${qBittorrent_BINARY_DIR}/src/webui/www/translations")
|
||||||
if (Qt5_VERSION VERSION_LESS 5.12)
|
qt5_add_translation(QBT_WEBUI_QM_FILES ${QBT_WEBUI_TS_FILES} OPTIONS -silent)
|
||||||
qt5_add_translation(QBT_WEBUI_QM_FILES ${QBT_WEBUI_TS_FILES})
|
|
||||||
else()
|
|
||||||
qt5_add_translation(QBT_WEBUI_QM_FILES ${QBT_WEBUI_TS_FILES} OPTIONS -silent)
|
|
||||||
endif()
|
|
||||||
configure_file("${qBittorrent_SOURCE_DIR}/src/webui/www/translations/webui_translations.qrc"
|
configure_file("${qBittorrent_SOURCE_DIR}/src/webui/www/translations/webui_translations.qrc"
|
||||||
"${qBittorrent_BINARY_DIR}/src/webui/www/translations/webui_translations.qrc" COPYONLY)
|
"${qBittorrent_BINARY_DIR}/src/webui/www/translations/webui_translations.qrc" COPYONLY)
|
||||||
endif()
|
endif()
|
||||||
@@ -61,7 +53,6 @@ target_sources(qbt_app PRIVATE
|
|||||||
|
|
||||||
target_link_libraries(qbt_app PRIVATE
|
target_link_libraries(qbt_app PRIVATE
|
||||||
qbt_base
|
qbt_base
|
||||||
qbt_version_definitions
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(qbt_app PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
set_target_properties(qbt_app PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
#include "base/bittorrent/infohash.h"
|
#include "base/bittorrent/infohash.h"
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrent.h"
|
||||||
#include "base/exceptions.h"
|
#include "base/exceptions.h"
|
||||||
#include "base/iconprovider.h"
|
#include "base/iconprovider.h"
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
@@ -81,6 +81,7 @@
|
|||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/string.h"
|
#include "base/utils/string.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "applicationinstancemanager.h"
|
#include "applicationinstancemanager.h"
|
||||||
#include "filelogger.h"
|
#include "filelogger.h"
|
||||||
|
|
||||||
@@ -214,7 +215,7 @@ const QBtCommandLineParameters &Application::commandLineArgs() const
|
|||||||
|
|
||||||
bool Application::isFileLoggerEnabled() const
|
bool Application::isFileLoggerEnabled() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_FILELOGGER_ENABLED, true).toBool();
|
return settings()->loadValue(KEY_FILELOGGER_ENABLED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFileLoggerEnabled(const bool value)
|
void Application::setFileLoggerEnabled(const bool value)
|
||||||
@@ -228,8 +229,8 @@ void Application::setFileLoggerEnabled(const bool value)
|
|||||||
|
|
||||||
QString Application::fileLoggerPath() const
|
QString Application::fileLoggerPath() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_FILELOGGER_PATH,
|
return settings()->loadValue(KEY_FILELOGGER_PATH
|
||||||
{specialFolderLocation(SpecialFolder::Data) + LOG_FOLDER}).toString();
|
, QString {specialFolderLocation(SpecialFolder::Data) + LOG_FOLDER});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFileLoggerPath(const QString &path)
|
void Application::setFileLoggerPath(const QString &path)
|
||||||
@@ -241,7 +242,7 @@ void Application::setFileLoggerPath(const QString &path)
|
|||||||
|
|
||||||
bool Application::isFileLoggerBackup() const
|
bool Application::isFileLoggerBackup() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_FILELOGGER_BACKUP, true).toBool();
|
return settings()->loadValue(KEY_FILELOGGER_BACKUP, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFileLoggerBackup(const bool value)
|
void Application::setFileLoggerBackup(const bool value)
|
||||||
@@ -253,7 +254,7 @@ void Application::setFileLoggerBackup(const bool value)
|
|||||||
|
|
||||||
bool Application::isFileLoggerDeleteOld() const
|
bool Application::isFileLoggerDeleteOld() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_FILELOGGER_DELETEOLD, true).toBool();
|
return settings()->loadValue(KEY_FILELOGGER_DELETEOLD, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFileLoggerDeleteOld(const bool value)
|
void Application::setFileLoggerDeleteOld(const bool value)
|
||||||
@@ -265,7 +266,7 @@ void Application::setFileLoggerDeleteOld(const bool value)
|
|||||||
|
|
||||||
int Application::fileLoggerMaxSize() const
|
int Application::fileLoggerMaxSize() const
|
||||||
{
|
{
|
||||||
const int val = settings()->loadValue(KEY_FILELOGGER_MAXSIZEBYTES, DEFAULT_FILELOG_SIZE).toInt();
|
const int val = settings()->loadValue(KEY_FILELOGGER_MAXSIZEBYTES, DEFAULT_FILELOG_SIZE);
|
||||||
return std::min(std::max(val, MIN_FILELOG_SIZE), MAX_FILELOG_SIZE);
|
return std::min(std::max(val, MIN_FILELOG_SIZE), MAX_FILELOG_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +280,7 @@ void Application::setFileLoggerMaxSize(const int bytes)
|
|||||||
|
|
||||||
int Application::fileLoggerAge() const
|
int Application::fileLoggerAge() const
|
||||||
{
|
{
|
||||||
const int val = settings()->loadValue(KEY_FILELOGGER_AGE, 1).toInt();
|
const int val = settings()->loadValue(KEY_FILELOGGER_AGE, 1);
|
||||||
return std::min(std::max(val, 1), 365);
|
return std::min(std::max(val, 1), 365);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +291,7 @@ void Application::setFileLoggerAge(const int value)
|
|||||||
|
|
||||||
int Application::fileLoggerAgeType() const
|
int Application::fileLoggerAgeType() const
|
||||||
{
|
{
|
||||||
const int val = settings()->loadValue(KEY_FILELOGGER_AGETYPE, 1).toInt();
|
const int val = settings()->loadValue(KEY_FILELOGGER_AGETYPE, 1);
|
||||||
return ((val < 0) || (val > 2)) ? 1 : val;
|
return ((val < 0) || (val > 2)) ? 1 : val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,16 +311,8 @@ void Application::processMessage(const QString &message)
|
|||||||
m_paramsQueue.append(params);
|
m_paramsQueue.append(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) const
|
void Application::runExternalProgram(const BitTorrent::Torrent *torrent) const
|
||||||
{
|
{
|
||||||
QString program = Preferences::instance()->getAutoRunProgram().trimmed();
|
|
||||||
program.replace("%N", torrent->name());
|
|
||||||
program.replace("%L", torrent->category());
|
|
||||||
|
|
||||||
QStringList tags = torrent->tags().values();
|
|
||||||
std::sort(tags.begin(), tags.end(), Utils::String::naturalLessThan<Qt::CaseInsensitive>);
|
|
||||||
program.replace("%G", tags.join(','));
|
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
const auto chopPathSep = [](const QString &str) -> QString
|
const auto chopPathSep = [](const QString &str) -> QString
|
||||||
{
|
{
|
||||||
@@ -327,21 +320,74 @@ void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) c
|
|||||||
return str.mid(0, (str.length() -1));
|
return str.mid(0, (str.length() -1));
|
||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
program.replace("%F", chopPathSep(Utils::Fs::toNativePath(torrent->contentPath())));
|
|
||||||
program.replace("%R", chopPathSep(Utils::Fs::toNativePath(torrent->rootPath())));
|
|
||||||
program.replace("%D", chopPathSep(Utils::Fs::toNativePath(torrent->savePath())));
|
|
||||||
#else
|
|
||||||
program.replace("%F", Utils::Fs::toNativePath(torrent->contentPath()));
|
|
||||||
program.replace("%R", Utils::Fs::toNativePath(torrent->rootPath()));
|
|
||||||
program.replace("%D", Utils::Fs::toNativePath(torrent->savePath()));
|
|
||||||
#endif
|
#endif
|
||||||
program.replace("%C", QString::number(torrent->filesCount()));
|
|
||||||
program.replace("%Z", QString::number(torrent->totalSize()));
|
|
||||||
program.replace("%T", torrent->currentTracker());
|
|
||||||
program.replace("%I", torrent->hash());
|
|
||||||
|
|
||||||
Logger *logger = Logger::instance();
|
QString program = Preferences::instance()->getAutoRunProgram().trimmed();
|
||||||
logger->addMessage(tr("Torrent: %1, running external program, command: %2").arg(torrent->name(), program));
|
|
||||||
|
for (int i = (program.length() - 2); i >= 0; --i)
|
||||||
|
{
|
||||||
|
if (program[i] != QLatin1Char('%'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const ushort specifier = program[i + 1].unicode();
|
||||||
|
switch (specifier)
|
||||||
|
{
|
||||||
|
case u'C':
|
||||||
|
program.replace(i, 2, QString::number(torrent->filesCount()));
|
||||||
|
break;
|
||||||
|
case u'D':
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
program.replace(i, 2, chopPathSep(Utils::Fs::toNativePath(torrent->savePath())));
|
||||||
|
#else
|
||||||
|
program.replace(i, 2, Utils::Fs::toNativePath(torrent->savePath()));
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case u'F':
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
program.replace(i, 2, chopPathSep(Utils::Fs::toNativePath(torrent->contentPath())));
|
||||||
|
#else
|
||||||
|
program.replace(i, 2, Utils::Fs::toNativePath(torrent->contentPath()));
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case u'G':
|
||||||
|
{
|
||||||
|
QStringList tags = torrent->tags().values();
|
||||||
|
std::sort(tags.begin(), tags.end(), Utils::String::naturalLessThan<Qt::CaseInsensitive>);
|
||||||
|
program.replace(i, 2, tags.join(','));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case u'I':
|
||||||
|
program.replace(i, 2, torrent->id().toString());
|
||||||
|
break;
|
||||||
|
case u'L':
|
||||||
|
program.replace(i, 2, torrent->category());
|
||||||
|
break;
|
||||||
|
case u'N':
|
||||||
|
program.replace(i, 2, torrent->name());
|
||||||
|
break;
|
||||||
|
case u'R':
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
program.replace(i, 2, chopPathSep(Utils::Fs::toNativePath(torrent->rootPath())));
|
||||||
|
#else
|
||||||
|
program.replace(i, 2, Utils::Fs::toNativePath(torrent->rootPath()));
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case u'T':
|
||||||
|
program.replace(i, 2, torrent->currentTracker());
|
||||||
|
break;
|
||||||
|
case u'Z':
|
||||||
|
program.replace(i, 2, QString::number(torrent->totalSize()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrement `i` to avoid unwanted replacement, example pattern: "%%N"
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMsg(tr("Torrent: %1, running external program, command: %2").arg(torrent->name(), program));
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
auto programWchar = std::make_unique<wchar_t[]>(program.length() + 1);
|
auto programWchar = std::make_unique<wchar_t[]>(program.length() + 1);
|
||||||
@@ -357,7 +403,6 @@ void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) c
|
|||||||
for (int i = 1; i < argCount; ++i)
|
for (int i = 1; i < argCount; ++i)
|
||||||
argList += QString::fromWCharArray(args[i]);
|
argList += QString::fromWCharArray(args[i]);
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
|
||||||
QProcess proc;
|
QProcess proc;
|
||||||
proc.setProgram(QString::fromWCharArray(args[0]));
|
proc.setProgram(QString::fromWCharArray(args[0]));
|
||||||
proc.setArguments(argList);
|
proc.setArguments(argList);
|
||||||
@@ -383,9 +428,6 @@ void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) c
|
|||||||
args->startupInfo->hStdError = nullptr;
|
args->startupInfo->hStdError = nullptr;
|
||||||
});
|
});
|
||||||
proc.startDetached();
|
proc.startDetached();
|
||||||
#else
|
|
||||||
QProcess::startDetached(QString::fromWCharArray(args[0]), argList);
|
|
||||||
#endif // QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
|
||||||
#else // Q_OS_WIN
|
#else // Q_OS_WIN
|
||||||
// Cannot give users shell environment by default, as doing so could
|
// Cannot give users shell environment by default, as doing so could
|
||||||
// enable command injection via torrent name and other arguments
|
// enable command injection via torrent name and other arguments
|
||||||
@@ -404,7 +446,7 @@ void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) c
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::sendNotificationEmail(const BitTorrent::TorrentHandle *torrent)
|
void Application::sendNotificationEmail(const BitTorrent::Torrent *torrent)
|
||||||
{
|
{
|
||||||
// Prepare mail content
|
// Prepare mail content
|
||||||
const QString content = tr("Torrent name: %1").arg(torrent->name()) + '\n'
|
const QString content = tr("Torrent name: %1").arg(torrent->name()) + '\n'
|
||||||
@@ -423,7 +465,7 @@ void Application::sendNotificationEmail(const BitTorrent::TorrentHandle *torrent
|
|||||||
content);
|
content);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::torrentFinished(BitTorrent::TorrentHandle *const torrent)
|
void Application::torrentFinished(BitTorrent::Torrent *const torrent)
|
||||||
{
|
{
|
||||||
Preferences *const pref = Preferences::instance();
|
Preferences *const pref = Preferences::instance();
|
||||||
|
|
||||||
@@ -505,7 +547,7 @@ void Application::processParams(const QStringList ¶ms)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
BitTorrent::AddTorrentParams torrentParams;
|
BitTorrent::AddTorrentParams torrentParams;
|
||||||
TriStateBool skipTorrentDialog;
|
std::optional<bool> skipTorrentDialog;
|
||||||
|
|
||||||
for (QString param : params)
|
for (QString param : params)
|
||||||
{
|
{
|
||||||
@@ -521,7 +563,7 @@ void Application::processParams(const QStringList ¶ms)
|
|||||||
|
|
||||||
if (param.startsWith(QLatin1String("@addPaused=")))
|
if (param.startsWith(QLatin1String("@addPaused=")))
|
||||||
{
|
{
|
||||||
torrentParams.addPaused = param.midRef(11).toInt() ? TriStateBool::True : TriStateBool::False;
|
torrentParams.addPaused = (param.midRef(11).toInt() != 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,7 +593,7 @@ void Application::processParams(const QStringList ¶ms)
|
|||||||
|
|
||||||
if (param.startsWith(QLatin1String("@skipDialog=")))
|
if (param.startsWith(QLatin1String("@skipDialog=")))
|
||||||
{
|
{
|
||||||
skipTorrentDialog = param.midRef(12).toInt() ? TriStateBool::True : TriStateBool::False;
|
skipTorrentDialog = (param.midRef(12).toInt() != 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,9 +603,7 @@ void Application::processParams(const QStringList ¶ms)
|
|||||||
// be shown and skipTorrentDialog is undefined. The other is when
|
// be shown and skipTorrentDialog is undefined. The other is when
|
||||||
// skipTorrentDialog is false, meaning that the application setting
|
// skipTorrentDialog is false, meaning that the application setting
|
||||||
// should be overridden.
|
// should be overridden.
|
||||||
const bool showDialogForThisTorrent =
|
const bool showDialogForThisTorrent = !skipTorrentDialog.value_or(!AddNewTorrentDialog::isEnabled());
|
||||||
((AddNewTorrentDialog::isEnabled() && skipTorrentDialog == TriStateBool::Undefined)
|
|
||||||
|| skipTorrentDialog == TriStateBool::False);
|
|
||||||
if (showDialogForThisTorrent)
|
if (showDialogForThisTorrent)
|
||||||
AddNewTorrentDialog::show(param, torrentParams, m_window);
|
AddNewTorrentDialog::show(param, torrentParams, m_window);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class FileLogger;
|
|||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class TorrentHandle;
|
class Torrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace RSS
|
namespace RSS
|
||||||
@@ -112,7 +112,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void processMessage(const QString &message);
|
void processMessage(const QString &message);
|
||||||
void torrentFinished(BitTorrent::TorrentHandle *const torrent);
|
void torrentFinished(BitTorrent::Torrent *const torrent);
|
||||||
void allTorrentsFinished();
|
void allTorrentsFinished();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
#if (!defined(DISABLE_GUI) && defined(Q_OS_WIN))
|
#if (!defined(DISABLE_GUI) && defined(Q_OS_WIN))
|
||||||
@@ -142,6 +142,6 @@ private:
|
|||||||
|
|
||||||
void initializeTranslation();
|
void initializeTranslation();
|
||||||
void processParams(const QStringList ¶ms);
|
void processParams(const QStringList ¶ms);
|
||||||
void runExternalProgram(const BitTorrent::TorrentHandle *torrent) const;
|
void runExternalProgram(const BitTorrent::Torrent *torrent) const;
|
||||||
void sendNotificationEmail(const BitTorrent::TorrentHandle *torrent);
|
void sendNotificationEmail(const BitTorrent::Torrent *torrent);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -254,13 +254,13 @@ namespace
|
|||||||
return padUsageText(fullParameter() + QLatin1String("=<true|false>"));
|
return padUsageText(fullParameter() + QLatin1String("=<true|false>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TriStateBool value(const QString &arg) const
|
std::optional<bool> value(const QString &arg) const
|
||||||
{
|
{
|
||||||
QStringList parts = arg.split(QLatin1Char('='));
|
QStringList parts = arg.split(QLatin1Char('='));
|
||||||
|
|
||||||
if (parts.size() == 1)
|
if (parts.size() == 1)
|
||||||
{
|
{
|
||||||
return TriStateBool(m_defaultValue);
|
return m_defaultValue;
|
||||||
}
|
}
|
||||||
if (parts.size() == 2)
|
if (parts.size() == 2)
|
||||||
{
|
{
|
||||||
@@ -268,11 +268,11 @@ namespace
|
|||||||
|
|
||||||
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
|
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
|
||||||
{
|
{
|
||||||
return TriStateBool::True;
|
return true;
|
||||||
}
|
}
|
||||||
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
|
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
|
||||||
{
|
{
|
||||||
return TriStateBool::False;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,30 +282,30 @@ namespace
|
|||||||
.arg(fullParameter(), QLatin1String("<true|false>")));
|
.arg(fullParameter(), QLatin1String("<true|false>")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TriStateBool value(const QProcessEnvironment &env) const
|
std::optional<bool> value(const QProcessEnvironment &env) const
|
||||||
{
|
{
|
||||||
const QString val = env.value(envVarName(), "-1");
|
const QString val = env.value(envVarName(), "-1");
|
||||||
|
|
||||||
if (val.isEmpty())
|
if (val.isEmpty())
|
||||||
{
|
{
|
||||||
return TriStateBool(m_defaultValue);
|
return m_defaultValue;
|
||||||
}
|
}
|
||||||
if (val == QLatin1String("-1"))
|
if (val == QLatin1String("-1"))
|
||||||
{
|
{
|
||||||
return TriStateBool::Undefined;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
|
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
|
||||||
{
|
{
|
||||||
return TriStateBool::True;
|
return true;
|
||||||
}
|
}
|
||||||
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
|
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
|
||||||
{
|
{
|
||||||
return TriStateBool::False;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << QObject::tr("Expected %1 in environment variable '%2', but got '%3'")
|
qDebug() << QObject::tr("Expected %1 in environment variable '%2', but got '%3'")
|
||||||
.arg(QLatin1String("true|false"), envVarName(), val);
|
.arg(QLatin1String("true|false"), envVarName(), val);
|
||||||
return TriStateBool::Undefined;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool m_defaultValue;
|
bool m_defaultValue;
|
||||||
@@ -374,14 +374,8 @@ QStringList QBtCommandLineParameters::paramList() const
|
|||||||
if (!savePath.isEmpty())
|
if (!savePath.isEmpty())
|
||||||
result.append(QLatin1String("@savePath=") + savePath);
|
result.append(QLatin1String("@savePath=") + savePath);
|
||||||
|
|
||||||
if (addPaused == TriStateBool::True)
|
if (addPaused.has_value())
|
||||||
{
|
result.append(*addPaused ? QLatin1String {"@addPaused=1"} : QLatin1String {"@addPaused=0"});
|
||||||
result.append(QLatin1String("@addPaused=1"));
|
|
||||||
}
|
|
||||||
else if (addPaused == TriStateBool::False)
|
|
||||||
{
|
|
||||||
result.append(QLatin1String("@addPaused=0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skipChecking)
|
if (skipChecking)
|
||||||
result.append(QLatin1String("@skipChecking"));
|
result.append(QLatin1String("@skipChecking"));
|
||||||
@@ -395,14 +389,8 @@ QStringList QBtCommandLineParameters::paramList() const
|
|||||||
if (firstLastPiecePriority)
|
if (firstLastPiecePriority)
|
||||||
result.append(QLatin1String("@firstLastPiecePriority"));
|
result.append(QLatin1String("@firstLastPiecePriority"));
|
||||||
|
|
||||||
if (skipDialog == TriStateBool::True)
|
if (skipDialog.has_value())
|
||||||
{
|
result.append(*skipDialog ? QLatin1String {"@skipDialog=1"} : QLatin1String {"@skipDialog=0"});
|
||||||
result.append(QLatin1String("@skipDialog=1"));
|
|
||||||
}
|
|
||||||
else if (skipDialog == TriStateBool::False)
|
|
||||||
{
|
|
||||||
result.append(QLatin1String("@skipDialog=0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
result += torrents;
|
result += torrents;
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -28,16 +28,14 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef APP_OPTIONS_H
|
#pragma once
|
||||||
#define APP_OPTIONS_H
|
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#include "base/tristatebool.h"
|
|
||||||
|
|
||||||
class QProcessEnvironment;
|
class QProcessEnvironment;
|
||||||
|
|
||||||
struct QBtCommandLineParameters
|
struct QBtCommandLineParameters
|
||||||
@@ -56,8 +54,8 @@ struct QBtCommandLineParameters
|
|||||||
bool shouldDaemonize;
|
bool shouldDaemonize;
|
||||||
#endif
|
#endif
|
||||||
int webUiPort;
|
int webUiPort;
|
||||||
TriStateBool addPaused;
|
std::optional<bool> addPaused;
|
||||||
TriStateBool skipDialog;
|
std::optional<bool> skipDialog;
|
||||||
QStringList torrents;
|
QStringList torrents;
|
||||||
QString profileDir;
|
QString profileDir;
|
||||||
QString configurationName;
|
QString configurationName;
|
||||||
@@ -81,5 +79,3 @@ private:
|
|||||||
|
|
||||||
QBtCommandLineParameters parseCommandLine(const QStringList &args);
|
QBtCommandLineParameters parseCommandLine(const QStringList &args);
|
||||||
void displayUsage(const QString &prgName);
|
void displayUsage(const QString &prgName);
|
||||||
|
|
||||||
#endif // APP_OPTIONS_H
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FILELOGGER_H
|
#pragma once
|
||||||
#define FILELOGGER_H
|
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@@ -73,5 +72,3 @@ private:
|
|||||||
QFile m_logFile;
|
QFile m_logFile;
|
||||||
QTimer m_flusher;
|
QTimer m_flusher;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILELOGGER_H
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ Q_IMPORT_PLUGIN(QICOPlugin)
|
|||||||
|
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "base/profile.h"
|
#include "base/profile.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "cmdoptions.h"
|
#include "cmdoptions.h"
|
||||||
#include "upgrade.h"
|
#include "upgrade.h"
|
||||||
@@ -234,7 +235,7 @@ int main(int argc, char *argv[])
|
|||||||
// 3. https://bugreports.qt.io/browse/QTBUG-46015
|
// 3. https://bugreports.qt.io/browse/QTBUG-46015
|
||||||
|
|
||||||
qputenv("QT_BEARER_POLL_TIMEOUT", QByteArray::number(-1));
|
qputenv("QT_BEARER_POLL_TIMEOUT", QByteArray::number(-1));
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) && !defined(DISABLE_GUI)
|
#if !defined(DISABLE_GUI)
|
||||||
// this is the default in Qt6
|
// this is the default in Qt6
|
||||||
app->setAttribute(Qt::AA_DisableWindowContextHelpButton);
|
app->setAttribute(Qt::AA_DisableWindowContextHelpButton);
|
||||||
#endif
|
#endif
|
||||||
@@ -250,6 +251,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// On OS X the standard is to not show icons in the menus
|
// On OS X the standard is to not show icons in the menus
|
||||||
app->setAttribute(Qt::AA_DontShowIconsInMenus);
|
app->setAttribute(Qt::AA_DontShowIconsInMenus);
|
||||||
|
#else
|
||||||
|
if (!Preferences::instance()->iconsInMenusEnabled())
|
||||||
|
app->setAttribute(Qt::AA_DontShowIconsInMenus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!firstTimeUser)
|
if (!firstTimeUser)
|
||||||
@@ -377,11 +381,7 @@ void showSplashScreen()
|
|||||||
const QString version = QBT_VERSION;
|
const QString version = QBT_VERSION;
|
||||||
painter.setPen(QPen(Qt::white));
|
painter.setPen(QPen(Qt::white));
|
||||||
painter.setFont(QFont("Arial", 22, QFont::Black));
|
painter.setFont(QFont("Arial", 22, QFont::Black));
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
|
||||||
painter.drawText(224 - painter.fontMetrics().horizontalAdvance(version), 270, version);
|
painter.drawText(224 - painter.fontMetrics().horizontalAdvance(version), 270, version);
|
||||||
#else
|
|
||||||
painter.drawText(224 - painter.fontMetrics().width(version), 270, version);
|
|
||||||
#endif
|
|
||||||
QSplashScreen *splash = new QSplashScreen(splashImg);
|
QSplashScreen *splash = new QSplashScreen(splashImg);
|
||||||
splash->show();
|
splash->show();
|
||||||
QTimer::singleShot(1500, splash, &QObject::deleteLater);
|
QTimer::singleShot(1500, splash, &QObject::deleteLater);
|
||||||
|
|||||||
@@ -79,6 +79,7 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QLocalServer>
|
#include <QLocalServer>
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
|
|||||||
#endif
|
#endif
|
||||||
prefix = id.section(QLatin1Char('/'), -1);
|
prefix = id.section(QLatin1Char('/'), -1);
|
||||||
}
|
}
|
||||||
prefix.remove(QRegExp("[^a-zA-Z]"));
|
prefix.remove(QRegularExpression("[^a-zA-Z]"));
|
||||||
prefix.truncate(6);
|
prefix.truncate(6);
|
||||||
|
|
||||||
QByteArray idc = id.toUtf8();
|
QByteArray idc = id.toUtf8();
|
||||||
@@ -152,7 +153,7 @@ bool QtLocalPeer::isClient()
|
|||||||
#endif
|
#endif
|
||||||
if (!res)
|
if (!res)
|
||||||
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
||||||
QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
|
connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,8 +66,7 @@
|
|||||||
****************************************************************************
|
****************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef QTLOCALPEER_H
|
#pragma once
|
||||||
#define QTLOCALPEER_H
|
|
||||||
|
|
||||||
#include "qtlockedfile.h"
|
#include "qtlockedfile.h"
|
||||||
|
|
||||||
@@ -99,5 +98,3 @@ protected:
|
|||||||
private:
|
private:
|
||||||
static const char* ack;
|
static const char* ack;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QTLOCALPEER_H
|
|
||||||
|
|||||||
@@ -66,8 +66,7 @@
|
|||||||
****************************************************************************
|
****************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef QTLOCKEDFILE_H
|
#pragma once
|
||||||
#define QTLOCKEDFILE_H
|
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
@@ -112,5 +111,3 @@ namespace QtLP_Private
|
|||||||
LockMode m_lock_mode;
|
LockMode m_lock_mode;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -18,13 +18,13 @@
|
|||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef STACKTRACE_WIN_H
|
#pragma once
|
||||||
#define STACKTRACE_WIN_H
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
@@ -257,7 +257,7 @@ const QString straceWin::getBacktrace()
|
|||||||
|
|
||||||
HANDLE hProcess = GetCurrentProcess();
|
HANDLE hProcess = GetCurrentProcess();
|
||||||
HANDLE hThread = GetCurrentThread();
|
HANDLE hThread = GetCurrentThread();
|
||||||
SymInitialize(hProcess, NULL, TRUE);
|
SymInitializeW(hProcess, QCoreApplication::applicationDirPath().toStdWString().c_str(), TRUE);
|
||||||
|
|
||||||
DWORD64 dwDisplacement;
|
DWORD64 dwDisplacement;
|
||||||
|
|
||||||
@@ -355,5 +355,3 @@ const QString straceWin::getBacktrace()
|
|||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#pragma optimize("g", on)
|
#pragma optimize("g", on)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // STACKTRACE_WIN_H
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "ui_stacktracedialog.h"
|
#include "ui_stacktracedialog.h"
|
||||||
|
|
||||||
StacktraceDialog::StacktraceDialog(QWidget *parent)
|
StacktraceDialog::StacktraceDialog(QWidget *parent)
|
||||||
|
|||||||
@@ -27,8 +27,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STACKTRACEDIALOG_H
|
#pragma once
|
||||||
#define STACKTRACEDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
@@ -51,5 +50,3 @@ public:
|
|||||||
private:
|
private:
|
||||||
Ui::StacktraceDialog *m_ui;
|
Ui::StacktraceDialog *m_ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STACKTRACEDIALOG_H
|
|
||||||
|
|||||||
@@ -29,11 +29,15 @@
|
|||||||
#include "upgrade.h"
|
#include "upgrade.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QMetaEnum>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
#include "base/bittorrent/torrentcontentlayout.h"
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
#include "base/profile.h"
|
#include "base/profile.h"
|
||||||
#include "base/settingsstorage.h"
|
#include "base/settingsstorage.h"
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
|
#include "base/utils/string.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -42,8 +46,8 @@ namespace
|
|||||||
const auto migrate = [](const QString &oldKey, const QString &newKey, const QString &savePath)
|
const auto migrate = [](const QString &oldKey, const QString &newKey, const QString &savePath)
|
||||||
{
|
{
|
||||||
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
||||||
const QByteArray oldData {settingsStorage->loadValue(oldKey).toByteArray()};
|
const auto oldData {settingsStorage->loadValue<QByteArray>(oldKey)};
|
||||||
const QString newData {settingsStorage->loadValue(newKey).toString()};
|
const auto newData {settingsStorage->loadValue<QString>(newKey)};
|
||||||
const QString errorMsgFormat {QObject::tr("Migrate preferences failed: WebUI https, file: \"%1\", error: \"%2\"")};
|
const QString errorMsgFormat {QObject::tr("Migrate preferences failed: WebUI https, file: \"%1\", error: \"%2\"")};
|
||||||
|
|
||||||
if (!newData.isEmpty() || oldData.isEmpty())
|
if (!newData.isEmpty() || oldData.isEmpty())
|
||||||
@@ -78,11 +82,32 @@ namespace
|
|||||||
, QLatin1String("Preferences/WebUI/HTTPS/KeyPath")
|
, QLatin1String("Preferences/WebUI/HTTPS/KeyPath")
|
||||||
, Utils::Fs::toNativePath(configPath + QLatin1String("WebUIPrivateKey.pem")));
|
, Utils::Fs::toNativePath(configPath + QLatin1String("WebUIPrivateKey.pem")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void upgradeTorrentContentLayout()
|
||||||
|
{
|
||||||
|
const QString oldKey {QLatin1String {"BitTorrent/Session/CreateTorrentSubfolder"}};
|
||||||
|
const QString newKey {QLatin1String {"BitTorrent/Session/TorrentContentLayout"}};
|
||||||
|
|
||||||
|
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
||||||
|
const auto oldData {settingsStorage->loadValue<QVariant>(oldKey)};
|
||||||
|
const auto newData {settingsStorage->loadValue<QString>(newKey)};
|
||||||
|
|
||||||
|
if (!newData.isEmpty() || !oldData.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const bool createSubfolder = oldData.toBool();
|
||||||
|
const BitTorrent::TorrentContentLayout torrentContentLayout =
|
||||||
|
(createSubfolder ? BitTorrent::TorrentContentLayout::Original : BitTorrent::TorrentContentLayout::NoSubfolder);
|
||||||
|
|
||||||
|
settingsStorage->storeValue(newKey, Utils::String::fromEnum(torrentContentLayout));
|
||||||
|
settingsStorage->removeValue(oldKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool upgrade(const bool /*ask*/)
|
bool upgrade(const bool /*ask*/)
|
||||||
{
|
{
|
||||||
exportWebUIHttpsFiles();
|
exportWebUIHttpsFiles();
|
||||||
|
upgradeTorrentContentLayout();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +128,7 @@ void handleChangedDefaults(const DefaultPreferencesMode mode)
|
|||||||
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
||||||
for (auto it = changedDefaults.cbegin(); it != changedDefaults.cend(); ++it)
|
for (auto it = changedDefaults.cbegin(); it != changedDefaults.cend(); ++it)
|
||||||
{
|
{
|
||||||
if (settingsStorage->loadValue(it->name).isNull())
|
if (settingsStorage->loadValue<QVariant>(it->name).isNull())
|
||||||
settingsStorage->storeValue(it->name, (mode == DefaultPreferencesMode::Legacy ? it->legacy : it->current));
|
settingsStorage->storeValue(it->name, (mode == DefaultPreferencesMode::Legacy ? it->legacy : it->current));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ add_library(qbt_base STATIC
|
|||||||
# headers
|
# headers
|
||||||
algorithm.h
|
algorithm.h
|
||||||
asyncfilestorage.h
|
asyncfilestorage.h
|
||||||
|
bittorrent/abstractfilestorage.h
|
||||||
bittorrent/addtorrentparams.h
|
bittorrent/addtorrentparams.h
|
||||||
bittorrent/bandwidthscheduler.h
|
bittorrent/bandwidthscheduler.h
|
||||||
bittorrent/cachestatus.h
|
bittorrent/cachestatus.h
|
||||||
bittorrent/common.h
|
bittorrent/common.h
|
||||||
bittorrent/customstorage.h
|
bittorrent/customstorage.h
|
||||||
bittorrent/downloadpriority.h
|
bittorrent/downloadpriority.h
|
||||||
|
bittorrent/filesearcher.h
|
||||||
bittorrent/filterparserthread.h
|
bittorrent/filterparserthread.h
|
||||||
bittorrent/infohash.h
|
bittorrent/infohash.h
|
||||||
bittorrent/ltqhash.h
|
bittorrent/ltqhash.h
|
||||||
@@ -23,12 +25,14 @@ add_library(qbt_base STATIC
|
|||||||
bittorrent/sessionstatus.h
|
bittorrent/sessionstatus.h
|
||||||
bittorrent/speedmonitor.h
|
bittorrent/speedmonitor.h
|
||||||
bittorrent/statistics.h
|
bittorrent/statistics.h
|
||||||
|
bittorrent/torrent.h
|
||||||
|
bittorrent/torrentcontentlayout.h
|
||||||
bittorrent/torrentcreatorthread.h
|
bittorrent/torrentcreatorthread.h
|
||||||
bittorrent/torrenthandle.h
|
bittorrent/torrentimpl.h
|
||||||
bittorrent/torrenthandleimpl.h
|
|
||||||
bittorrent/torrentinfo.h
|
bittorrent/torrentinfo.h
|
||||||
bittorrent/tracker.h
|
bittorrent/tracker.h
|
||||||
bittorrent/trackerentry.h
|
bittorrent/trackerentry.h
|
||||||
|
digest32.h
|
||||||
exceptions.h
|
exceptions.h
|
||||||
filesystemwatcher.h
|
filesystemwatcher.h
|
||||||
global.h
|
global.h
|
||||||
@@ -70,7 +74,6 @@ add_library(qbt_base STATIC
|
|||||||
settingsstorage.h
|
settingsstorage.h
|
||||||
torrentfileguard.h
|
torrentfileguard.h
|
||||||
torrentfilter.h
|
torrentfilter.h
|
||||||
tristatebool.h
|
|
||||||
types.h
|
types.h
|
||||||
unicodestrings.h
|
unicodestrings.h
|
||||||
utils/bytearray.h
|
utils/bytearray.h
|
||||||
@@ -84,12 +87,15 @@ add_library(qbt_base STATIC
|
|||||||
utils/random.h
|
utils/random.h
|
||||||
utils/string.h
|
utils/string.h
|
||||||
utils/version.h
|
utils/version.h
|
||||||
|
version.h
|
||||||
|
|
||||||
# sources
|
# sources
|
||||||
asyncfilestorage.cpp
|
asyncfilestorage.cpp
|
||||||
|
bittorrent/abstractfilestorage.cpp
|
||||||
bittorrent/bandwidthscheduler.cpp
|
bittorrent/bandwidthscheduler.cpp
|
||||||
bittorrent/customstorage.cpp
|
bittorrent/customstorage.cpp
|
||||||
bittorrent/downloadpriority.cpp
|
bittorrent/downloadpriority.cpp
|
||||||
|
bittorrent/filesearcher.cpp
|
||||||
bittorrent/filterparserthread.cpp
|
bittorrent/filterparserthread.cpp
|
||||||
bittorrent/infohash.cpp
|
bittorrent/infohash.cpp
|
||||||
bittorrent/magneturi.cpp
|
bittorrent/magneturi.cpp
|
||||||
@@ -102,9 +108,9 @@ add_library(qbt_base STATIC
|
|||||||
bittorrent/session.cpp
|
bittorrent/session.cpp
|
||||||
bittorrent/speedmonitor.cpp
|
bittorrent/speedmonitor.cpp
|
||||||
bittorrent/statistics.cpp
|
bittorrent/statistics.cpp
|
||||||
|
bittorrent/torrent.cpp
|
||||||
bittorrent/torrentcreatorthread.cpp
|
bittorrent/torrentcreatorthread.cpp
|
||||||
bittorrent/torrenthandle.cpp
|
bittorrent/torrentimpl.cpp
|
||||||
bittorrent/torrenthandleimpl.cpp
|
|
||||||
bittorrent/torrentinfo.cpp
|
bittorrent/torrentinfo.cpp
|
||||||
bittorrent/tracker.cpp
|
bittorrent/tracker.cpp
|
||||||
bittorrent/trackerentry.cpp
|
bittorrent/trackerentry.cpp
|
||||||
@@ -145,7 +151,6 @@ add_library(qbt_base STATIC
|
|||||||
settingsstorage.cpp
|
settingsstorage.cpp
|
||||||
torrentfileguard.cpp
|
torrentfileguard.cpp
|
||||||
torrentfilter.cpp
|
torrentfilter.cpp
|
||||||
tristatebool.cpp
|
|
||||||
utils/bytearray.cpp
|
utils/bytearray.cpp
|
||||||
utils/foreignapps.cpp
|
utils/foreignapps.cpp
|
||||||
utils/fs.cpp
|
utils/fs.cpp
|
||||||
@@ -162,7 +167,6 @@ target_link_libraries(qbt_base
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
OpenSSL::Crypto OpenSSL::SSL
|
OpenSSL::Crypto OpenSSL::SSL
|
||||||
ZLIB::ZLIB
|
ZLIB::ZLIB
|
||||||
qbt_version_definitions
|
|
||||||
PUBLIC
|
PUBLIC
|
||||||
LibtorrentRasterbar::torrent-rasterbar
|
LibtorrentRasterbar::torrent-rasterbar
|
||||||
Qt5::Core Qt5::Network Qt5::Xml
|
Qt5::Core Qt5::Network Qt5::Xml
|
||||||
|
|||||||
@@ -32,9 +32,6 @@
|
|||||||
|
|
||||||
namespace Algorithm
|
namespace Algorithm
|
||||||
{
|
{
|
||||||
template <typename ...>
|
|
||||||
using void_t = void; // replace this with std::void_t in C++17
|
|
||||||
|
|
||||||
template <typename T, typename = void>
|
template <typename T, typename = void>
|
||||||
struct HasMappedType
|
struct HasMappedType
|
||||||
: std::false_type
|
: std::false_type
|
||||||
@@ -42,7 +39,7 @@ namespace Algorithm
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct HasMappedType<T, void_t<typename T::mapped_type>>
|
struct HasMappedType<T, std::void_t<typename T::mapped_type>>
|
||||||
: std::true_type
|
: std::true_type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,13 +55,8 @@ AsyncFileStorage::~AsyncFileStorage()
|
|||||||
|
|
||||||
void AsyncFileStorage::store(const QString &fileName, const QByteArray &data)
|
void AsyncFileStorage::store(const QString &fileName, const QByteArray &data)
|
||||||
{
|
{
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
|
||||||
QMetaObject::invokeMethod(this, [this, data, fileName]() { store_impl(fileName, data); }
|
QMetaObject::invokeMethod(this, [this, data, fileName]() { store_impl(fileName, data); }
|
||||||
, Qt::QueuedConnection);
|
, Qt::QueuedConnection);
|
||||||
#else
|
|
||||||
QMetaObject::invokeMethod(this, "store_impl", Qt::QueuedConnection
|
|
||||||
, Q_ARG(QString, fileName), Q_ARG(QByteArray, data));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir AsyncFileStorage::storageDir() const
|
QDir AsyncFileStorage::storageDir() const
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/algorithm.h \
|
$$PWD/algorithm.h \
|
||||||
$$PWD/asyncfilestorage.h \
|
$$PWD/asyncfilestorage.h \
|
||||||
|
$$PWD/bittorrent/abstractfilestorage.h \
|
||||||
$$PWD/bittorrent/addtorrentparams.h \
|
$$PWD/bittorrent/addtorrentparams.h \
|
||||||
$$PWD/bittorrent/bandwidthscheduler.h \
|
$$PWD/bittorrent/bandwidthscheduler.h \
|
||||||
$$PWD/bittorrent/cachestatus.h \
|
$$PWD/bittorrent/cachestatus.h \
|
||||||
$$PWD/bittorrent/common.h \
|
$$PWD/bittorrent/common.h \
|
||||||
$$PWD/bittorrent/customstorage.h \
|
$$PWD/bittorrent/customstorage.h \
|
||||||
$$PWD/bittorrent/downloadpriority.h \
|
$$PWD/bittorrent/downloadpriority.h \
|
||||||
|
$$PWD/bittorrent/filesearcher.h \
|
||||||
$$PWD/bittorrent/filterparserthread.h \
|
$$PWD/bittorrent/filterparserthread.h \
|
||||||
$$PWD/bittorrent/infohash.h \
|
$$PWD/bittorrent/infohash.h \
|
||||||
$$PWD/bittorrent/ltqhash.h \
|
$$PWD/bittorrent/ltqhash.h \
|
||||||
@@ -22,12 +24,14 @@ HEADERS += \
|
|||||||
$$PWD/bittorrent/sessionstatus.h \
|
$$PWD/bittorrent/sessionstatus.h \
|
||||||
$$PWD/bittorrent/speedmonitor.h \
|
$$PWD/bittorrent/speedmonitor.h \
|
||||||
$$PWD/bittorrent/statistics.h \
|
$$PWD/bittorrent/statistics.h \
|
||||||
|
$$PWD/bittorrent/torrent.h \
|
||||||
|
$$PWD/bittorrent/torrentcontentlayout.h \
|
||||||
$$PWD/bittorrent/torrentcreatorthread.h \
|
$$PWD/bittorrent/torrentcreatorthread.h \
|
||||||
$$PWD/bittorrent/torrenthandle.h \
|
$$PWD/bittorrent/torrentimpl.h \
|
||||||
$$PWD/bittorrent/torrenthandleimpl.h \
|
|
||||||
$$PWD/bittorrent/torrentinfo.h \
|
$$PWD/bittorrent/torrentinfo.h \
|
||||||
$$PWD/bittorrent/tracker.h \
|
$$PWD/bittorrent/tracker.h \
|
||||||
$$PWD/bittorrent/trackerentry.h \
|
$$PWD/bittorrent/trackerentry.h \
|
||||||
|
$$PWD/digest32.h \
|
||||||
$$PWD/exceptions.h \
|
$$PWD/exceptions.h \
|
||||||
$$PWD/filesystemwatcher.h \
|
$$PWD/filesystemwatcher.h \
|
||||||
$$PWD/global.h \
|
$$PWD/global.h \
|
||||||
@@ -70,7 +74,6 @@ HEADERS += \
|
|||||||
$$PWD/settingvalue.h \
|
$$PWD/settingvalue.h \
|
||||||
$$PWD/torrentfileguard.h \
|
$$PWD/torrentfileguard.h \
|
||||||
$$PWD/torrentfilter.h \
|
$$PWD/torrentfilter.h \
|
||||||
$$PWD/tristatebool.h \
|
|
||||||
$$PWD/types.h \
|
$$PWD/types.h \
|
||||||
$$PWD/unicodestrings.h \
|
$$PWD/unicodestrings.h \
|
||||||
$$PWD/utils/bytearray.h \
|
$$PWD/utils/bytearray.h \
|
||||||
@@ -83,13 +86,16 @@ HEADERS += \
|
|||||||
$$PWD/utils/password.h \
|
$$PWD/utils/password.h \
|
||||||
$$PWD/utils/random.h \
|
$$PWD/utils/random.h \
|
||||||
$$PWD/utils/string.h \
|
$$PWD/utils/string.h \
|
||||||
$$PWD/utils/version.h
|
$$PWD/utils/version.h \
|
||||||
|
$$PWD/version.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/asyncfilestorage.cpp \
|
$$PWD/asyncfilestorage.cpp \
|
||||||
|
$$PWD/bittorrent/abstractfilestorage.cpp \
|
||||||
$$PWD/bittorrent/bandwidthscheduler.cpp \
|
$$PWD/bittorrent/bandwidthscheduler.cpp \
|
||||||
$$PWD/bittorrent/customstorage.cpp \
|
$$PWD/bittorrent/customstorage.cpp \
|
||||||
$$PWD/bittorrent/downloadpriority.cpp \
|
$$PWD/bittorrent/downloadpriority.cpp \
|
||||||
|
$$PWD/bittorrent/filesearcher.cpp \
|
||||||
$$PWD/bittorrent/filterparserthread.cpp \
|
$$PWD/bittorrent/filterparserthread.cpp \
|
||||||
$$PWD/bittorrent/infohash.cpp \
|
$$PWD/bittorrent/infohash.cpp \
|
||||||
$$PWD/bittorrent/magneturi.cpp \
|
$$PWD/bittorrent/magneturi.cpp \
|
||||||
@@ -102,9 +108,9 @@ SOURCES += \
|
|||||||
$$PWD/bittorrent/session.cpp \
|
$$PWD/bittorrent/session.cpp \
|
||||||
$$PWD/bittorrent/speedmonitor.cpp \
|
$$PWD/bittorrent/speedmonitor.cpp \
|
||||||
$$PWD/bittorrent/statistics.cpp \
|
$$PWD/bittorrent/statistics.cpp \
|
||||||
|
$$PWD/bittorrent/torrent.cpp \
|
||||||
$$PWD/bittorrent/torrentcreatorthread.cpp \
|
$$PWD/bittorrent/torrentcreatorthread.cpp \
|
||||||
$$PWD/bittorrent/torrenthandle.cpp \
|
$$PWD/bittorrent/torrentimpl.cpp \
|
||||||
$$PWD/bittorrent/torrenthandleimpl.cpp \
|
|
||||||
$$PWD/bittorrent/torrentinfo.cpp \
|
$$PWD/bittorrent/torrentinfo.cpp \
|
||||||
$$PWD/bittorrent/tracker.cpp \
|
$$PWD/bittorrent/tracker.cpp \
|
||||||
$$PWD/bittorrent/trackerentry.cpp \
|
$$PWD/bittorrent/trackerentry.cpp \
|
||||||
@@ -145,7 +151,6 @@ SOURCES += \
|
|||||||
$$PWD/settingsstorage.cpp \
|
$$PWD/settingsstorage.cpp \
|
||||||
$$PWD/torrentfileguard.cpp \
|
$$PWD/torrentfileguard.cpp \
|
||||||
$$PWD/torrentfilter.cpp \
|
$$PWD/torrentfilter.cpp \
|
||||||
$$PWD/tristatebool.cpp \
|
|
||||||
$$PWD/utils/bytearray.cpp \
|
$$PWD/utils/bytearray.cpp \
|
||||||
$$PWD/utils/foreignapps.cpp \
|
$$PWD/utils/foreignapps.cpp \
|
||||||
$$PWD/utils/fs.cpp \
|
$$PWD/utils/fs.cpp \
|
||||||
|
|||||||
138
src/base/bittorrent/abstractfilestorage.cpp
Normal file
138
src/base/bittorrent/abstractfilestorage.cpp
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "abstractfilestorage.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
#include "base/bittorrent/common.h"
|
||||||
|
#include "base/exceptions.h"
|
||||||
|
#include "base/utils/fs.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
const Qt::CaseSensitivity CASE_SENSITIVITY {Qt::CaseInsensitive};
|
||||||
|
#else
|
||||||
|
const Qt::CaseSensitivity CASE_SENSITIVITY {Qt::CaseSensitive};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool areSameFileNames(QString first, QString second)
|
||||||
|
{
|
||||||
|
if (first.endsWith(QB_EXT, Qt::CaseInsensitive))
|
||||||
|
first.chop(QB_EXT.size());
|
||||||
|
if (second.endsWith(QB_EXT, Qt::CaseInsensitive))
|
||||||
|
second.chop(QB_EXT.size());
|
||||||
|
return QString::compare(first, second, CASE_SENSITIVITY) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitTorrent::AbstractFileStorage::renameFile(const QString &oldPath, const QString &newPath)
|
||||||
|
{
|
||||||
|
if (!Utils::Fs::isValidFileSystemName(oldPath, true))
|
||||||
|
throw RuntimeError {tr("The old path is invalid: '%1'.").arg(oldPath)};
|
||||||
|
if (!Utils::Fs::isValidFileSystemName(newPath, true))
|
||||||
|
throw RuntimeError {tr("The new path is invalid: '%1'.").arg(newPath)};
|
||||||
|
|
||||||
|
const QString oldFilePath = Utils::Fs::toUniformPath(oldPath);
|
||||||
|
if (oldFilePath.endsWith(QLatin1Char {'/'}))
|
||||||
|
throw RuntimeError {tr("Invalid file path: '%1'.").arg(oldFilePath)};
|
||||||
|
|
||||||
|
const QString newFilePath = Utils::Fs::toUniformPath(newPath);
|
||||||
|
if (newFilePath.endsWith(QLatin1Char {'/'}))
|
||||||
|
throw RuntimeError {tr("Invalid file path: '%1'.").arg(newFilePath)};
|
||||||
|
if (QDir().isAbsolutePath(newFilePath))
|
||||||
|
throw RuntimeError {tr("Absolute path isn't allowed: '%1'.").arg(newFilePath)};
|
||||||
|
|
||||||
|
int renamingFileIndex = -1;
|
||||||
|
for (int i = 0; i < filesCount(); ++i)
|
||||||
|
{
|
||||||
|
const QString path = filePath(i);
|
||||||
|
|
||||||
|
if ((renamingFileIndex < 0) && areSameFileNames(path, oldFilePath))
|
||||||
|
renamingFileIndex = i;
|
||||||
|
else if (areSameFileNames(path, newFilePath))
|
||||||
|
throw RuntimeError {tr("The file already exists: '%1'.").arg(newFilePath)};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renamingFileIndex < 0)
|
||||||
|
throw RuntimeError {tr("No such file: '%1'.").arg(oldFilePath)};
|
||||||
|
|
||||||
|
const auto extAdjusted = [](const QString &path, const bool needExt) -> QString
|
||||||
|
{
|
||||||
|
if (path.endsWith(QB_EXT, Qt::CaseInsensitive) == needExt)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
return (needExt ? (path + QB_EXT) : (path.left(path.size() - QB_EXT.size())));
|
||||||
|
};
|
||||||
|
|
||||||
|
renameFile(renamingFileIndex, extAdjusted(newFilePath, filePath(renamingFileIndex).endsWith(QB_EXT, Qt::CaseInsensitive)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitTorrent::AbstractFileStorage::renameFolder(const QString &oldPath, const QString &newPath)
|
||||||
|
{
|
||||||
|
if (!Utils::Fs::isValidFileSystemName(oldPath, true))
|
||||||
|
throw RuntimeError {tr("The old path is invalid: '%1'.").arg(oldPath)};
|
||||||
|
if (!Utils::Fs::isValidFileSystemName(newPath, true))
|
||||||
|
throw RuntimeError {tr("The new path is invalid: '%1'.").arg(newPath)};
|
||||||
|
|
||||||
|
const auto cleanFolderPath = [](const QString &path) -> QString
|
||||||
|
{
|
||||||
|
const QString uniformPath = Utils::Fs::toUniformPath(path);
|
||||||
|
return (uniformPath.endsWith(QLatin1Char {'/'}) ? uniformPath : uniformPath + QLatin1Char {'/'});
|
||||||
|
};
|
||||||
|
|
||||||
|
const QString oldFolderPath = cleanFolderPath(oldPath);
|
||||||
|
const QString newFolderPath = cleanFolderPath(newPath);
|
||||||
|
if (QDir().isAbsolutePath(newFolderPath))
|
||||||
|
throw RuntimeError {tr("Absolute path isn't allowed: '%1'.").arg(newFolderPath)};
|
||||||
|
|
||||||
|
QVector<int> renamingFileIndexes;
|
||||||
|
renamingFileIndexes.reserve(filesCount());
|
||||||
|
|
||||||
|
for (int i = 0; i < filesCount(); ++i)
|
||||||
|
{
|
||||||
|
const QString path = filePath(i);
|
||||||
|
|
||||||
|
if (path.startsWith(oldFolderPath, CASE_SENSITIVITY))
|
||||||
|
renamingFileIndexes.append(i);
|
||||||
|
else if (path.startsWith(newFolderPath, CASE_SENSITIVITY))
|
||||||
|
throw RuntimeError {tr("The folder already exists: '%1'.").arg(newFolderPath)};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renamingFileIndexes.isEmpty())
|
||||||
|
throw RuntimeError {tr("No such folder: '%1'.").arg(oldFolderPath)};
|
||||||
|
|
||||||
|
for (const int index : renamingFileIndexes)
|
||||||
|
{
|
||||||
|
const QString newFilePath = newFolderPath + filePath(index).mid(oldFolderPath.size());
|
||||||
|
renameFile(index, newFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/base/bittorrent/abstractfilestorage.h
Normal file
53
src/base/bittorrent/abstractfilestorage.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
namespace BitTorrent
|
||||||
|
{
|
||||||
|
class AbstractFileStorage
|
||||||
|
{
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(AbstractFileStorage)
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int filesCount() const = 0;
|
||||||
|
virtual QString filePath(int index) const = 0;
|
||||||
|
virtual QString fileName(int index) const = 0;
|
||||||
|
virtual qlonglong fileSize(int index) const = 0;
|
||||||
|
|
||||||
|
virtual void renameFile(int index, const QString &name) = 0;
|
||||||
|
|
||||||
|
void renameFile(const QString &oldPath, const QString &newPath);
|
||||||
|
void renameFolder(const QString &oldPath, const QString &newPath);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -28,12 +28,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include "base/tristatebool.h"
|
#include "torrent.h"
|
||||||
#include "torrenthandle.h"
|
#include "torrentcontentlayout.h"
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
@@ -48,15 +50,15 @@ namespace BitTorrent
|
|||||||
bool disableTempPath = false; // e.g. for imported torrents
|
bool disableTempPath = false; // e.g. for imported torrents
|
||||||
bool sequential = false;
|
bool sequential = false;
|
||||||
bool firstLastPiecePriority = false;
|
bool firstLastPiecePriority = false;
|
||||||
TriStateBool addForced;
|
bool addForced = false;
|
||||||
TriStateBool addPaused;
|
std::optional<bool> addPaused;
|
||||||
QVector<DownloadPriority> filePriorities; // used if TorrentInfo is set
|
QVector<DownloadPriority> filePriorities; // used if TorrentInfo is set
|
||||||
bool skipChecking = false;
|
bool skipChecking = false;
|
||||||
TriStateBool createSubfolder;
|
std::optional<BitTorrent::TorrentContentLayout> contentLayout;
|
||||||
TriStateBool useAutoTMM;
|
std::optional<bool> useAutoTMM;
|
||||||
int uploadLimit = -1;
|
int uploadLimit = -1;
|
||||||
int downloadLimit = -1;
|
int downloadLimit = -1;
|
||||||
int seedingTimeLimit = TorrentHandle::USE_GLOBAL_SEEDING_TIME;
|
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
||||||
qreal ratioLimit = TorrentHandle::USE_GLOBAL_RATIO;
|
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BANDWIDTHSCHEDULER_H
|
#pragma once
|
||||||
#define BANDWIDTHSCHEDULER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -52,5 +51,3 @@ private:
|
|||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
bool m_lastAlternative;
|
bool m_lastAlternative;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BANDWIDTHSCHEDULER_H
|
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_CACHESTATUS_H
|
#pragma once
|
||||||
#define BITTORRENT_CACHESTATUS_H
|
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
@@ -39,8 +38,6 @@ namespace BitTorrent
|
|||||||
quint64 jobQueueLength = 0;
|
quint64 jobQueueLength = 0;
|
||||||
quint64 averageJobTime = 0;
|
quint64 averageJobTime = 0;
|
||||||
quint64 queuedBytes = 0;
|
quint64 queuedBytes = 0;
|
||||||
qreal readRatio = 0.0;
|
qreal readRatio = 0; // TODO: remove when LIBTORRENT_VERSION_NUM >= 20000
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_CACHESTATUS_H
|
|
||||||
|
|||||||
@@ -30,5 +30,4 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
// TODO: Make it inline in C++17
|
inline const QString QB_EXT {QStringLiteral(".!qB")};
|
||||||
extern const QString QB_EXT;
|
|
||||||
|
|||||||
69
src/base/bittorrent/filesearcher.cpp
Normal file
69
src/base/bittorrent/filesearcher.cpp
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "filesearcher.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "base/bittorrent/common.h"
|
||||||
|
#include "base/bittorrent/infohash.h"
|
||||||
|
|
||||||
|
void FileSearcher::search(const BitTorrent::TorrentID &id, const QStringList &originalFileNames
|
||||||
|
, const QString &completeSavePath, const QString &incompleteSavePath)
|
||||||
|
{
|
||||||
|
const auto findInDir = [](const QString &dirPath, QStringList &fileNames) -> bool
|
||||||
|
{
|
||||||
|
const QDir dir {dirPath};
|
||||||
|
bool found = false;
|
||||||
|
for (QString &fileName : fileNames)
|
||||||
|
{
|
||||||
|
if (dir.exists(fileName))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
else if (dir.exists(fileName + QB_EXT))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
fileName += QB_EXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
};
|
||||||
|
|
||||||
|
QString savePath = completeSavePath;
|
||||||
|
QStringList adjustedFileNames = originalFileNames;
|
||||||
|
const bool found = findInDir(savePath, adjustedFileNames);
|
||||||
|
if (!found && !incompleteSavePath.isEmpty())
|
||||||
|
{
|
||||||
|
savePath = incompleteSavePath;
|
||||||
|
findInDir(savePath, adjustedFileNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit searchFinished(id, savePath, adjustedFileNames);
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -26,8 +26,27 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tristatebool.h"
|
#pragma once
|
||||||
|
|
||||||
const TriStateBool TriStateBool::Undefined(-1);
|
#include <QObject>
|
||||||
const TriStateBool TriStateBool::False(0);
|
|
||||||
const TriStateBool TriStateBool::True(1);
|
namespace BitTorrent
|
||||||
|
{
|
||||||
|
class TorrentID;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileSearcher final : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(FileSearcher)
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileSearcher() = default;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void search(const BitTorrent::TorrentID &id, const QStringList &originalFileNames
|
||||||
|
, const QString &completeSavePath, const QString &incompleteSavePath);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void searchFinished(const BitTorrent::TorrentID &id, const QString &savePath, const QStringList &fileNames);
|
||||||
|
};
|
||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FILTERPARSERTHREAD_H
|
#pragma once
|
||||||
#define FILTERPARSERTHREAD_H
|
|
||||||
|
|
||||||
#include <libtorrent/ip_filter.hpp>
|
#include <libtorrent/ip_filter.hpp>
|
||||||
|
|
||||||
@@ -64,5 +63,3 @@ private:
|
|||||||
QString m_filePath;
|
QString m_filePath;
|
||||||
lt::ip_filter m_filter;
|
lt::ip_filter m_filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITTORRENT_FILTERPARSERTHREAD_H
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015, 2021 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -28,66 +28,54 @@
|
|||||||
|
|
||||||
#include "infohash.h"
|
#include "infohash.h"
|
||||||
|
|
||||||
#include <QByteArray>
|
const int TorrentIDTypeId = qRegisterMetaType<BitTorrent::TorrentID>();
|
||||||
#include <QHash>
|
|
||||||
|
|
||||||
using namespace BitTorrent;
|
BitTorrent::InfoHash::InfoHash(const WrappedType &nativeHash)
|
||||||
|
: m_valid {true}
|
||||||
InfoHash::InfoHash()
|
, m_nativeHash {nativeHash}
|
||||||
: m_valid(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoHash::InfoHash(const lt::sha1_hash &nativeHash)
|
bool BitTorrent::InfoHash::isValid() const
|
||||||
: m_valid(true)
|
|
||||||
, m_nativeHash(nativeHash)
|
|
||||||
{
|
|
||||||
const QByteArray raw = QByteArray::fromRawData(nativeHash.data(), length());
|
|
||||||
m_hashString = QString::fromLatin1(raw.toHex());
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoHash::InfoHash(const QString &hashString)
|
|
||||||
: m_valid(false)
|
|
||||||
{
|
|
||||||
if (hashString.size() != (length() * 2))
|
|
||||||
return;
|
|
||||||
|
|
||||||
const QByteArray raw = QByteArray::fromHex(hashString.toLatin1());
|
|
||||||
if (raw.size() != length()) // QByteArray::fromHex() will skip over invalid characters
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_valid = true;
|
|
||||||
m_hashString = hashString;
|
|
||||||
m_nativeHash.assign(raw.constData());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InfoHash::isValid() const
|
|
||||||
{
|
{
|
||||||
return m_valid;
|
return m_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoHash::operator lt::sha1_hash() const
|
BitTorrent::TorrentID BitTorrent::InfoHash::toTorrentID() const
|
||||||
|
{
|
||||||
|
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
||||||
|
return m_nativeHash.get_best();
|
||||||
|
#else
|
||||||
|
return {m_nativeHash};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
BitTorrent::InfoHash::operator WrappedType() const
|
||||||
{
|
{
|
||||||
return m_nativeHash;
|
return m_nativeHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoHash::operator QString() const
|
BitTorrent::TorrentID BitTorrent::TorrentID::fromString(const QString &hashString)
|
||||||
{
|
{
|
||||||
return m_hashString;
|
return {BaseType::fromString(hashString)};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitTorrent::operator==(const InfoHash &left, const InfoHash &right)
|
BitTorrent::TorrentID BitTorrent::TorrentID::fromInfoHash(const BitTorrent::InfoHash &infoHash)
|
||||||
{
|
{
|
||||||
return (static_cast<lt::sha1_hash>(left)
|
return infoHash.toTorrentID();
|
||||||
== static_cast<lt::sha1_hash>(right));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitTorrent::operator!=(const InfoHash &left, const InfoHash &right)
|
uint BitTorrent::qHash(const BitTorrent::TorrentID &key, const uint seed)
|
||||||
|
{
|
||||||
|
return ::qHash(std::hash<TorrentID::UnderlyingType>()(key), seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BitTorrent::operator==(const BitTorrent::InfoHash &left, const BitTorrent::InfoHash &right)
|
||||||
|
{
|
||||||
|
return (static_cast<InfoHash::WrappedType>(left) == static_cast<InfoHash::WrappedType>(right));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BitTorrent::operator!=(const BitTorrent::InfoHash &left, const BitTorrent::InfoHash &right)
|
||||||
{
|
{
|
||||||
return !(left == right);
|
return !(left == right);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint BitTorrent::qHash(const InfoHash &key, const uint seed)
|
|
||||||
{
|
|
||||||
return ::qHash((std::hash<lt::sha1_hash> {})(key), seed);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015, 2021 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -26,42 +26,62 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_INFOHASH_H
|
#pragma once
|
||||||
#define BITTORRENT_INFOHASH_H
|
|
||||||
|
|
||||||
#include <libtorrent/sha1_hash.hpp>
|
#include <libtorrent/version.hpp>
|
||||||
|
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
||||||
|
#include <libtorrent/info_hash.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QString>
|
#include <QHash>
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
|
#include "base/digest32.h"
|
||||||
|
|
||||||
|
using SHA1Hash = Digest32<160>;
|
||||||
|
using SHA256Hash = Digest32<256>;
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
|
class InfoHash;
|
||||||
|
|
||||||
|
class TorrentID : public Digest32<160>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BaseType = Digest32<160>;
|
||||||
|
using BaseType::BaseType;
|
||||||
|
|
||||||
|
static TorrentID fromString(const QString &hashString);
|
||||||
|
static TorrentID fromInfoHash(const InfoHash &infoHash);
|
||||||
|
};
|
||||||
|
|
||||||
class InfoHash
|
class InfoHash
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InfoHash();
|
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
||||||
InfoHash(const lt::sha1_hash &nativeHash);
|
using WrappedType = lt::info_hash_t;
|
||||||
InfoHash(const QString &hashString);
|
#else
|
||||||
InfoHash(const InfoHash &other) = default;
|
using WrappedType = lt::sha1_hash;
|
||||||
|
#endif
|
||||||
|
|
||||||
static constexpr int length()
|
InfoHash() = default;
|
||||||
{
|
InfoHash(const InfoHash &other) = default;
|
||||||
return lt::sha1_hash::size();
|
InfoHash(const WrappedType &nativeHash);
|
||||||
}
|
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
TorrentID toTorrentID() const;
|
||||||
|
|
||||||
operator lt::sha1_hash() const;
|
operator WrappedType() const;
|
||||||
operator QString() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_valid;
|
bool m_valid = false;
|
||||||
lt::sha1_hash m_nativeHash;
|
WrappedType m_nativeHash;
|
||||||
QString m_hashString;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint qHash(const TorrentID &key, uint seed);
|
||||||
|
|
||||||
bool operator==(const InfoHash &left, const InfoHash &right);
|
bool operator==(const InfoHash &left, const InfoHash &right);
|
||||||
bool operator!=(const InfoHash &left, const InfoHash &right);
|
bool operator!=(const InfoHash &left, const InfoHash &right);
|
||||||
uint qHash(const InfoHash &key, uint seed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_INFOHASH_H
|
Q_DECLARE_METATYPE(BitTorrent::TorrentID)
|
||||||
|
|||||||
@@ -30,9 +30,6 @@
|
|||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
template <typename ...>
|
|
||||||
using void_t = void; // replace this with std::void_t in C++17
|
|
||||||
|
|
||||||
template <typename T, typename = void>
|
template <typename T, typename = void>
|
||||||
struct HasUnderlyingType
|
struct HasUnderlyingType
|
||||||
: std::false_type
|
: std::false_type
|
||||||
@@ -40,7 +37,7 @@ struct HasUnderlyingType
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct HasUnderlyingType<T, void_t<typename T::underlying_type>>
|
struct HasUnderlyingType<T, std::void_t<typename T::underlying_type>>
|
||||||
: std::true_type
|
: std::true_type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,15 +40,15 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
bool isBitTorrentInfoHash(const QString &string)
|
bool isSHA1Hash(const QString &string)
|
||||||
{
|
{
|
||||||
// There are 2 representations for BitTorrent info hash:
|
// There are 2 representations for BitTorrent info hash:
|
||||||
// 1. 40 chars hex-encoded string
|
// 1. 40 chars hex-encoded string
|
||||||
// == 20 (SHA-1 length in bytes) * 2 (each byte maps to 2 hex characters)
|
// == 20 (SHA-1 length in bytes) * 2 (each byte maps to 2 hex characters)
|
||||||
// 2. 32 chars Base32 encoded string
|
// 2. 32 chars Base32 encoded string
|
||||||
// == 20 (SHA-1 length in bytes) * 1.6 (the efficiency of Base32 encoding)
|
// == 20 (SHA-1 length in bytes) * 1.6 (the efficiency of Base32 encoding)
|
||||||
const int SHA1_HEX_SIZE = BitTorrent::InfoHash::length() * 2;
|
const int SHA1_HEX_SIZE = SHA1Hash::length() * 2;
|
||||||
const int SHA1_BASE32_SIZE = BitTorrent::InfoHash::length() * 1.6;
|
const int SHA1_BASE32_SIZE = SHA1Hash::length() * 1.6;
|
||||||
|
|
||||||
return ((((string.size() == SHA1_HEX_SIZE))
|
return ((((string.size() == SHA1_HEX_SIZE))
|
||||||
&& !string.contains(QRegularExpression(QLatin1String("[^0-9A-Fa-f]"))))
|
&& !string.contains(QRegularExpression(QLatin1String("[^0-9A-Fa-f]"))))
|
||||||
@@ -65,7 +65,7 @@ MagnetUri::MagnetUri(const QString &source)
|
|||||||
{
|
{
|
||||||
if (source.isEmpty()) return;
|
if (source.isEmpty()) return;
|
||||||
|
|
||||||
if (isBitTorrentInfoHash(source))
|
if (isSHA1Hash(source))
|
||||||
m_url = QLatin1String("magnet:?xt=urn:btih:") + source;
|
m_url = QLatin1String("magnet:?xt=urn:btih:") + source;
|
||||||
|
|
||||||
lt::error_code ec;
|
lt::error_code ec;
|
||||||
@@ -73,12 +73,18 @@ MagnetUri::MagnetUri(const QString &source)
|
|||||||
if (ec) return;
|
if (ec) return;
|
||||||
|
|
||||||
m_valid = true;
|
m_valid = true;
|
||||||
m_hash = m_addTorrentParams.info_hash;
|
|
||||||
|
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
||||||
|
m_infoHash = m_addTorrentParams.info_hashes;
|
||||||
|
#else
|
||||||
|
m_infoHash = m_addTorrentParams.info_hash;
|
||||||
|
#endif
|
||||||
|
|
||||||
m_name = QString::fromStdString(m_addTorrentParams.name);
|
m_name = QString::fromStdString(m_addTorrentParams.name);
|
||||||
|
|
||||||
m_trackers.reserve(m_addTorrentParams.trackers.size());
|
m_trackers.reserve(m_addTorrentParams.trackers.size());
|
||||||
for (const std::string &tracker : m_addTorrentParams.trackers)
|
for (const std::string &tracker : m_addTorrentParams.trackers)
|
||||||
m_trackers.append(lt::announce_entry {tracker});
|
m_trackers.append({QString::fromStdString(tracker)});
|
||||||
|
|
||||||
m_urlSeeds.reserve(m_addTorrentParams.url_seeds.size());
|
m_urlSeeds.reserve(m_addTorrentParams.url_seeds.size());
|
||||||
for (const std::string &urlSeed : m_addTorrentParams.url_seeds)
|
for (const std::string &urlSeed : m_addTorrentParams.url_seeds)
|
||||||
@@ -90,9 +96,9 @@ bool MagnetUri::isValid() const
|
|||||||
return m_valid;
|
return m_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoHash MagnetUri::hash() const
|
InfoHash MagnetUri::infoHash() const
|
||||||
{
|
{
|
||||||
return m_hash;
|
return m_infoHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MagnetUri::name() const
|
QString MagnetUri::name() const
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_MAGNETURI_H
|
#pragma once
|
||||||
#define BITTORRENT_MAGNETURI_H
|
|
||||||
|
|
||||||
#include <libtorrent/add_torrent_params.hpp>
|
#include <libtorrent/add_torrent_params.hpp>
|
||||||
|
|
||||||
@@ -47,7 +46,7 @@ namespace BitTorrent
|
|||||||
explicit MagnetUri(const QString &source = {});
|
explicit MagnetUri(const QString &source = {});
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
InfoHash hash() const;
|
InfoHash infoHash() const;
|
||||||
QString name() const;
|
QString name() const;
|
||||||
QVector<TrackerEntry> trackers() const;
|
QVector<TrackerEntry> trackers() const;
|
||||||
QVector<QUrl> urlSeeds() const;
|
QVector<QUrl> urlSeeds() const;
|
||||||
@@ -58,12 +57,10 @@ namespace BitTorrent
|
|||||||
private:
|
private:
|
||||||
bool m_valid;
|
bool m_valid;
|
||||||
QString m_url;
|
QString m_url;
|
||||||
InfoHash m_hash;
|
InfoHash m_infoHash;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QVector<TrackerEntry> m_trackers;
|
QVector<TrackerEntry> m_trackers;
|
||||||
QVector<QUrl> m_urlSeeds;
|
QVector<QUrl> m_urlSeeds;
|
||||||
lt::add_torrent_params m_addTorrentParams;
|
lt::add_torrent_params m_addTorrentParams;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_MAGNETURI_H
|
|
||||||
|
|||||||
@@ -52,3 +52,11 @@ bool NativeTorrentExtension::on_pause()
|
|||||||
// and other extensions to be also invoked.
|
// and other extensions to be also invoked.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeTorrentExtension::on_state(const lt::torrent_status::state_t state)
|
||||||
|
{
|
||||||
|
if (m_state == lt::torrent_status::downloading_metadata)
|
||||||
|
m_torrentHandle.set_flags(lt::torrent_flags::stop_when_ready);
|
||||||
|
|
||||||
|
m_state = state;
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool on_pause() override;
|
bool on_pause() override;
|
||||||
|
void on_state(lt::torrent_status::state_t state) override;
|
||||||
|
|
||||||
lt::torrent_handle m_torrentHandle;
|
lt::torrent_handle m_torrentHandle;
|
||||||
|
lt::torrent_status::state_t m_state = lt::torrent_status::checking_resume_data;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,14 +30,14 @@
|
|||||||
|
|
||||||
#include <QBitArray>
|
#include <QBitArray>
|
||||||
|
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrent.h"
|
||||||
#include "base/net/geoipmanager.h"
|
#include "base/net/geoipmanager.h"
|
||||||
#include "base/unicodestrings.h"
|
#include "base/unicodestrings.h"
|
||||||
#include "peeraddress.h"
|
#include "peeraddress.h"
|
||||||
|
|
||||||
using namespace BitTorrent;
|
using namespace BitTorrent;
|
||||||
|
|
||||||
PeerInfo::PeerInfo(const TorrentHandle *torrent, const lt::peer_info &nativeInfo)
|
PeerInfo::PeerInfo(const Torrent *torrent, const lt::peer_info &nativeInfo)
|
||||||
: m_nativeInfo(nativeInfo)
|
: m_nativeInfo(nativeInfo)
|
||||||
{
|
{
|
||||||
calcRelevance(torrent);
|
calcRelevance(torrent);
|
||||||
@@ -226,7 +226,7 @@ QString PeerInfo::connectionType() const
|
|||||||
: QLatin1String {"Web"};
|
: QLatin1String {"Web"};
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerInfo::calcRelevance(const TorrentHandle *torrent)
|
void PeerInfo::calcRelevance(const Torrent *torrent)
|
||||||
{
|
{
|
||||||
const QBitArray allPieces = torrent->pieces();
|
const QBitArray allPieces = torrent->pieces();
|
||||||
const QBitArray peerPieces = pieces();
|
const QBitArray peerPieces = pieces();
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_PEERINFO_H
|
#pragma once
|
||||||
#define BITTORRENT_PEERINFO_H
|
|
||||||
|
|
||||||
#include <libtorrent/peer_info.hpp>
|
#include <libtorrent/peer_info.hpp>
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ class QBitArray;
|
|||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class TorrentHandle;
|
class Torrent;
|
||||||
struct PeerAddress;
|
struct PeerAddress;
|
||||||
|
|
||||||
class PeerInfo
|
class PeerInfo
|
||||||
@@ -46,7 +45,7 @@ namespace BitTorrent
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
PeerInfo() = default;
|
PeerInfo() = default;
|
||||||
PeerInfo(const TorrentHandle *torrent, const lt::peer_info &nativeInfo);
|
PeerInfo(const Torrent *torrent, const lt::peer_info &nativeInfo);
|
||||||
|
|
||||||
bool fromDHT() const;
|
bool fromDHT() const;
|
||||||
bool fromPeX() const;
|
bool fromPeX() const;
|
||||||
@@ -93,7 +92,7 @@ namespace BitTorrent
|
|||||||
int downloadingPieceIndex() const;
|
int downloadingPieceIndex() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void calcRelevance(const TorrentHandle *torrent);
|
void calcRelevance(const Torrent *torrent);
|
||||||
void determineFlags();
|
void determineFlags();
|
||||||
|
|
||||||
lt::peer_info m_nativeInfo = {};
|
lt::peer_info m_nativeInfo = {};
|
||||||
@@ -104,5 +103,3 @@ namespace BitTorrent
|
|||||||
mutable QString m_country;
|
mutable QString m_country;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_PEERINFO_H
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const QString KEY_ENABLED = QStringLiteral("Network/PortForwardingEnabled");
|
|||||||
|
|
||||||
PortForwarderImpl::PortForwarderImpl(lt::session *provider, QObject *parent)
|
PortForwarderImpl::PortForwarderImpl(lt::session *provider, QObject *parent)
|
||||||
: Net::PortForwarder {parent}
|
: Net::PortForwarder {parent}
|
||||||
, m_active {SettingsStorage::instance()->loadValue(KEY_ENABLED, true).toBool()}
|
, m_active {SettingsStorage::instance()->loadValue(KEY_ENABLED, true)}
|
||||||
, m_provider {provider}
|
, m_provider {provider}
|
||||||
{
|
{
|
||||||
if (m_active)
|
if (m_active)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -27,10 +27,10 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_SESSION_H
|
#pragma once
|
||||||
#define BITTORRENT_SESSION_H
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <libtorrent/add_torrent_params.hpp>
|
#include <libtorrent/add_torrent_params.hpp>
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
#include <QtContainerFwd>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include "base/settingvalue.h"
|
#include "base/settingvalue.h"
|
||||||
@@ -50,20 +51,16 @@
|
|||||||
#include "sessionstatus.h"
|
#include "sessionstatus.h"
|
||||||
#include "torrentinfo.h"
|
#include "torrentinfo.h"
|
||||||
|
|
||||||
#if ((LIBTORRENT_VERSION_NUM >= 10206) && !defined(Q_OS_WIN))
|
|
||||||
#define HAS_HTTPS_TRACKER_VALIDATION
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class QFile;
|
class QFile;
|
||||||
class QNetworkConfiguration;
|
class QNetworkConfiguration;
|
||||||
class QNetworkConfigurationManager;
|
class QNetworkConfigurationManager;
|
||||||
class QString;
|
class QString;
|
||||||
class QStringList;
|
|
||||||
class QThread;
|
class QThread;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
|
||||||
class BandwidthScheduler;
|
class BandwidthScheduler;
|
||||||
|
class FileSearcher;
|
||||||
class FilterParserThread;
|
class FilterParserThread;
|
||||||
class ResumeDataSavingManager;
|
class ResumeDataSavingManager;
|
||||||
class Statistics;
|
class Statistics;
|
||||||
@@ -80,8 +77,8 @@ enum MaxRatioAction
|
|||||||
|
|
||||||
enum DeleteOption
|
enum DeleteOption
|
||||||
{
|
{
|
||||||
Torrent,
|
DeleteTorrent,
|
||||||
TorrentAndFiles
|
DeleteTorrentAndFiles
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TorrentExportFolder
|
enum TorrentExportFolder
|
||||||
@@ -99,18 +96,18 @@ namespace BitTorrent
|
|||||||
{
|
{
|
||||||
class InfoHash;
|
class InfoHash;
|
||||||
class MagnetUri;
|
class MagnetUri;
|
||||||
class TorrentHandle;
|
class Torrent;
|
||||||
class TorrentHandleImpl;
|
class TorrentImpl;
|
||||||
class Tracker;
|
class Tracker;
|
||||||
class TrackerEntry;
|
|
||||||
struct LoadTorrentParams;
|
struct LoadTorrentParams;
|
||||||
|
struct TrackerEntry;
|
||||||
|
|
||||||
enum class MoveStorageMode;
|
enum class MoveStorageMode;
|
||||||
|
|
||||||
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
||||||
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
||||||
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
||||||
namespace SessionSettingsEnums
|
inline namespace SessionSettingsEnums
|
||||||
{
|
{
|
||||||
Q_NAMESPACE
|
Q_NAMESPACE
|
||||||
|
|
||||||
@@ -156,49 +153,50 @@ namespace BitTorrent
|
|||||||
Q_ENUM_NS(OSMemoryPriority)
|
Q_ENUM_NS(OSMemoryPriority)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
using namespace SessionSettingsEnums;
|
|
||||||
|
|
||||||
struct SessionMetricIndices
|
struct SessionMetricIndices
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int hasIncomingConnections = 0;
|
int hasIncomingConnections = -1;
|
||||||
int sentPayloadBytes = 0;
|
int sentPayloadBytes = -1;
|
||||||
int recvPayloadBytes = 0;
|
int recvPayloadBytes = -1;
|
||||||
int sentBytes = 0;
|
int sentBytes = -1;
|
||||||
int recvBytes = 0;
|
int recvBytes = -1;
|
||||||
int sentIPOverheadBytes = 0;
|
int sentIPOverheadBytes = -1;
|
||||||
int recvIPOverheadBytes = 0;
|
int recvIPOverheadBytes = -1;
|
||||||
int sentTrackerBytes = 0;
|
int sentTrackerBytes = -1;
|
||||||
int recvTrackerBytes = 0;
|
int recvTrackerBytes = -1;
|
||||||
int recvRedundantBytes = 0;
|
int recvRedundantBytes = -1;
|
||||||
int recvFailedBytes = 0;
|
int recvFailedBytes = -1;
|
||||||
} net;
|
} net;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int numPeersConnected = 0;
|
int numPeersConnected = -1;
|
||||||
int numPeersUpDisk = 0;
|
int numPeersUpDisk = -1;
|
||||||
int numPeersDownDisk = 0;
|
int numPeersDownDisk = -1;
|
||||||
} peer;
|
} peer;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int dhtBytesIn = 0;
|
int dhtBytesIn = -1;
|
||||||
int dhtBytesOut = 0;
|
int dhtBytesOut = -1;
|
||||||
int dhtNodes = 0;
|
int dhtNodes = -1;
|
||||||
} dht;
|
} dht;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int diskBlocksInUse = 0;
|
int diskBlocksInUse = -1;
|
||||||
int numBlocksRead = 0;
|
int numBlocksRead = -1;
|
||||||
int numBlocksCacheHits = 0;
|
#if (LIBTORRENT_VERSION_NUM < 20000)
|
||||||
int writeJobs = 0;
|
int numBlocksCacheHits = -1;
|
||||||
int readJobs = 0;
|
#endif
|
||||||
int hashJobs = 0;
|
int writeJobs = -1;
|
||||||
int queuedDiskJobs = 0;
|
int readJobs = -1;
|
||||||
int diskJobTime = 0;
|
int hashJobs = -1;
|
||||||
|
int queuedDiskJobs = -1;
|
||||||
|
int diskJobTime = -1;
|
||||||
} disk;
|
} disk;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -270,8 +268,8 @@ namespace BitTorrent
|
|||||||
void setPeXEnabled(bool enabled);
|
void setPeXEnabled(bool enabled);
|
||||||
bool isAddTorrentPaused() const;
|
bool isAddTorrentPaused() const;
|
||||||
void setAddTorrentPaused(bool value);
|
void setAddTorrentPaused(bool value);
|
||||||
bool isKeepTorrentTopLevelFolder() const;
|
TorrentContentLayout torrentContentLayout() const;
|
||||||
void setKeepTorrentTopLevelFolder(bool value);
|
void setTorrentContentLayout(TorrentContentLayout value);
|
||||||
bool isTrackerEnabled() const;
|
bool isTrackerEnabled() const;
|
||||||
void setTrackerEnabled(bool enabled);
|
void setTrackerEnabled(bool enabled);
|
||||||
bool isAppendExtensionEnabled() const;
|
bool isAppendExtensionEnabled() const;
|
||||||
@@ -386,6 +384,8 @@ namespace BitTorrent
|
|||||||
void setOutgoingPortsMax(int max);
|
void setOutgoingPortsMax(int max);
|
||||||
int UPnPLeaseDuration() const;
|
int UPnPLeaseDuration() const;
|
||||||
void setUPnPLeaseDuration(int duration);
|
void setUPnPLeaseDuration(int duration);
|
||||||
|
int peerToS() const;
|
||||||
|
void setPeerToS(int value);
|
||||||
bool ignoreLimitsOnLAN() const;
|
bool ignoreLimitsOnLAN() const;
|
||||||
void setIgnoreLimitsOnLAN(bool ignore);
|
void setIgnoreLimitsOnLAN(bool ignore);
|
||||||
bool includeOverheadInLimits() const;
|
bool includeOverheadInLimits() const;
|
||||||
@@ -416,6 +416,8 @@ namespace BitTorrent
|
|||||||
void setUTPRateLimited(bool limited);
|
void setUTPRateLimited(bool limited);
|
||||||
MixedModeAlgorithm utpMixedMode() const;
|
MixedModeAlgorithm utpMixedMode() const;
|
||||||
void setUtpMixedMode(MixedModeAlgorithm mode);
|
void setUtpMixedMode(MixedModeAlgorithm mode);
|
||||||
|
bool isIDNSupportEnabled() const;
|
||||||
|
void setIDNSupportEnabled(bool enabled);
|
||||||
bool multiConnectionsPerIpEnabled() const;
|
bool multiConnectionsPerIpEnabled() const;
|
||||||
void setMultiConnectionsPerIpEnabled(bool enabled);
|
void setMultiConnectionsPerIpEnabled(bool enabled);
|
||||||
bool validateHTTPSTrackerCertificate() const;
|
bool validateHTTPSTrackerCertificate() const;
|
||||||
@@ -432,8 +434,8 @@ namespace BitTorrent
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void startUpTorrents();
|
void startUpTorrents();
|
||||||
TorrentHandle *findTorrent(const InfoHash &hash) const;
|
Torrent *findTorrent(const TorrentID &id) const;
|
||||||
QVector<TorrentHandle *> torrents() const;
|
QVector<Torrent *> torrents() const;
|
||||||
bool hasActiveTorrents() const;
|
bool hasActiveTorrents() const;
|
||||||
bool hasUnfinishedTorrents() const;
|
bool hasUnfinishedTorrents() const;
|
||||||
bool hasRunningSeed() const;
|
bool hasRunningSeed() const;
|
||||||
@@ -448,45 +450,48 @@ namespace BitTorrent
|
|||||||
|
|
||||||
void banIP(const QString &ip);
|
void banIP(const QString &ip);
|
||||||
|
|
||||||
bool isKnownTorrent(const InfoHash &hash) const;
|
bool isKnownTorrent(const TorrentID &id) const;
|
||||||
bool addTorrent(const QString &source, const AddTorrentParams ¶ms = AddTorrentParams());
|
bool addTorrent(const QString &source, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||||
bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams ¶ms = AddTorrentParams());
|
bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||||
bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms = AddTorrentParams());
|
bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||||
bool deleteTorrent(const InfoHash &hash, DeleteOption deleteOption = Torrent);
|
bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteTorrent);
|
||||||
bool loadMetadata(const MagnetUri &magnetUri);
|
bool downloadMetadata(const MagnetUri &magnetUri);
|
||||||
bool cancelLoadMetadata(const InfoHash &hash);
|
bool cancelDownloadMetadata(const TorrentID &id);
|
||||||
|
|
||||||
void recursiveTorrentDownload(const InfoHash &hash);
|
void recursiveTorrentDownload(const TorrentID &id);
|
||||||
void increaseTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
void increaseTorrentsQueuePos(const QVector<TorrentID> &ids);
|
||||||
void decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
void decreaseTorrentsQueuePos(const QVector<TorrentID> &ids);
|
||||||
void topTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
void topTorrentsQueuePos(const QVector<TorrentID> &ids);
|
||||||
void bottomTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
void bottomTorrentsQueuePos(const QVector<TorrentID> &ids);
|
||||||
|
|
||||||
// TorrentHandle interface
|
// Torrent interface
|
||||||
void handleTorrentSaveResumeDataRequested(const TorrentHandleImpl *torrent);
|
void handleTorrentNeedSaveResumeData(const TorrentImpl *torrent);
|
||||||
void handleTorrentShareLimitChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentSaveResumeDataRequested(const TorrentImpl *torrent);
|
||||||
void handleTorrentNameChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentShareLimitChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentSavePathChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentNameChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentCategoryChanged(TorrentHandleImpl *const torrent, const QString &oldCategory);
|
void handleTorrentSavePathChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentTagAdded(TorrentHandleImpl *const torrent, const QString &tag);
|
void handleTorrentCategoryChanged(TorrentImpl *const torrent, const QString &oldCategory);
|
||||||
void handleTorrentTagRemoved(TorrentHandleImpl *const torrent, const QString &tag);
|
void handleTorrentTagAdded(TorrentImpl *const torrent, const QString &tag);
|
||||||
void handleTorrentSavingModeChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentTagRemoved(TorrentImpl *const torrent, const QString &tag);
|
||||||
void handleTorrentMetadataReceived(TorrentHandleImpl *const torrent);
|
void handleTorrentSavingModeChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentPaused(TorrentHandleImpl *const torrent);
|
void handleTorrentMetadataReceived(TorrentImpl *const torrent);
|
||||||
void handleTorrentResumed(TorrentHandleImpl *const torrent);
|
void handleTorrentPaused(TorrentImpl *const torrent);
|
||||||
void handleTorrentChecked(TorrentHandleImpl *const torrent);
|
void handleTorrentResumed(TorrentImpl *const torrent);
|
||||||
void handleTorrentFinished(TorrentHandleImpl *const torrent);
|
void handleTorrentChecked(TorrentImpl *const torrent);
|
||||||
void handleTorrentTrackersAdded(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &newTrackers);
|
void handleTorrentFinished(TorrentImpl *const torrent);
|
||||||
void handleTorrentTrackersRemoved(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers);
|
void handleTorrentTrackersAdded(TorrentImpl *const torrent, const QVector<TrackerEntry> &newTrackers);
|
||||||
void handleTorrentTrackersChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentTrackersRemoved(TorrentImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers);
|
||||||
void handleTorrentUrlSeedsAdded(TorrentHandleImpl *const torrent, const QVector<QUrl> &newUrlSeeds);
|
void handleTorrentTrackersChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentUrlSeedsRemoved(TorrentHandleImpl *const torrent, const QVector<QUrl> &urlSeeds);
|
void handleTorrentUrlSeedsAdded(TorrentImpl *const torrent, const QVector<QUrl> &newUrlSeeds);
|
||||||
void handleTorrentResumeDataReady(TorrentHandleImpl *const torrent, const std::shared_ptr<lt::entry> &data);
|
void handleTorrentUrlSeedsRemoved(TorrentImpl *const torrent, const QVector<QUrl> &urlSeeds);
|
||||||
void handleTorrentTrackerReply(TorrentHandleImpl *const torrent, const QString &trackerUrl);
|
void handleTorrentResumeDataReady(TorrentImpl *const torrent, const LoadTorrentParams &data);
|
||||||
void handleTorrentTrackerWarning(TorrentHandleImpl *const torrent, const QString &trackerUrl);
|
void handleTorrentTrackerReply(TorrentImpl *const torrent, const QString &trackerUrl);
|
||||||
void handleTorrentTrackerError(TorrentHandleImpl *const torrent, const QString &trackerUrl);
|
void handleTorrentTrackerWarning(TorrentImpl *const torrent, const QString &trackerUrl);
|
||||||
|
void handleTorrentTrackerError(TorrentImpl *const torrent, const QString &trackerUrl);
|
||||||
|
|
||||||
bool addMoveTorrentStorageJob(TorrentHandleImpl *torrent, const QString &newPath, MoveStorageMode mode);
|
bool addMoveTorrentStorageJob(TorrentImpl *torrent, const QString &newPath, MoveStorageMode mode);
|
||||||
|
|
||||||
|
void findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void allTorrentsFinished();
|
void allTorrentsFinished();
|
||||||
@@ -494,39 +499,37 @@ namespace BitTorrent
|
|||||||
void categoryRemoved(const QString &categoryName);
|
void categoryRemoved(const QString &categoryName);
|
||||||
void downloadFromUrlFailed(const QString &url, const QString &reason);
|
void downloadFromUrlFailed(const QString &url, const QString &reason);
|
||||||
void downloadFromUrlFinished(const QString &url);
|
void downloadFromUrlFinished(const QString &url);
|
||||||
void fullDiskError(TorrentHandle *torrent, const QString &msg);
|
void fullDiskError(Torrent *torrent, const QString &msg);
|
||||||
void IPFilterParsed(bool error, int ruleCount);
|
void IPFilterParsed(bool error, int ruleCount);
|
||||||
void loadTorrentFailed(const QString &error);
|
void loadTorrentFailed(const QString &error);
|
||||||
void metadataLoaded(const TorrentInfo &info);
|
void metadataDownloaded(const TorrentInfo &info);
|
||||||
void recursiveTorrentDownloadPossible(TorrentHandle *torrent);
|
void recursiveTorrentDownloadPossible(Torrent *torrent);
|
||||||
void speedLimitModeChanged(bool alternative);
|
void speedLimitModeChanged(bool alternative);
|
||||||
void statsUpdated();
|
void statsUpdated();
|
||||||
void subcategoriesSupportChanged();
|
void subcategoriesSupportChanged();
|
||||||
void tagAdded(const QString &tag);
|
void tagAdded(const QString &tag);
|
||||||
void tagRemoved(const QString &tag);
|
void tagRemoved(const QString &tag);
|
||||||
void torrentAboutToBeRemoved(TorrentHandle *torrent);
|
void torrentAboutToBeRemoved(Torrent *torrent);
|
||||||
void torrentAdded(TorrentHandle *torrent);
|
void torrentAdded(Torrent *torrent);
|
||||||
void torrentCategoryChanged(TorrentHandle *torrent, const QString &oldCategory);
|
void torrentCategoryChanged(Torrent *torrent, const QString &oldCategory);
|
||||||
void torrentFinished(TorrentHandle *torrent);
|
void torrentFinished(Torrent *torrent);
|
||||||
void torrentFinishedChecking(TorrentHandle *torrent);
|
void torrentFinishedChecking(Torrent *torrent);
|
||||||
void torrentLoaded(TorrentHandle *torrent);
|
void torrentLoaded(Torrent *torrent);
|
||||||
void torrentMetadataLoaded(TorrentHandle *torrent);
|
void torrentMetadataReceived(Torrent *torrent);
|
||||||
void torrentPaused(TorrentHandle *torrent);
|
void torrentPaused(Torrent *torrent);
|
||||||
void torrentResumed(TorrentHandle *torrent);
|
void torrentResumed(Torrent *torrent);
|
||||||
void torrentSavePathChanged(TorrentHandle *torrent);
|
void torrentSavePathChanged(Torrent *torrent);
|
||||||
void torrentSavingModeChanged(TorrentHandle *torrent);
|
void torrentSavingModeChanged(Torrent *torrent);
|
||||||
void torrentStorageMoveFailed(TorrentHandle *torrent, const QString &targetPath, const QString &error);
|
void torrentsUpdated(const QVector<Torrent *> &torrents);
|
||||||
void torrentStorageMoveFinished(TorrentHandle *torrent, const QString &newPath);
|
void torrentTagAdded(Torrent *torrent, const QString &tag);
|
||||||
void torrentsUpdated(const QVector<TorrentHandle *> &torrents);
|
void torrentTagRemoved(Torrent *torrent, const QString &tag);
|
||||||
void torrentTagAdded(TorrentHandle *torrent, const QString &tag);
|
void trackerError(Torrent *torrent, const QString &tracker);
|
||||||
void torrentTagRemoved(TorrentHandle *torrent, const QString &tag);
|
void trackerlessStateChanged(Torrent *torrent, bool trackerless);
|
||||||
void trackerError(TorrentHandle *torrent, const QString &tracker);
|
void trackersAdded(Torrent *torrent, const QVector<TrackerEntry> &trackers);
|
||||||
void trackerlessStateChanged(TorrentHandle *torrent, bool trackerless);
|
void trackersChanged(Torrent *torrent);
|
||||||
void trackersAdded(TorrentHandle *torrent, const QVector<TrackerEntry> &trackers);
|
void trackersRemoved(Torrent *torrent, const QVector<TrackerEntry> &trackers);
|
||||||
void trackersChanged(TorrentHandle *torrent);
|
void trackerSuccess(Torrent *torrent, const QString &tracker);
|
||||||
void trackersRemoved(TorrentHandle *torrent, const QVector<TrackerEntry> &trackers);
|
void trackerWarning(Torrent *torrent, const QString &tracker);
|
||||||
void trackerSuccess(TorrentHandle *torrent, const QString &tracker);
|
|
||||||
void trackerWarning(TorrentHandle *torrent, const QString &tracker);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void configureDeferred();
|
void configureDeferred();
|
||||||
@@ -537,6 +540,7 @@ namespace BitTorrent
|
|||||||
void handleIPFilterParsed(int ruleCount);
|
void handleIPFilterParsed(int ruleCount);
|
||||||
void handleIPFilterError();
|
void handleIPFilterError();
|
||||||
void handleDownloadFinished(const Net::DownloadResult &result);
|
void handleDownloadFinished(const Net::DownloadResult &result);
|
||||||
|
void fileSearchFinished(const TorrentID &id, const QString &savePath, const QStringList &fileNames);
|
||||||
|
|
||||||
// Session reconfiguration triggers
|
// Session reconfiguration triggers
|
||||||
void networkOnlineStateChanged(bool online);
|
void networkOnlineStateChanged(bool online);
|
||||||
@@ -592,11 +596,10 @@ namespace BitTorrent
|
|||||||
bool loadTorrentResumeData(const QByteArray &data, const TorrentInfo &metadata, LoadTorrentParams &torrentParams);
|
bool loadTorrentResumeData(const QByteArray &data, const TorrentInfo &metadata, LoadTorrentParams &torrentParams);
|
||||||
bool loadTorrent(LoadTorrentParams params);
|
bool loadTorrent(LoadTorrentParams params);
|
||||||
LoadTorrentParams initLoadTorrentParams(const AddTorrentParams &addTorrentParams);
|
LoadTorrentParams initLoadTorrentParams(const AddTorrentParams &addTorrentParams);
|
||||||
bool addTorrent_impl(const AddTorrentParams &addTorrentParams, const MagnetUri &magnetUri, TorrentInfo torrentInfo = TorrentInfo());
|
bool addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source, const AddTorrentParams &addTorrentParams);
|
||||||
bool findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const;
|
|
||||||
|
|
||||||
void updateSeedingLimitTimer();
|
void updateSeedingLimitTimer();
|
||||||
void exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
void exportTorrentFile(const Torrent *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
||||||
|
|
||||||
void handleAlert(const lt::alert *a);
|
void handleAlert(const lt::alert *a);
|
||||||
void dispatchTorrentAlert(const lt::alert *a);
|
void dispatchTorrentAlert(const lt::alert *a);
|
||||||
@@ -604,9 +607,6 @@ namespace BitTorrent
|
|||||||
void handleStateUpdateAlert(const lt::state_update_alert *p);
|
void handleStateUpdateAlert(const lt::state_update_alert *p);
|
||||||
void handleMetadataReceivedAlert(const lt::metadata_received_alert *p);
|
void handleMetadataReceivedAlert(const lt::metadata_received_alert *p);
|
||||||
void handleFileErrorAlert(const lt::file_error_alert *p);
|
void handleFileErrorAlert(const lt::file_error_alert *p);
|
||||||
#if (LIBTORRENT_VERSION_NUM < 10208)
|
|
||||||
void handleReadPieceAlert(const lt::read_piece_alert *p) const;
|
|
||||||
#endif
|
|
||||||
void handleTorrentRemovedAlert(const lt::torrent_removed_alert *p);
|
void handleTorrentRemovedAlert(const lt::torrent_removed_alert *p);
|
||||||
void handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p);
|
void handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p);
|
||||||
void handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *p);
|
void handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *p);
|
||||||
@@ -622,15 +622,13 @@ namespace BitTorrent
|
|||||||
void handleAlertsDroppedAlert(const lt::alerts_dropped_alert *p) const;
|
void handleAlertsDroppedAlert(const lt::alerts_dropped_alert *p) const;
|
||||||
void handleStorageMovedAlert(const lt::storage_moved_alert *p);
|
void handleStorageMovedAlert(const lt::storage_moved_alert *p);
|
||||||
void handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert *p);
|
void handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert *p);
|
||||||
#if (LIBTORRENT_VERSION_NUM >= 10204)
|
|
||||||
void handleSocks5Alert(const lt::socks5_alert *p) const;
|
void handleSocks5Alert(const lt::socks5_alert *p) const;
|
||||||
#endif
|
|
||||||
|
|
||||||
void createTorrentHandle(const lt::torrent_handle &nativeHandle);
|
void createTorrent(const lt::torrent_handle &nativeHandle);
|
||||||
|
|
||||||
void saveResumeData();
|
void saveResumeData();
|
||||||
void saveTorrentsQueue();
|
void saveTorrentsQueue() const;
|
||||||
void removeTorrentsQueue();
|
void removeTorrentsQueue() const;
|
||||||
|
|
||||||
std::vector<lt::alert *> getPendingAlerts(lt::time_duration time = lt::time_duration::zero()) const;
|
std::vector<lt::alert *> getPendingAlerts(lt::time_duration time = lt::time_duration::zero()) const;
|
||||||
|
|
||||||
@@ -678,6 +676,7 @@ namespace BitTorrent
|
|||||||
CachedSettingValue<int> m_outgoingPortsMin;
|
CachedSettingValue<int> m_outgoingPortsMin;
|
||||||
CachedSettingValue<int> m_outgoingPortsMax;
|
CachedSettingValue<int> m_outgoingPortsMax;
|
||||||
CachedSettingValue<int> m_UPnPLeaseDuration;
|
CachedSettingValue<int> m_UPnPLeaseDuration;
|
||||||
|
CachedSettingValue<int> m_peerToS;
|
||||||
CachedSettingValue<bool> m_ignoreLimitsOnLAN;
|
CachedSettingValue<bool> m_ignoreLimitsOnLAN;
|
||||||
CachedSettingValue<bool> m_includeOverheadInLimits;
|
CachedSettingValue<bool> m_includeOverheadInLimits;
|
||||||
CachedSettingValue<QString> m_announceIP;
|
CachedSettingValue<QString> m_announceIP;
|
||||||
@@ -690,6 +689,7 @@ namespace BitTorrent
|
|||||||
CachedSettingValue<BTProtocol> m_btProtocol;
|
CachedSettingValue<BTProtocol> m_btProtocol;
|
||||||
CachedSettingValue<bool> m_isUTPRateLimited;
|
CachedSettingValue<bool> m_isUTPRateLimited;
|
||||||
CachedSettingValue<MixedModeAlgorithm> m_utpMixedMode;
|
CachedSettingValue<MixedModeAlgorithm> m_utpMixedMode;
|
||||||
|
CachedSettingValue<bool> m_IDNSupportEnabled;
|
||||||
CachedSettingValue<bool> m_multiConnectionsPerIpEnabled;
|
CachedSettingValue<bool> m_multiConnectionsPerIpEnabled;
|
||||||
CachedSettingValue<bool> m_validateHTTPSTrackerCertificate;
|
CachedSettingValue<bool> m_validateHTTPSTrackerCertificate;
|
||||||
CachedSettingValue<bool> m_blockPeersOnPrivilegedPorts;
|
CachedSettingValue<bool> m_blockPeersOnPrivilegedPorts;
|
||||||
@@ -698,7 +698,7 @@ namespace BitTorrent
|
|||||||
CachedSettingValue<qreal> m_globalMaxRatio;
|
CachedSettingValue<qreal> m_globalMaxRatio;
|
||||||
CachedSettingValue<int> m_globalMaxSeedingMinutes;
|
CachedSettingValue<int> m_globalMaxSeedingMinutes;
|
||||||
CachedSettingValue<bool> m_isAddTorrentPaused;
|
CachedSettingValue<bool> m_isAddTorrentPaused;
|
||||||
CachedSettingValue<bool> m_isKeepTorrentTopLevelFolder;
|
CachedSettingValue<TorrentContentLayout> m_torrentContentLayout;
|
||||||
CachedSettingValue<bool> m_isAppendExtensionEnabled;
|
CachedSettingValue<bool> m_isAppendExtensionEnabled;
|
||||||
CachedSettingValue<int> m_refreshInterval;
|
CachedSettingValue<int> m_refreshInterval;
|
||||||
CachedSettingValue<bool> m_isPreallocationEnabled;
|
CachedSettingValue<bool> m_isPreallocationEnabled;
|
||||||
@@ -763,18 +763,20 @@ namespace BitTorrent
|
|||||||
// fastresume data writing thread
|
// fastresume data writing thread
|
||||||
QThread *m_ioThread = nullptr;
|
QThread *m_ioThread = nullptr;
|
||||||
ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
|
ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
|
||||||
|
FileSearcher *m_fileSearcher = nullptr;
|
||||||
|
|
||||||
QSet<InfoHash> m_loadedMetadata;
|
QSet<TorrentID> m_downloadedMetadata;
|
||||||
|
|
||||||
QHash<InfoHash, TorrentHandleImpl *> m_torrents;
|
QHash<TorrentID, TorrentImpl *> m_torrents;
|
||||||
QHash<InfoHash, LoadTorrentParams> m_loadingTorrents;
|
QHash<TorrentID, LoadTorrentParams> m_loadingTorrents;
|
||||||
QHash<QString, AddTorrentParams> m_downloadedTorrents;
|
QHash<QString, AddTorrentParams> m_downloadedTorrents;
|
||||||
QHash<InfoHash, RemovingTorrentData> m_removingTorrents;
|
QHash<TorrentID, RemovingTorrentData> m_removingTorrents;
|
||||||
|
QSet<TorrentID> m_needSaveResumeDataTorrents;
|
||||||
QStringMap m_categories;
|
QStringMap m_categories;
|
||||||
QSet<QString> m_tags;
|
QSet<QString> m_tags;
|
||||||
|
|
||||||
// I/O errored torrents
|
// I/O errored torrents
|
||||||
QSet<InfoHash> m_recentErroredTorrents;
|
QSet<TorrentID> m_recentErroredTorrents;
|
||||||
QTimer *m_recentErroredTorrentsTimer = nullptr;
|
QTimer *m_recentErroredTorrentsTimer = nullptr;
|
||||||
|
|
||||||
SessionMetricIndices m_metricIndices;
|
SessionMetricIndices m_metricIndices;
|
||||||
@@ -790,10 +792,3 @@ namespace BitTorrent
|
|||||||
static Session *m_instance;
|
static Session *m_instance;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
|
|
||||||
Q_DECLARE_METATYPE(std::shared_ptr<lt::entry>)
|
|
||||||
const int sharedPtrLtEntryTypeID = qRegisterMetaType<std::shared_ptr<lt::entry>>();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // BITTORRENT_SESSION_H
|
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_SESSIONSTATUS_H
|
#pragma once
|
||||||
#define BITTORRENT_SESSIONSTATUS_H
|
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
@@ -74,5 +73,3 @@ namespace BitTorrent
|
|||||||
quint64 peersCount = 0;
|
quint64 peersCount = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_SESSIONSTATUS_H
|
|
||||||
|
|||||||
@@ -27,8 +27,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SPEEDMONITOR_H
|
#pragma once
|
||||||
#define SPEEDMONITOR_H
|
|
||||||
|
|
||||||
#ifndef Q_MOC_RUN
|
#ifndef Q_MOC_RUN
|
||||||
#include <boost/circular_buffer.hpp>
|
#include <boost/circular_buffer.hpp>
|
||||||
@@ -86,5 +85,3 @@ private:
|
|||||||
boost::circular_buffer<SpeedSample> m_speedSamples;
|
boost::circular_buffer<SpeedSample> m_speedSamples;
|
||||||
SpeedSample m_sum;
|
SpeedSample m_sum;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SPEEDMONITOR_H
|
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STATISTICS_H
|
#pragma once
|
||||||
#define STATISTICS_H
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -67,5 +66,3 @@ private:
|
|||||||
|
|
||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STATISTICS_H
|
|
||||||
|
|||||||
@@ -27,9 +27,11 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "torrenthandle.h"
|
#include "torrent.h"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <QHash>
|
||||||
|
|
||||||
|
#include "infohash.h"
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
@@ -38,33 +40,38 @@ namespace BitTorrent
|
|||||||
return ::qHash(static_cast<std::underlying_type_t<TorrentState>>(key), seed);
|
return ::qHash(static_cast<std::underlying_type_t<TorrentState>>(key), seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TorrentHandle
|
// Torrent
|
||||||
|
|
||||||
const qreal TorrentHandle::USE_GLOBAL_RATIO = -2.;
|
const qreal Torrent::USE_GLOBAL_RATIO = -2;
|
||||||
const qreal TorrentHandle::NO_RATIO_LIMIT = -1.;
|
const qreal Torrent::NO_RATIO_LIMIT = -1;
|
||||||
|
|
||||||
const int TorrentHandle::USE_GLOBAL_SEEDING_TIME = -2;
|
const int Torrent::USE_GLOBAL_SEEDING_TIME = -2;
|
||||||
const int TorrentHandle::NO_SEEDING_TIME_LIMIT = -1;
|
const int Torrent::NO_SEEDING_TIME_LIMIT = -1;
|
||||||
|
|
||||||
const qreal TorrentHandle::MAX_RATIO = 9999.;
|
const qreal Torrent::MAX_RATIO = 9999;
|
||||||
const int TorrentHandle::MAX_SEEDING_TIME = 525600;
|
const int Torrent::MAX_SEEDING_TIME = 525600;
|
||||||
|
|
||||||
bool TorrentHandle::isResumed() const
|
TorrentID Torrent::id() const
|
||||||
|
{
|
||||||
|
return infoHash().toTorrentID();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Torrent::isResumed() const
|
||||||
{
|
{
|
||||||
return !isPaused();
|
return !isPaused();
|
||||||
}
|
}
|
||||||
|
|
||||||
qlonglong TorrentHandle::remainingSize() const
|
qlonglong Torrent::remainingSize() const
|
||||||
{
|
{
|
||||||
return wantedSize() - completedSize();
|
return wantedSize() - completedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::toggleSequentialDownload()
|
void Torrent::toggleSequentialDownload()
|
||||||
{
|
{
|
||||||
setSequentialDownload(!isSequentialDownload());
|
setSequentialDownload(!isSequentialDownload());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::toggleFirstLastPiecePriority()
|
void Torrent::toggleFirstLastPiecePriority()
|
||||||
{
|
{
|
||||||
setFirstLastPiecePriority(!hasFirstLastPiecePriority());
|
setFirstLastPiecePriority(!hasFirstLastPiecePriority());
|
||||||
}
|
}
|
||||||
@@ -29,15 +29,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QHash>
|
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QSet>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVector>
|
#include <QtContainerFwd>
|
||||||
|
|
||||||
|
#include "abstractfilestorage.h"
|
||||||
|
|
||||||
class QBitArray;
|
class QBitArray;
|
||||||
class QDateTime;
|
class QDateTime;
|
||||||
class QStringList;
|
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
@@ -45,9 +44,10 @@ namespace BitTorrent
|
|||||||
enum class DownloadPriority;
|
enum class DownloadPriority;
|
||||||
class InfoHash;
|
class InfoHash;
|
||||||
class PeerInfo;
|
class PeerInfo;
|
||||||
|
class TorrentID;
|
||||||
class TorrentInfo;
|
class TorrentInfo;
|
||||||
class TrackerEntry;
|
|
||||||
struct PeerAddress;
|
struct PeerAddress;
|
||||||
|
struct TrackerEntry;
|
||||||
|
|
||||||
enum class TorrentOperatingMode
|
enum class TorrentOperatingMode
|
||||||
{
|
{
|
||||||
@@ -92,7 +92,7 @@ namespace BitTorrent
|
|||||||
|
|
||||||
uint qHash(TorrentState key, uint seed);
|
uint qHash(TorrentState key, uint seed);
|
||||||
|
|
||||||
class TorrentHandle
|
class Torrent : public AbstractFileStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const qreal USE_GLOBAL_RATIO;
|
static const qreal USE_GLOBAL_RATIO;
|
||||||
@@ -104,9 +104,9 @@ namespace BitTorrent
|
|||||||
static const qreal MAX_RATIO;
|
static const qreal MAX_RATIO;
|
||||||
static const int MAX_SEEDING_TIME;
|
static const int MAX_SEEDING_TIME;
|
||||||
|
|
||||||
virtual ~TorrentHandle() = default;
|
virtual ~Torrent() = default;
|
||||||
|
|
||||||
virtual InfoHash hash() const = 0;
|
virtual InfoHash infoHash() const = 0;
|
||||||
virtual QString name() const = 0;
|
virtual QString name() const = 0;
|
||||||
virtual QDateTime creationDate() const = 0;
|
virtual QDateTime creationDate() const = 0;
|
||||||
virtual QString creator() const = 0;
|
virtual QString creator() const = 0;
|
||||||
@@ -180,9 +180,6 @@ namespace BitTorrent
|
|||||||
virtual bool removeTag(const QString &tag) = 0;
|
virtual bool removeTag(const QString &tag) = 0;
|
||||||
virtual void removeAllTags() = 0;
|
virtual void removeAllTags() = 0;
|
||||||
|
|
||||||
virtual bool hasRootFolder() const = 0;
|
|
||||||
|
|
||||||
virtual int filesCount() const = 0;
|
|
||||||
virtual int piecesCount() const = 0;
|
virtual int piecesCount() const = 0;
|
||||||
virtual int piecesHave() const = 0;
|
virtual int piecesHave() const = 0;
|
||||||
virtual qreal progress() const = 0;
|
virtual qreal progress() const = 0;
|
||||||
@@ -190,9 +187,6 @@ namespace BitTorrent
|
|||||||
virtual qreal ratioLimit() const = 0;
|
virtual qreal ratioLimit() const = 0;
|
||||||
virtual int seedingTimeLimit() const = 0;
|
virtual int seedingTimeLimit() const = 0;
|
||||||
|
|
||||||
virtual QString filePath(int index) const = 0;
|
|
||||||
virtual QString fileName(int index) const = 0;
|
|
||||||
virtual qlonglong fileSize(int index) const = 0;
|
|
||||||
virtual QStringList absoluteFilePaths() const = 0;
|
virtual QStringList absoluteFilePaths() const = 0;
|
||||||
virtual QVector<DownloadPriority> filePriorities() const = 0;
|
virtual QVector<DownloadPriority> filePriorities() const = 0;
|
||||||
|
|
||||||
@@ -243,6 +237,9 @@ namespace BitTorrent
|
|||||||
virtual int downloadLimit() const = 0;
|
virtual int downloadLimit() const = 0;
|
||||||
virtual int uploadLimit() const = 0;
|
virtual int uploadLimit() const = 0;
|
||||||
virtual bool superSeeding() const = 0;
|
virtual bool superSeeding() const = 0;
|
||||||
|
virtual bool isDHTDisabled() const = 0;
|
||||||
|
virtual bool isPEXDisabled() const = 0;
|
||||||
|
virtual bool isLSDDisabled() const = 0;
|
||||||
virtual QVector<PeerInfo> peers() const = 0;
|
virtual QVector<PeerInfo> peers() const = 0;
|
||||||
virtual QBitArray pieces() const = 0;
|
virtual QBitArray pieces() const = 0;
|
||||||
virtual QBitArray downloadingPieces() const = 0;
|
virtual QBitArray downloadingPieces() const = 0;
|
||||||
@@ -275,13 +272,15 @@ namespace BitTorrent
|
|||||||
virtual void forceReannounce(int index = -1) = 0;
|
virtual void forceReannounce(int index = -1) = 0;
|
||||||
virtual void forceDHTAnnounce() = 0;
|
virtual void forceDHTAnnounce() = 0;
|
||||||
virtual void forceRecheck() = 0;
|
virtual void forceRecheck() = 0;
|
||||||
virtual void renameFile(int index, const QString &name) = 0;
|
|
||||||
virtual void prioritizeFiles(const QVector<DownloadPriority> &priorities) = 0;
|
virtual void prioritizeFiles(const QVector<DownloadPriority> &priorities) = 0;
|
||||||
virtual void setRatioLimit(qreal limit) = 0;
|
virtual void setRatioLimit(qreal limit) = 0;
|
||||||
virtual void setSeedingTimeLimit(int limit) = 0;
|
virtual void setSeedingTimeLimit(int limit) = 0;
|
||||||
virtual void setUploadLimit(int limit) = 0;
|
virtual void setUploadLimit(int limit) = 0;
|
||||||
virtual void setDownloadLimit(int limit) = 0;
|
virtual void setDownloadLimit(int limit) = 0;
|
||||||
virtual void setSuperSeeding(bool enable) = 0;
|
virtual void setSuperSeeding(bool enable) = 0;
|
||||||
|
virtual void setDHTDisabled(bool disable) = 0;
|
||||||
|
virtual void setPEXDisabled(bool disable) = 0;
|
||||||
|
virtual void setLSDDisabled(bool disable) = 0;
|
||||||
virtual void flushCache() const = 0;
|
virtual void flushCache() const = 0;
|
||||||
virtual void addTrackers(const QVector<TrackerEntry> &trackers) = 0;
|
virtual void addTrackers(const QVector<TrackerEntry> &trackers) = 0;
|
||||||
virtual void replaceTrackers(const QVector<TrackerEntry> &trackers) = 0;
|
virtual void replaceTrackers(const QVector<TrackerEntry> &trackers) = 0;
|
||||||
@@ -292,6 +291,7 @@ namespace BitTorrent
|
|||||||
|
|
||||||
virtual QString createMagnetURI() const = 0;
|
virtual QString createMagnetURI() const = 0;
|
||||||
|
|
||||||
|
TorrentID id() const;
|
||||||
bool isResumed() const;
|
bool isResumed() const;
|
||||||
qlonglong remainingSize() const;
|
qlonglong remainingSize() const;
|
||||||
|
|
||||||
51
src/base/bittorrent/torrentcontentlayout.h
Normal file
51
src/base/bittorrent/torrentcontentlayout.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMetaEnum>
|
||||||
|
|
||||||
|
namespace BitTorrent
|
||||||
|
{
|
||||||
|
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
||||||
|
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
||||||
|
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
||||||
|
inline namespace TorrentContentLayoutNS
|
||||||
|
{
|
||||||
|
Q_NAMESPACE
|
||||||
|
|
||||||
|
enum class TorrentContentLayout
|
||||||
|
{
|
||||||
|
Original,
|
||||||
|
Subfolder,
|
||||||
|
NoSubfolder
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM_NS(TorrentContentLayout)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/io.h"
|
#include "base/utils/io.h"
|
||||||
#include "base/utils/string.h"
|
#include "base/utils/string.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "ltunderlyingtype.h"
|
#include "ltunderlyingtype.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -99,8 +100,6 @@ void TorrentCreatorThread::sendProgressSignal(int currentPieceIdx, int totalPiec
|
|||||||
|
|
||||||
void TorrentCreatorThread::run()
|
void TorrentCreatorThread::run()
|
||||||
{
|
{
|
||||||
const QString creatorStr("qBittorrent " QBT_VERSION);
|
|
||||||
|
|
||||||
emit updateProgress(0);
|
emit updateProgress(0);
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -177,17 +176,19 @@ void TorrentCreatorThread::run()
|
|||||||
newTorrent.add_tracker(tracker.trimmed().toStdString(), tier);
|
newTorrent.add_tracker(tracker.trimmed().toStdString(), tier);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInterruptionRequested()) return;
|
|
||||||
|
|
||||||
// calculate the hash for all pieces
|
// calculate the hash for all pieces
|
||||||
lt::set_piece_hashes(newTorrent, Utils::Fs::toNativePath(parentPath).toStdString()
|
lt::set_piece_hashes(newTorrent, Utils::Fs::toNativePath(parentPath).toStdString()
|
||||||
, [this, &newTorrent](const lt::piece_index_t n)
|
, [this, &newTorrent](const lt::piece_index_t n)
|
||||||
{
|
{
|
||||||
|
if (isInterruptionRequested())
|
||||||
|
throw RuntimeError {tr("Create new torrent aborted.")};
|
||||||
|
|
||||||
sendProgressSignal(static_cast<LTUnderlyingType<lt::piece_index_t>>(n), newTorrent.num_pieces());
|
sendProgressSignal(static_cast<LTUnderlyingType<lt::piece_index_t>>(n), newTorrent.num_pieces());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set qBittorrent as creator and add user comment to
|
// Set qBittorrent as creator and add user comment to
|
||||||
// torrent_info structure
|
// torrent_info structure
|
||||||
newTorrent.set_creator(creatorStr.toUtf8().constData());
|
newTorrent.set_creator("qBittorrent " QBT_VERSION);
|
||||||
newTorrent.set_comment(m_params.comment.toUtf8().constData());
|
newTorrent.set_comment(m_params.comment.toUtf8().constData());
|
||||||
// Is private ?
|
// Is private ?
|
||||||
newTorrent.set_priv(m_params.isPrivate);
|
newTorrent.set_priv(m_params.isPrivate);
|
||||||
@@ -206,8 +207,7 @@ void TorrentCreatorThread::run()
|
|||||||
QFile outfile {m_params.savePath};
|
QFile outfile {m_params.savePath};
|
||||||
if (!outfile.open(QIODevice::WriteOnly))
|
if (!outfile.open(QIODevice::WriteOnly))
|
||||||
{
|
{
|
||||||
throw RuntimeError
|
throw RuntimeError {tr("Create new torrent file failed. Reason: %1")
|
||||||
{tr("Create new torrent file failed. Reason: %1")
|
|
||||||
.arg(outfile.errorString())};
|
.arg(outfile.errorString())};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,8 +216,7 @@ void TorrentCreatorThread::run()
|
|||||||
lt::bencode(Utils::IO::FileDeviceOutputIterator {outfile}, entry);
|
lt::bencode(Utils::IO::FileDeviceOutputIterator {outfile}, entry);
|
||||||
if (outfile.error() != QFileDevice::NoError)
|
if (outfile.error() != QFileDevice::NoError)
|
||||||
{
|
{
|
||||||
throw RuntimeError
|
throw RuntimeError {tr("Create new torrent file failed. Reason: %1")
|
||||||
{tr("Create new torrent file failed. Reason: %1")
|
|
||||||
.arg(outfile.errorString())};
|
.arg(outfile.errorString())};
|
||||||
}
|
}
|
||||||
outfile.close();
|
outfile.close();
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_TORRENTCREATORTHREAD_H
|
#pragma once
|
||||||
#define BITTORRENT_TORRENTCREATORTHREAD_H
|
|
||||||
|
|
||||||
#include <libtorrent/version.hpp>
|
#include <libtorrent/version.hpp>
|
||||||
|
|
||||||
@@ -94,5 +93,3 @@ namespace BitTorrent
|
|||||||
TorrentCreatorParams m_params;
|
TorrentCreatorParams m_params;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_TORRENTCREATORTHREAD_H
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#include "infohash.h"
|
#include "infohash.h"
|
||||||
#include "speedmonitor.h"
|
#include "speedmonitor.h"
|
||||||
#include "torrenthandle.h"
|
#include "torrent.h"
|
||||||
#include "torrentinfo.h"
|
#include "torrentinfo.h"
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
@@ -62,14 +62,14 @@ namespace BitTorrent
|
|||||||
QString category;
|
QString category;
|
||||||
QSet<QString> tags;
|
QSet<QString> tags;
|
||||||
QString savePath;
|
QString savePath;
|
||||||
|
TorrentContentLayout contentLayout = TorrentContentLayout::Original;
|
||||||
bool firstLastPiecePriority = false;
|
bool firstLastPiecePriority = false;
|
||||||
bool hasSeedStatus = false;
|
bool hasSeedStatus = false;
|
||||||
bool hasRootFolder = true;
|
|
||||||
bool forced = false;
|
bool forced = false;
|
||||||
bool paused = false;
|
bool paused = false;
|
||||||
|
|
||||||
qreal ratioLimit = TorrentHandle::USE_GLOBAL_RATIO;
|
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
||||||
int seedingTimeLimit = TorrentHandle::USE_GLOBAL_SEEDING_TIME;
|
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
||||||
|
|
||||||
bool restored = false; // is existing torrent job?
|
bool restored = false; // is existing torrent job?
|
||||||
};
|
};
|
||||||
@@ -80,19 +80,25 @@ namespace BitTorrent
|
|||||||
Overwrite
|
Overwrite
|
||||||
};
|
};
|
||||||
|
|
||||||
class TorrentHandleImpl final : public QObject, public TorrentHandle
|
enum class MaintenanceJob
|
||||||
{
|
{
|
||||||
Q_DISABLE_COPY(TorrentHandleImpl)
|
None,
|
||||||
Q_DECLARE_TR_FUNCTIONS(BitTorrent::TorrentHandleImpl)
|
HandleMetadata
|
||||||
|
};
|
||||||
|
|
||||||
|
class TorrentImpl final : public QObject, public Torrent
|
||||||
|
{
|
||||||
|
Q_DISABLE_COPY(TorrentImpl)
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(BitTorrent::TorrentImpl)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TorrentHandleImpl(Session *session, const lt::torrent_handle &nativeHandle,
|
TorrentImpl(Session *session, lt::session *nativeSession
|
||||||
const LoadTorrentParams ¶ms);
|
, const lt::torrent_handle &nativeHandle, const LoadTorrentParams ¶ms);
|
||||||
~TorrentHandleImpl() override;
|
~TorrentImpl() override;
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
InfoHash hash() const override;
|
InfoHash infoHash() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QDateTime creationDate() const override;
|
QDateTime creationDate() const override;
|
||||||
QString creator() const override;
|
QString creator() const override;
|
||||||
@@ -123,8 +129,6 @@ namespace BitTorrent
|
|||||||
bool removeTag(const QString &tag) override;
|
bool removeTag(const QString &tag) override;
|
||||||
void removeAllTags() override;
|
void removeAllTags() override;
|
||||||
|
|
||||||
bool hasRootFolder() const override;
|
|
||||||
|
|
||||||
int filesCount() const override;
|
int filesCount() const override;
|
||||||
int piecesCount() const override;
|
int piecesCount() const override;
|
||||||
int piecesHave() const override;
|
int piecesHave() const override;
|
||||||
@@ -186,6 +190,9 @@ namespace BitTorrent
|
|||||||
int downloadLimit() const override;
|
int downloadLimit() const override;
|
||||||
int uploadLimit() const override;
|
int uploadLimit() const override;
|
||||||
bool superSeeding() const override;
|
bool superSeeding() const override;
|
||||||
|
bool isDHTDisabled() const override;
|
||||||
|
bool isPEXDisabled() const override;
|
||||||
|
bool isLSDDisabled() const override;
|
||||||
QVector<PeerInfo> peers() const override;
|
QVector<PeerInfo> peers() const override;
|
||||||
QBitArray pieces() const override;
|
QBitArray pieces() const override;
|
||||||
QBitArray downloadingPieces() const override;
|
QBitArray downloadingPieces() const override;
|
||||||
@@ -212,13 +219,16 @@ namespace BitTorrent
|
|||||||
void forceReannounce(int index = -1) override;
|
void forceReannounce(int index = -1) override;
|
||||||
void forceDHTAnnounce() override;
|
void forceDHTAnnounce() override;
|
||||||
void forceRecheck() override;
|
void forceRecheck() override;
|
||||||
void renameFile(int index, const QString &name) override;
|
void renameFile(int index, const QString &path) override;
|
||||||
void prioritizeFiles(const QVector<DownloadPriority> &priorities) override;
|
void prioritizeFiles(const QVector<DownloadPriority> &priorities) override;
|
||||||
void setRatioLimit(qreal limit) override;
|
void setRatioLimit(qreal limit) override;
|
||||||
void setSeedingTimeLimit(int limit) override;
|
void setSeedingTimeLimit(int limit) override;
|
||||||
void setUploadLimit(int limit) override;
|
void setUploadLimit(int limit) override;
|
||||||
void setDownloadLimit(int limit) override;
|
void setDownloadLimit(int limit) override;
|
||||||
void setSuperSeeding(bool enable) override;
|
void setSuperSeeding(bool enable) override;
|
||||||
|
void setDHTDisabled(bool disable) override;
|
||||||
|
void setPEXDisabled(bool disable) override;
|
||||||
|
void setLSDDisabled(bool disable) override;
|
||||||
void flushCache() const override;
|
void flushCache() const override;
|
||||||
void addTrackers(const QVector<TrackerEntry> &trackers) override;
|
void addTrackers(const QVector<TrackerEntry> &trackers) override;
|
||||||
void replaceTrackers(const QVector<TrackerEntry> &trackers) override;
|
void replaceTrackers(const QVector<TrackerEntry> &trackers) override;
|
||||||
@@ -241,6 +251,7 @@ namespace BitTorrent
|
|||||||
void handleAppendExtensionToggled();
|
void handleAppendExtensionToggled();
|
||||||
void saveResumeData();
|
void saveResumeData();
|
||||||
void handleMoveStorageJobFinished(bool hasOutstandingJob);
|
void handleMoveStorageJobFinished(bool hasOutstandingJob);
|
||||||
|
void fileSearchFinished(const QString &savePath, const QStringList &fileNames);
|
||||||
|
|
||||||
QString actualStorageLocation() const;
|
QString actualStorageLocation() const;
|
||||||
|
|
||||||
@@ -250,7 +261,6 @@ namespace BitTorrent
|
|||||||
void updateStatus();
|
void updateStatus();
|
||||||
void updateStatus(const lt::torrent_status &nativeStatus);
|
void updateStatus(const lt::torrent_status &nativeStatus);
|
||||||
void updateState();
|
void updateState();
|
||||||
void updateTorrentInfo();
|
|
||||||
|
|
||||||
void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert *p);
|
void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert *p);
|
||||||
void handleFileCompletedAlert(const lt::file_completed_alert *p);
|
void handleFileCompletedAlert(const lt::file_completed_alert *p);
|
||||||
@@ -279,14 +289,18 @@ namespace BitTorrent
|
|||||||
void manageIncompleteFiles();
|
void manageIncompleteFiles();
|
||||||
void applyFirstLastPiecePriority(bool enabled, const QVector<DownloadPriority> &updatedFilePrio = {});
|
void applyFirstLastPiecePriority(bool enabled, const QVector<DownloadPriority> &updatedFilePrio = {});
|
||||||
|
|
||||||
|
void endReceivedMetadataHandling(const QString &savePath, const QStringList &fileNames);
|
||||||
|
void reload();
|
||||||
|
|
||||||
Session *const m_session;
|
Session *const m_session;
|
||||||
|
lt::session *m_nativeSession;
|
||||||
lt::torrent_handle m_nativeHandle;
|
lt::torrent_handle m_nativeHandle;
|
||||||
lt::torrent_status m_nativeStatus;
|
lt::torrent_status m_nativeStatus;
|
||||||
TorrentState m_state = TorrentState::Unknown;
|
TorrentState m_state = TorrentState::Unknown;
|
||||||
TorrentInfo m_torrentInfo;
|
TorrentInfo m_torrentInfo;
|
||||||
SpeedMonitor m_speedMonitor;
|
SpeedMonitor m_speedMonitor;
|
||||||
|
|
||||||
InfoHash m_hash;
|
InfoHash m_infoHash;
|
||||||
|
|
||||||
// m_moveFinishedTriggers is activated only when the following conditions are met:
|
// m_moveFinishedTriggers is activated only when the following conditions are met:
|
||||||
// all file rename jobs complete, all file move jobs complete
|
// all file rename jobs complete, all file move jobs complete
|
||||||
@@ -294,6 +308,8 @@ namespace BitTorrent
|
|||||||
int m_renameCount = 0;
|
int m_renameCount = 0;
|
||||||
bool m_storageIsMoving = false;
|
bool m_storageIsMoving = false;
|
||||||
|
|
||||||
|
MaintenanceJob m_maintenanceJob = MaintenanceJob::None;
|
||||||
|
|
||||||
// Until libtorrent provide an "old_name" field in `file_renamed_alert`
|
// Until libtorrent provide an "old_name" field in `file_renamed_alert`
|
||||||
// we will rely on this workaround to remove empty leftover folders
|
// we will rely on this workaround to remove empty leftover folders
|
||||||
QHash<lt::file_index_t, QVector<QString>> m_oldPath;
|
QHash<lt::file_index_t, QVector<QString>> m_oldPath;
|
||||||
@@ -308,10 +324,10 @@ namespace BitTorrent
|
|||||||
qreal m_ratioLimit;
|
qreal m_ratioLimit;
|
||||||
int m_seedingTimeLimit;
|
int m_seedingTimeLimit;
|
||||||
TorrentOperatingMode m_operatingMode;
|
TorrentOperatingMode m_operatingMode;
|
||||||
|
TorrentContentLayout m_contentLayout;
|
||||||
bool m_hasSeedStatus;
|
bool m_hasSeedStatus;
|
||||||
bool m_fastresumeDataRejected = false;
|
bool m_fastresumeDataRejected = false;
|
||||||
bool m_hasMissingFiles = false;
|
bool m_hasMissingFiles = false;
|
||||||
bool m_hasRootFolder;
|
|
||||||
bool m_hasFirstLastPiecePriority = false;
|
bool m_hasFirstLastPiecePriority = false;
|
||||||
bool m_useAutoTMM;
|
bool m_useAutoTMM;
|
||||||
bool m_isStopped;
|
bool m_isStopped;
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
#include "base/exceptions.h"
|
#include "base/exceptions.h"
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
@@ -51,6 +52,29 @@
|
|||||||
|
|
||||||
using namespace BitTorrent;
|
using namespace BitTorrent;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
QString getRootFolder(const QStringList &filePaths)
|
||||||
|
{
|
||||||
|
QString rootFolder;
|
||||||
|
for (const QString &filePath : filePaths)
|
||||||
|
{
|
||||||
|
if (QDir::isAbsolutePath(filePath)) continue;
|
||||||
|
|
||||||
|
const auto filePathElements = filePath.splitRef('/');
|
||||||
|
// if at least one file has no root folder, no common root folder exists
|
||||||
|
if (filePathElements.count() <= 1) return {};
|
||||||
|
|
||||||
|
if (rootFolder.isEmpty())
|
||||||
|
rootFolder = filePathElements.at(0).toString();
|
||||||
|
else if (rootFolder != filePathElements.at(0))
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootFolder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TorrentInfo::TorrentInfo(std::shared_ptr<const lt::torrent_info> nativeInfo)
|
TorrentInfo::TorrentInfo(std::shared_ptr<const lt::torrent_info> nativeInfo)
|
||||||
{
|
{
|
||||||
m_nativeInfo = std::const_pointer_cast<lt::torrent_info>(nativeInfo);
|
m_nativeInfo = std::const_pointer_cast<lt::torrent_info>(nativeInfo);
|
||||||
@@ -160,16 +184,21 @@ bool TorrentInfo::isValid() const
|
|||||||
return (m_nativeInfo && m_nativeInfo->is_valid() && (m_nativeInfo->num_files() > 0));
|
return (m_nativeInfo && m_nativeInfo->is_valid() && (m_nativeInfo->num_files() > 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoHash TorrentInfo::hash() const
|
InfoHash TorrentInfo::infoHash() const
|
||||||
{
|
{
|
||||||
if (!isValid()) return {};
|
if (!isValid()) return {};
|
||||||
|
|
||||||
|
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
||||||
|
return m_nativeInfo->info_hashes();
|
||||||
|
#else
|
||||||
return m_nativeInfo->info_hash();
|
return m_nativeInfo->info_hash();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TorrentInfo::name() const
|
QString TorrentInfo::name() const
|
||||||
{
|
{
|
||||||
if (!isValid()) return {};
|
if (!isValid()) return {};
|
||||||
return QString::fromStdString(m_nativeInfo->name());
|
return QString::fromStdString(m_nativeInfo->orig_files().name());
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime TorrentInfo::creationDate() const
|
QDateTime TorrentInfo::creationDate() const
|
||||||
@@ -278,7 +307,7 @@ QVector<TrackerEntry> TorrentInfo::trackers() const
|
|||||||
ret.reserve(trackers.size());
|
ret.reserve(trackers.size());
|
||||||
|
|
||||||
for (const lt::announce_entry &tracker : trackers)
|
for (const lt::announce_entry &tracker : trackers)
|
||||||
ret.append(tracker);
|
ret.append({QString::fromStdString(tracker.url)});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +379,7 @@ QVector<QByteArray> TorrentInfo::pieceHashes() const
|
|||||||
hashes.reserve(count);
|
hashes.reserve(count);
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
hashes += {m_nativeInfo->hash_for_piece_ptr(lt::piece_index_t {i}), InfoHash::length()};
|
hashes += {m_nativeInfo->hash_for_piece_ptr(lt::piece_index_t {i}), SHA1Hash::length()};
|
||||||
|
|
||||||
return hashes;
|
return hashes;
|
||||||
}
|
}
|
||||||
@@ -411,23 +440,7 @@ int TorrentInfo::fileIndex(const QString &fileName) const
|
|||||||
|
|
||||||
QString TorrentInfo::rootFolder() const
|
QString TorrentInfo::rootFolder() const
|
||||||
{
|
{
|
||||||
QString rootFolder;
|
return getRootFolder(filePaths());
|
||||||
for (int i = 0; i < filesCount(); ++i)
|
|
||||||
{
|
|
||||||
const QString filePath = this->filePath(i);
|
|
||||||
if (QDir::isAbsolutePath(filePath)) continue;
|
|
||||||
|
|
||||||
const auto filePathElements = filePath.splitRef('/');
|
|
||||||
// if at least one file has no root folder, no common root folder exists
|
|
||||||
if (filePathElements.count() <= 1) return "";
|
|
||||||
|
|
||||||
if (rootFolder.isEmpty())
|
|
||||||
rootFolder = filePathElements.at(0).toString();
|
|
||||||
else if (rootFolder != filePathElements.at(0))
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return rootFolder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentInfo::hasRootFolder() const
|
bool TorrentInfo::hasRootFolder() const
|
||||||
@@ -435,10 +448,26 @@ bool TorrentInfo::hasRootFolder() const
|
|||||||
return !rootFolder().isEmpty();
|
return !rootFolder().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TorrentInfo::setContentLayout(const TorrentContentLayout layout)
|
||||||
|
{
|
||||||
|
switch (layout)
|
||||||
|
{
|
||||||
|
case TorrentContentLayout::Original:
|
||||||
|
setContentLayout(defaultContentLayout());
|
||||||
|
break;
|
||||||
|
case TorrentContentLayout::Subfolder:
|
||||||
|
if (rootFolder().isEmpty())
|
||||||
|
addRootFolder();
|
||||||
|
break;
|
||||||
|
case TorrentContentLayout::NoSubfolder:
|
||||||
|
if (!rootFolder().isEmpty())
|
||||||
|
stripRootFolder();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TorrentInfo::stripRootFolder()
|
void TorrentInfo::stripRootFolder()
|
||||||
{
|
{
|
||||||
if (!hasRootFolder()) return;
|
|
||||||
|
|
||||||
lt::file_storage files = m_nativeInfo->files();
|
lt::file_storage files = m_nativeInfo->files();
|
||||||
|
|
||||||
// Solution for case of renamed root folder
|
// Solution for case of renamed root folder
|
||||||
@@ -455,6 +484,36 @@ void TorrentInfo::stripRootFolder()
|
|||||||
m_nativeInfo->remap_files(files);
|
m_nativeInfo->remap_files(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TorrentInfo::addRootFolder()
|
||||||
|
{
|
||||||
|
const QString originalName = name();
|
||||||
|
Q_ASSERT(!originalName.isEmpty());
|
||||||
|
|
||||||
|
const QString extension = Utils::Fs::fileExtension(originalName);
|
||||||
|
const QString rootFolder = extension.isEmpty()
|
||||||
|
? originalName
|
||||||
|
: originalName.chopped(extension.size() + 1);
|
||||||
|
const std::string rootPrefix = Utils::Fs::toNativePath(rootFolder + QLatin1Char {'/'}).toStdString();
|
||||||
|
lt::file_storage files = m_nativeInfo->files();
|
||||||
|
files.set_name(rootFolder.toStdString());
|
||||||
|
for (int i = 0; i < files.num_files(); ++i)
|
||||||
|
files.rename_file(lt::file_index_t {i}, rootPrefix + files.file_path(lt::file_index_t {i}));
|
||||||
|
m_nativeInfo->remap_files(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
TorrentContentLayout TorrentInfo::defaultContentLayout() const
|
||||||
|
{
|
||||||
|
QStringList origFilePaths;
|
||||||
|
origFilePaths.reserve(filesCount());
|
||||||
|
for (int i = 0; i < filesCount(); ++i)
|
||||||
|
origFilePaths << origFilePath(i);
|
||||||
|
|
||||||
|
const QString origRootFolder = getRootFolder(origFilePaths);
|
||||||
|
return (origRootFolder.isEmpty()
|
||||||
|
? TorrentContentLayout::NoSubfolder
|
||||||
|
: TorrentContentLayout::Subfolder);
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<lt::torrent_info> TorrentInfo::nativeInfo() const
|
std::shared_ptr<lt::torrent_info> TorrentInfo::nativeInfo() const
|
||||||
{
|
{
|
||||||
return m_nativeInfo;
|
return m_nativeInfo;
|
||||||
|
|||||||
@@ -26,28 +26,28 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_TORRENTINFO_H
|
#pragma once
|
||||||
#define BITTORRENT_TORRENTINFO_H
|
|
||||||
|
|
||||||
#include <libtorrent/torrent_info.hpp>
|
#include <libtorrent/torrent_info.hpp>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QVector>
|
#include <QtContainerFwd>
|
||||||
|
|
||||||
#include "base/indexrange.h"
|
#include "base/indexrange.h"
|
||||||
|
#include "abstractfilestorage.h"
|
||||||
|
#include "torrentcontentlayout.h"
|
||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
class QDateTime;
|
class QDateTime;
|
||||||
class QString;
|
class QString;
|
||||||
class QStringList;
|
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class InfoHash;
|
class InfoHash;
|
||||||
class TrackerEntry;
|
struct TrackerEntry;
|
||||||
|
|
||||||
class TorrentInfo
|
class TorrentInfo final : public AbstractFileStorage
|
||||||
{
|
{
|
||||||
Q_DECLARE_TR_FUNCTIONS(TorrentInfo)
|
Q_DECLARE_TR_FUNCTIONS(TorrentInfo)
|
||||||
|
|
||||||
@@ -62,22 +62,22 @@ namespace BitTorrent
|
|||||||
TorrentInfo &operator=(const TorrentInfo &other);
|
TorrentInfo &operator=(const TorrentInfo &other);
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
InfoHash hash() const;
|
InfoHash infoHash() const;
|
||||||
QString name() const;
|
QString name() const;
|
||||||
QDateTime creationDate() const;
|
QDateTime creationDate() const;
|
||||||
QString creator() const;
|
QString creator() const;
|
||||||
QString comment() const;
|
QString comment() const;
|
||||||
bool isPrivate() const;
|
bool isPrivate() const;
|
||||||
qlonglong totalSize() const;
|
qlonglong totalSize() const;
|
||||||
int filesCount() const;
|
int filesCount() const override;
|
||||||
int pieceLength() const;
|
int pieceLength() const;
|
||||||
int pieceLength(int index) const;
|
int pieceLength(int index) const;
|
||||||
int piecesCount() const;
|
int piecesCount() const;
|
||||||
QString filePath(int index) const;
|
QString filePath(int index) const override;
|
||||||
QStringList filePaths() const;
|
QStringList filePaths() const;
|
||||||
QString fileName(int index) const;
|
QString fileName(int index) const override;
|
||||||
QString origFilePath(int index) const;
|
QString origFilePath(int index) const;
|
||||||
qlonglong fileSize(int index) const;
|
qlonglong fileSize(int index) const override;
|
||||||
qlonglong fileOffset(int index) const;
|
qlonglong fileOffset(int index) const;
|
||||||
QVector<TrackerEntry> trackers() const;
|
QVector<TrackerEntry> trackers() const;
|
||||||
QVector<QUrl> urlSeeds() const;
|
QVector<QUrl> urlSeeds() const;
|
||||||
@@ -92,19 +92,21 @@ namespace BitTorrent
|
|||||||
PieceRange filePieces(const QString &file) const;
|
PieceRange filePieces(const QString &file) const;
|
||||||
PieceRange filePieces(int fileIndex) const;
|
PieceRange filePieces(int fileIndex) const;
|
||||||
|
|
||||||
void renameFile(int index, const QString &newPath);
|
void renameFile(int index, const QString &newPath) override;
|
||||||
|
|
||||||
QString rootFolder() const;
|
QString rootFolder() const;
|
||||||
bool hasRootFolder() const;
|
bool hasRootFolder() const;
|
||||||
void stripRootFolder();
|
void setContentLayout(TorrentContentLayout layout);
|
||||||
|
|
||||||
std::shared_ptr<lt::torrent_info> nativeInfo() const;
|
std::shared_ptr<lt::torrent_info> nativeInfo() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// returns file index or -1 if fileName is not found
|
// returns file index or -1 if fileName is not found
|
||||||
int fileIndex(const QString &fileName) const;
|
int fileIndex(const QString &fileName) const;
|
||||||
|
void stripRootFolder();
|
||||||
|
void addRootFolder();
|
||||||
|
TorrentContentLayout defaultContentLayout() const;
|
||||||
|
|
||||||
std::shared_ptr<lt::torrent_info> m_nativeInfo;
|
std::shared_ptr<lt::torrent_info> m_nativeInfo;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_TORRENTINFO_H
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ struct Tracker::TrackerAnnounceRequest
|
|||||||
{
|
{
|
||||||
QHostAddress socketAddress;
|
QHostAddress socketAddress;
|
||||||
QByteArray claimedAddress; // self claimed by peer
|
QByteArray claimedAddress; // self claimed by peer
|
||||||
InfoHash infoHash;
|
TorrentID torrentID;
|
||||||
QString event;
|
QString event;
|
||||||
Peer peer;
|
Peer peer;
|
||||||
int numwant = 50;
|
int numwant = 50;
|
||||||
@@ -295,11 +295,11 @@ void Tracker::processAnnounceRequest()
|
|||||||
if (infoHashIter == queryParams.end())
|
if (infoHashIter == queryParams.end())
|
||||||
throw TrackerError("Missing \"info_hash\" parameter");
|
throw TrackerError("Missing \"info_hash\" parameter");
|
||||||
|
|
||||||
const InfoHash infoHash(infoHashIter->toHex());
|
const auto torrentID = TorrentID::fromString(infoHashIter->toHex());
|
||||||
if (!infoHash.isValid())
|
if (!torrentID.isValid())
|
||||||
throw TrackerError("Invalid \"info_hash\" parameter");
|
throw TrackerError("Invalid \"info_hash\" parameter");
|
||||||
|
|
||||||
announceReq.infoHash = infoHash;
|
announceReq.torrentID = torrentID;
|
||||||
|
|
||||||
// 2. peer_id
|
// 2. peer_id
|
||||||
const auto peerIdIter = queryParams.find(ANNOUNCE_REQUEST_PEER_ID);
|
const auto peerIdIter = queryParams.find(ANNOUNCE_REQUEST_PEER_ID);
|
||||||
@@ -381,19 +381,19 @@ void Tracker::processAnnounceRequest()
|
|||||||
|
|
||||||
void Tracker::registerPeer(const TrackerAnnounceRequest &announceReq)
|
void Tracker::registerPeer(const TrackerAnnounceRequest &announceReq)
|
||||||
{
|
{
|
||||||
if (!m_torrents.contains(announceReq.infoHash))
|
if (!m_torrents.contains(announceReq.torrentID))
|
||||||
{
|
{
|
||||||
// Reached max size, remove a random torrent
|
// Reached max size, remove a random torrent
|
||||||
if (m_torrents.size() >= MAX_TORRENTS)
|
if (m_torrents.size() >= MAX_TORRENTS)
|
||||||
m_torrents.erase(m_torrents.begin());
|
m_torrents.erase(m_torrents.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_torrents[announceReq.infoHash].setPeer(announceReq.peer);
|
m_torrents[announceReq.torrentID].setPeer(announceReq.peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tracker::unregisterPeer(const TrackerAnnounceRequest &announceReq)
|
void Tracker::unregisterPeer(const TrackerAnnounceRequest &announceReq)
|
||||||
{
|
{
|
||||||
const auto torrentStatsIter = m_torrents.find(announceReq.infoHash);
|
const auto torrentStatsIter = m_torrents.find(announceReq.torrentID);
|
||||||
if (torrentStatsIter == m_torrents.end())
|
if (torrentStatsIter == m_torrents.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -405,7 +405,7 @@ void Tracker::unregisterPeer(const TrackerAnnounceRequest &announceReq)
|
|||||||
|
|
||||||
void Tracker::prepareAnnounceResponse(const TrackerAnnounceRequest &announceReq)
|
void Tracker::prepareAnnounceResponse(const TrackerAnnounceRequest &announceReq)
|
||||||
{
|
{
|
||||||
const TorrentStats &torrentStats = m_torrents[announceReq.infoHash];
|
const TorrentStats &torrentStats = m_torrents[announceReq.torrentID];
|
||||||
|
|
||||||
lt::entry::dictionary_type replyDict
|
lt::entry::dictionary_type replyDict
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,8 +28,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_TRACKER_H
|
#pragma once
|
||||||
#define BITTORRENT_TRACKER_H
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -103,8 +102,6 @@ namespace BitTorrent
|
|||||||
Http::Request m_request;
|
Http::Request m_request;
|
||||||
Http::Environment m_env;
|
Http::Environment m_env;
|
||||||
|
|
||||||
QHash<InfoHash, TorrentStats> m_torrents;
|
QHash<TorrentID, TorrentStats> m_torrents;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_TRACKER_H
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015, 2021 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -28,139 +28,15 @@
|
|||||||
|
|
||||||
#include "trackerentry.h"
|
#include "trackerentry.h"
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include <libtorrent/version.hpp>
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
using namespace BitTorrent;
|
|
||||||
|
|
||||||
TrackerEntry::TrackerEntry(const QString &url)
|
|
||||||
: m_nativeEntry(url.toStdString())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackerEntry::TrackerEntry(const lt::announce_entry &nativeEntry)
|
|
||||||
: m_nativeEntry(nativeEntry)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QString TrackerEntry::url() const
|
|
||||||
{
|
|
||||||
return QString::fromStdString(nativeEntry().url);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TrackerEntry::tier() const
|
|
||||||
{
|
|
||||||
return nativeEntry().tier;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackerEntry::Status TrackerEntry::status() const
|
|
||||||
{
|
|
||||||
const auto &endpoints = nativeEntry().endpoints;
|
|
||||||
|
|
||||||
const bool allFailed = !endpoints.empty() && std::all_of(endpoints.begin(), endpoints.end()
|
|
||||||
, [](const lt::announce_endpoint &endpoint)
|
|
||||||
{
|
|
||||||
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
|
||||||
return std::all_of(endpoint.info_hashes.begin(), endpoint.info_hashes.end()
|
|
||||||
, [](const lt::announce_infohash &infohash)
|
|
||||||
{
|
|
||||||
return (infohash.fails > 0);
|
|
||||||
});
|
|
||||||
#else
|
|
||||||
return (endpoint.fails > 0);
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
if (allFailed)
|
|
||||||
return NotWorking;
|
|
||||||
|
|
||||||
const bool isUpdating = std::any_of(endpoints.begin(), endpoints.end()
|
|
||||||
, [](const lt::announce_endpoint &endpoint)
|
|
||||||
{
|
|
||||||
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
|
||||||
return std::any_of(endpoint.info_hashes.begin(), endpoint.info_hashes.end()
|
|
||||||
, [](const lt::announce_infohash &infohash)
|
|
||||||
{
|
|
||||||
return infohash.updating;
|
|
||||||
});
|
|
||||||
#else
|
|
||||||
return endpoint.updating;
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
if (isUpdating)
|
|
||||||
return Updating;
|
|
||||||
|
|
||||||
if (!nativeEntry().verified)
|
|
||||||
return NotContacted;
|
|
||||||
|
|
||||||
return Working;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrackerEntry::setTier(const int value)
|
|
||||||
{
|
|
||||||
m_nativeEntry.tier = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TrackerEntry::numSeeds() const
|
|
||||||
{
|
|
||||||
int value = -1;
|
|
||||||
for (const lt::announce_endpoint &endpoint : nativeEntry().endpoints)
|
|
||||||
{
|
|
||||||
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
|
||||||
for (const lt::announce_infohash &infoHash : endpoint.info_hashes)
|
|
||||||
value = std::max(value, infoHash.scrape_complete);
|
|
||||||
#else
|
|
||||||
value = std::max(value, endpoint.scrape_complete);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TrackerEntry::numLeeches() const
|
|
||||||
{
|
|
||||||
int value = -1;
|
|
||||||
for (const lt::announce_endpoint &endpoint : nativeEntry().endpoints)
|
|
||||||
{
|
|
||||||
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
|
||||||
for (const lt::announce_infohash &infoHash : endpoint.info_hashes)
|
|
||||||
value = std::max(value, infoHash.scrape_incomplete);
|
|
||||||
#else
|
|
||||||
value = std::max(value, endpoint.scrape_incomplete);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TrackerEntry::numDownloaded() const
|
|
||||||
{
|
|
||||||
int value = -1;
|
|
||||||
for (const lt::announce_endpoint &endpoint : nativeEntry().endpoints)
|
|
||||||
{
|
|
||||||
#if (LIBTORRENT_VERSION_NUM >= 20000)
|
|
||||||
for (const lt::announce_infohash &infoHash : endpoint.info_hashes)
|
|
||||||
value = std::max(value, infoHash.scrape_downloaded);
|
|
||||||
#else
|
|
||||||
value = std::max(value, endpoint.scrape_downloaded);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lt::announce_entry &TrackerEntry::nativeEntry() const
|
|
||||||
{
|
|
||||||
return m_nativeEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BitTorrent::operator==(const TrackerEntry &left, const TrackerEntry &right)
|
bool BitTorrent::operator==(const TrackerEntry &left, const TrackerEntry &right)
|
||||||
{
|
{
|
||||||
return ((left.tier() == right.tier())
|
return ((left.tier == right.tier)
|
||||||
&& QUrl(left.url()) == QUrl(right.url()));
|
&& QUrl(left.url) == QUrl(right.url));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint BitTorrent::qHash(const TrackerEntry &key, const uint seed)
|
uint BitTorrent::qHash(const TrackerEntry &key, const uint seed)
|
||||||
{
|
{
|
||||||
return (::qHash(key.url(), seed) ^ ::qHash(key.tier()));
|
return (::qHash(key.url, seed) ^ ::qHash(key.tier));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015, 2021 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -26,20 +26,16 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BITTORRENT_TRACKERENTRY_H
|
#pragma once
|
||||||
#define BITTORRENT_TRACKERENTRY_H
|
|
||||||
|
|
||||||
#include <libtorrent/announce_entry.hpp>
|
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
#include <QString>
|
||||||
class QString;
|
#include <QVector>
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class TrackerEntry
|
struct TrackerEntry
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
enum Status
|
enum Status
|
||||||
{
|
{
|
||||||
NotContacted = 1,
|
NotContacted = 1,
|
||||||
@@ -48,30 +44,28 @@ namespace BitTorrent
|
|||||||
NotWorking = 4
|
NotWorking = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
TrackerEntry() = default;
|
struct EndpointStats
|
||||||
TrackerEntry(const QString &url);
|
{
|
||||||
TrackerEntry(const lt::announce_entry &nativeEntry);
|
int protocolVersion = 1;
|
||||||
TrackerEntry(const TrackerEntry &other) = default;
|
|
||||||
TrackerEntry &operator=(const TrackerEntry &other) = default;
|
|
||||||
|
|
||||||
QString url() const;
|
Status status = NotContacted;
|
||||||
Status status() const;
|
int numSeeds = -1;
|
||||||
|
int numLeeches = -1;
|
||||||
|
int numDownloaded = -1;
|
||||||
|
};
|
||||||
|
|
||||||
int tier() const;
|
QString url;
|
||||||
void setTier(int value);
|
int tier = 0;
|
||||||
|
|
||||||
int numSeeds() const;
|
QVector<EndpointStats> endpoints {};
|
||||||
int numLeeches() const;
|
|
||||||
int numDownloaded() const;
|
|
||||||
|
|
||||||
const lt::announce_entry &nativeEntry() const;
|
// Deprecated fields
|
||||||
|
Status status = NotContacted;
|
||||||
private:
|
int numSeeds = -1;
|
||||||
lt::announce_entry m_nativeEntry;
|
int numLeeches = -1;
|
||||||
|
int numDownloaded = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator==(const TrackerEntry &left, const TrackerEntry &right);
|
bool operator==(const TrackerEntry &left, const TrackerEntry &right);
|
||||||
uint qHash(const TrackerEntry &key, uint seed);
|
uint qHash(const TrackerEntry &key, uint seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITTORRENT_TRACKERENTRY_H
|
|
||||||
|
|||||||
121
src/base/digest32.h
Normal file
121
src/base/digest32.h
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2015, 2021 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <libtorrent/sha1_hash.hpp>
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
class Digest32
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using UnderlyingType = lt::digest32<N>;
|
||||||
|
|
||||||
|
Digest32() = default;
|
||||||
|
Digest32(const Digest32 &other) = default;
|
||||||
|
|
||||||
|
Digest32(const UnderlyingType &nativeDigest)
|
||||||
|
: m_valid {true}
|
||||||
|
, m_nativeDigest {nativeDigest}
|
||||||
|
{
|
||||||
|
const QByteArray raw = QByteArray::fromRawData(nativeDigest.data(), length());
|
||||||
|
m_hashString = QString::fromLatin1(raw.toHex());
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr int length()
|
||||||
|
{
|
||||||
|
return UnderlyingType::size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid() const
|
||||||
|
{
|
||||||
|
return m_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator UnderlyingType() const
|
||||||
|
{
|
||||||
|
return m_nativeDigest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Digest32 fromString(const QString &digestString)
|
||||||
|
{
|
||||||
|
if (digestString.size() != (length() * 2))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const QByteArray raw = QByteArray::fromHex(digestString.toLatin1());
|
||||||
|
if (raw.size() != length()) // QByteArray::fromHex() will skip over invalid characters
|
||||||
|
return {};
|
||||||
|
|
||||||
|
Digest32 result;
|
||||||
|
result.m_valid = true;
|
||||||
|
result.m_hashString = digestString;
|
||||||
|
result.m_nativeDigest.assign(raw.constData());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString toString() const
|
||||||
|
{
|
||||||
|
return m_hashString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_valid = false;
|
||||||
|
UnderlyingType m_nativeDigest;
|
||||||
|
QString m_hashString;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
bool operator==(const Digest32<N> &left, const Digest32<N> &right)
|
||||||
|
{
|
||||||
|
return (static_cast<typename Digest32<N>::UnderlyingType>(left)
|
||||||
|
== static_cast<typename Digest32<N>::UnderlyingType>(right));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
bool operator!=(const Digest32<N> &left, const Digest32<N> &right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
bool operator<(const Digest32<N> &left, const Digest32<N> &right)
|
||||||
|
{
|
||||||
|
return static_cast<typename Digest32<N>::UnderlyingType>(left)
|
||||||
|
< static_cast<typename Digest32<N>::UnderlyingType>(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
uint qHash(const Digest32<N> &key, const uint seed)
|
||||||
|
{
|
||||||
|
return ::qHash(std::hash<typename Digest32<N>::UnderlyingType>()(key), seed);
|
||||||
|
}
|
||||||
@@ -26,17 +26,15 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FILESYSTEMWATCHER_H
|
#pragma once
|
||||||
#define FILESYSTEMWATCHER_H
|
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QtContainerFwd>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
class QStringList;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Subclassing QFileSystemWatcher in order to support Network File
|
* Subclassing QFileSystemWatcher in order to support Network File
|
||||||
* System watching (NFS, CIFS) on Linux and Mac OS.
|
* System watching (NFS, CIFS) on Linux and Mac OS.
|
||||||
@@ -70,5 +68,3 @@ private:
|
|||||||
QVector<QDir> m_watchedFolders;
|
QVector<QDir> m_watchedFolders;
|
||||||
QTimer m_watchTimer;
|
QTimer m_watchTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILESYSTEMWATCHER_H
|
|
||||||
|
|||||||
@@ -28,8 +28,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef HTTP_CONNECTION_H
|
#pragma once
|
||||||
#define HTTP_CONNECTION_H
|
|
||||||
|
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@@ -66,5 +65,3 @@ namespace Http
|
|||||||
QElapsedTimer m_idleTimer;
|
QElapsedTimer m_idleTimer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HTTP_CONNECTION_H
|
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HTTP_IREQUESTHANDLER_H
|
#pragma once
|
||||||
#define HTTP_IREQUESTHANDLER_H
|
|
||||||
|
|
||||||
namespace Http
|
namespace Http
|
||||||
{
|
{
|
||||||
@@ -42,5 +41,3 @@ namespace Http
|
|||||||
virtual Response processRequest(const Request &request, const Environment &env) = 0;
|
virtual Response processRequest(const Request &request, const Environment &env) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HTTP_IREQUESTHANDLER_H
|
|
||||||
|
|||||||
@@ -28,8 +28,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HTTP_REQUESTPARSER_H
|
#pragma once
|
||||||
#define HTTP_REQUESTPARSER_H
|
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
@@ -70,5 +69,3 @@ namespace Http
|
|||||||
Request m_request;
|
Request m_request;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HTTP_REQUESTPARSER_H
|
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HTTP_RESPONSEBUILDER_H
|
#pragma once
|
||||||
#define HTTP_RESPONSEBUILDER_H
|
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
@@ -50,5 +49,3 @@ namespace Http
|
|||||||
Response m_response;
|
Response m_response;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HTTP_RESPONSEBUILDER_H
|
|
||||||
|
|||||||
@@ -28,8 +28,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef HTTP_RESPONSEGENERATOR_H
|
#pragma once
|
||||||
#define HTTP_RESPONSEGENERATOR_H
|
|
||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
class QString;
|
class QString;
|
||||||
@@ -42,5 +41,3 @@ namespace Http
|
|||||||
QString httpDate();
|
QString httpDate();
|
||||||
void compressContent(Response &response);
|
void compressContent(Response &response);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HTTP_RESPONSEGENERATOR_H
|
|
||||||
|
|||||||
@@ -28,8 +28,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef HTTP_SERVER_H
|
#pragma once
|
||||||
#define HTTP_SERVER_H
|
|
||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QSslCertificate>
|
#include <QSslCertificate>
|
||||||
@@ -67,5 +66,3 @@ namespace Http
|
|||||||
QSslKey m_key;
|
QSslKey m_key;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HTTP_SERVER_H
|
|
||||||
|
|||||||
@@ -27,8 +27,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HTTP_TYPES_H
|
#pragma once
|
||||||
#define HTTP_TYPES_H
|
|
||||||
|
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -127,5 +126,3 @@ namespace Http
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HTTP_TYPES_H
|
|
||||||
|
|||||||
@@ -27,8 +27,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ICONPROVIDER_H
|
#pragma once
|
||||||
#define ICONPROVIDER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
@@ -51,5 +50,3 @@ protected:
|
|||||||
|
|
||||||
static IconProvider *m_instance;
|
static IconProvider *m_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ICONPROVIDER_H
|
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef QBT_INDEXRANGE_H
|
#pragma once
|
||||||
#define QBT_INDEXRANGE_H
|
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
@@ -38,8 +37,7 @@ class IndexInterval
|
|||||||
public:
|
public:
|
||||||
using IndexType = Index;
|
using IndexType = Index;
|
||||||
|
|
||||||
// TODO: add constexpr when using C++17
|
constexpr IndexInterval(const IndexType first, const IndexType last)
|
||||||
IndexInterval(const IndexType first, const IndexType last)
|
|
||||||
: m_first {first}
|
: m_first {first}
|
||||||
, m_last {last}
|
, m_last {last}
|
||||||
{
|
{
|
||||||
@@ -169,5 +167,3 @@ private:
|
|||||||
IndexType m_first;
|
IndexType m_first;
|
||||||
IndexDiffType m_size;
|
IndexDiffType m_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QBT_INDEXRANGE_H
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,15 +26,14 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LOGGER_H
|
#pragma once
|
||||||
#define LOGGER_H
|
|
||||||
|
|
||||||
#include <boost/circular_buffer.hpp>
|
#include <boost/circular_buffer.hpp>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVector>
|
#include <QtContainerFwd>
|
||||||
|
|
||||||
const int MAX_LOG_MESSAGES = 20000;
|
const int MAX_LOG_MESSAGES = 20000;
|
||||||
|
|
||||||
@@ -103,5 +102,3 @@ private:
|
|||||||
|
|
||||||
// Helper function
|
// Helper function
|
||||||
void LogMsg(const QString &message, const Log::MsgType &type = Log::NORMAL);
|
void LogMsg(const QString &message, const Log::MsgType &type = Log::NORMAL);
|
||||||
|
|
||||||
#endif // LOGGER_H
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
#include "base/net/downloadmanager.h"
|
#include "base/net/downloadmanager.h"
|
||||||
|
#include "base/version.h"
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DNSUPDATER_H
|
#pragma once
|
||||||
#define DNSUPDATER_H
|
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
@@ -84,5 +83,3 @@ namespace Net
|
|||||||
QString m_password;
|
QString m_password;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DNSUPDATER_H
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user