You've already forked qBittorrent
							
							
				mirror of
				https://github.com/qbittorrent/qBittorrent
				synced 2025-10-26 06:12:17 +01:00 
			
		
		
		
	Compare commits
	
		
			165 Commits
		
	
	
		
			release-5.
			...
			v5_0_x
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 805c80bf51 | ||
|   | 4b794a9930 | ||
|   | 96b27a313e | ||
|   | c39849bd3b | ||
|   | daf7af0d7b | ||
|   | a6809efbbb | ||
|   | ddd8fbd34e | ||
|   | 13fcd3d635 | ||
|   | 3c6ff0097f | ||
|   | 03dc089148 | ||
|   | 100ee5dbe0 | ||
|   | 310a9d8e1a | ||
|   | 677cabcbdf | ||
|   | b86079974c | ||
|   | ca6a89e238 | ||
|   | 0132b17af6 | ||
|   | 505c1e1c0a | ||
|   | ecde201ec5 | ||
|   | 730bf957a4 | ||
|   | 069cd029eb | ||
|   | 375e6800e9 | ||
|   | 09fb92466a | ||
|   | 69321f0e94 | ||
|   | f39e066672 | ||
|   | 6a5ea93c92 | ||
|   | 35dce07c63 | ||
|   | 0188e11dd7 | ||
|   | 1dc348539b | ||
|   | 241a0e91bf | ||
|   | 68f7295500 | ||
|   | 53adb7bfa8 | ||
|   | 6128f6eecc | ||
|   | d156a44f8d | ||
|   | c3c7f28bad | ||
|   | 9ac14cdf9f | ||
|   | b899ea8c40 | ||
|   | 0d7c367332 | ||
|   | 22826499d5 | ||
|   | dbfd830b56 | ||
|   | ad3348b95f | ||
|   | 44b08fcb74 | ||
|   | 71b752baf3 | ||
|   | 15b6091261 | ||
|   | abe457389d | ||
|   | abce4cd1bc | ||
|   | 2bfb336905 | ||
|   | 2dee65fa52 | ||
|   | 423b3ed9bf | ||
|   | 3454f064f0 | ||
|   | ac9ca4f452 | ||
|   | 09899a7d0d | ||
|   | 9ab3c573dc | ||
|   | 993eb25323 | ||
|   | 1e27e6504e | ||
|   | 330dce6aa2 | ||
|   | 39b965af48 | ||
|   | 5e105b0348 | ||
|   | f2b2a2b034 | ||
|   | 10499dffe9 | ||
|   | eea01b94a3 | ||
|   | 374951f6f2 | ||
|   | 6d6f9bc619 | ||
|   | 84ee620fdc | ||
|   | 6079b25419 | ||
|   | fe24bc825b | ||
|   | 94136262a8 | ||
|   | f52947e27e | ||
|   | 315e88aee9 | ||
|   | 565c6d843a | ||
|   | 9104351c89 | ||
|   | e58b0a65d2 | ||
|   | 878d829904 | ||
|   | 063f77bc6c | ||
|   | 2a4077414f | ||
|   | 2a44253802 | ||
|   | 4712eba0dc | ||
|   | 983b7814aa | ||
|   | e082a21751 | ||
|   | 7dd1d1bac8 | ||
|   | 49f57b1049 | ||
|   | fbf68a0649 | ||
|   | 39229dc06a | ||
|   | bb314e1555 | ||
|   | a3a8b15828 | ||
|   | b579afe1aa | ||
|   | 93096dba56 | ||
|   | 6379c33964 | ||
|   | 84372de675 | ||
|   | 403b7c7c35 | ||
|   | b2fab43865 | ||
|   | 387821267f | ||
|   | dd7ef8e934 | ||
|   | cce295faeb | ||
|   | db5479ea01 | ||
|   | e1216c4c9a | ||
|   | f4a0868426 | ||
|   | 59a5fcf7d0 | ||
|   | f9a2b02a8d | ||
|   | 04f6a565f3 | ||
|   | 3e96048ee4 | ||
|   | d4ccf3001c | ||
|   | 64506f16bd | ||
|   | 24a7a835af | ||
|   | 93b9bf9552 | ||
|   | f4125601de | ||
|   | 2d67729617 | ||
|   | 878ebbed41 | ||
|   | c61c3d7cd8 | ||
|   | 978fbbdc0d | ||
|   | 63689cf763 | ||
|   | cebc72d3cf | ||
|   | a67bd271c6 | ||
|   | a8cffbb205 | ||
|   | 7dfb0110d4 | ||
|   | 3ad8fcbdd2 | ||
|   | 195eae5f3d | ||
|   | 920ae26f7b | ||
|   | 09ed0d6b66 | ||
|   | 4f0cc8aa11 | ||
|   | 4d490c84e7 | ||
|   | 96607ce874 | ||
|   | 418edc7471 | ||
|   | bd01b7c4df | ||
|   | b0ac763048 | ||
|   | 127d2d6f0b | ||
|   | 4149609e78 | ||
|   | 78c549f83e | ||
|   | a3a53e2e0e | ||
|   | 5aaa43e01d | ||
|   | 86745d7b07 | ||
|   | 210650a5ee | ||
|   | fe93b6d0d8 | ||
|   | e8b585acd8 | ||
|   | cea20141a9 | ||
|   | 0f5a27ed50 | ||
|   | c2cf898ccd | ||
|   | 5e5aa8a563 | ||
|   | 12a4c3fda2 | ||
|   | 5f50b701d2 | ||
|   | 9f20d9c3aa | ||
|   | 05e3130baa | ||
|   | 683492648f | ||
|   | 2f2e158877 | ||
|   | e60e96cb0e | ||
|   | 5f31208bf1 | ||
|   | fa58e58e70 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 671943a9a6 | ||
|   | 8bad80bcdd | ||
|   | c44e300507 | ||
|   | 318a677e8f | ||
|   | 0246df790a | ||
|   | 782fbc1425 | ||
|   | 7deccd5592 | ||
|   | 4a36fe7278 | ||
|   | 1c5af96ad8 | ||
|   | 3bb47a5410 | ||
|   | d7abeb4bf0 | ||
|   | a19d623ead | ||
|   | 1ef21bc2b7 | ||
|   | 4687b4e8e4 | ||
|   | d2e5163861 | ||
|   | 8a15ea8026 | ||
|   | 2b99554813 | ||
|   | e6638f9c19 | ||
|   | ec6eac2ba1 | 
							
								
								
									
										7
									
								
								.github/workflows/ci_macos.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.github/workflows/ci_macos.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -23,7 +23,6 @@ jobs: | ||||
|  | ||||
|     env: | ||||
|       boost_path: "${{ github.workspace }}/../boost" | ||||
|       openssl_root: "$(brew --prefix openssl@3)" | ||||
|       libtorrent_path: "${{ github.workspace }}/../libtorrent" | ||||
|  | ||||
|     steps: | ||||
| @@ -70,7 +69,7 @@ jobs: | ||||
|           mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}" | ||||
|  | ||||
|       - name: Install Qt | ||||
|         uses: jurplel/install-qt-action@v3 | ||||
|         uses: jurplel/install-qt-action@v4 | ||||
|         with: | ||||
|           version: ${{ matrix.qt_version }} | ||||
|           archives: qtbase qtdeclarative qtsvg qttools | ||||
| @@ -94,8 +93,7 @@ jobs: | ||||
|             -DCMAKE_CXX_STANDARD=17 \ | ||||
|             -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ | ||||
|             -DBOOST_ROOT="${{ env.boost_path }}" \ | ||||
|             -Ddeprecated-functions=OFF \ | ||||
|             -DOPENSSL_ROOT_DIR="${{ env.openssl_root }}" | ||||
|             -Ddeprecated-functions=OFF | ||||
|           cmake --build build | ||||
|           sudo cmake --install build | ||||
|  | ||||
| @@ -109,7 +107,6 @@ jobs: | ||||
|             -DCMAKE_BUILD_TYPE=RelWithDebInfo \ | ||||
|             -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ | ||||
|             -DBOOST_ROOT="${{ env.boost_path }}" \ | ||||
|             -DOPENSSL_ROOT_DIR="${{ env.openssl_root }}" \ | ||||
|             -DTESTING=ON \ | ||||
|             -DVERBOSE_CONFIGURE=ON \ | ||||
|             -D${{ matrix.qbt_gui }} | ||||
|   | ||||
							
								
								
									
										12
									
								
								.github/workflows/ci_python.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/ci_python.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -53,7 +53,7 @@ jobs: | ||||
|           python-version: '3.7' | ||||
|  | ||||
|       - name: Install tools (search engine) | ||||
|         run: pip install bandit pycodestyle pyflakes | ||||
|         run: pip install bandit mypy pycodestyle pyflakes pyright | ||||
|  | ||||
|       - name: Gather files (search engine) | ||||
|         run: | | ||||
| @@ -61,6 +61,16 @@ jobs: | ||||
|           echo $PY_FILES | ||||
|           echo "PY_FILES=$PY_FILES" >> "$GITHUB_ENV" | ||||
|  | ||||
|       - name: Check typings  (search engine) | ||||
|         run: | | ||||
|           MYPYPATH="src/searchengine/nova3" \ | ||||
|           mypy \ | ||||
|             --follow-imports skip \ | ||||
|             --strict \ | ||||
|             $PY_FILES | ||||
|           pyright \ | ||||
|             $PY_FILES | ||||
|  | ||||
|       - name: Lint code (search engine) | ||||
|         run: | | ||||
|           pyflakes $PY_FILES | ||||
|   | ||||
							
								
								
									
										3
									
								
								.github/workflows/ci_ubuntu.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/ci_ubuntu.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -64,7 +64,7 @@ jobs: | ||||
|           mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}" | ||||
|  | ||||
|       - name: Install Qt | ||||
|         uses: jurplel/install-qt-action@v3 | ||||
|         uses: jurplel/install-qt-action@v4 | ||||
|         with: | ||||
|           version: ${{ matrix.qt_version }} | ||||
|           archives: icu qtbase qtdeclarative qtsvg qttools | ||||
| @@ -134,7 +134,6 @@ jobs: | ||||
|  | ||||
|       - name: Install AppImage | ||||
|         run: | | ||||
|           sudo apt install libfuse2 | ||||
|           curl \ | ||||
|             -L \ | ||||
|             -Z \ | ||||
|   | ||||
							
								
								
									
										32
									
								
								.github/workflows/ci_windows.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								.github/workflows/ci_windows.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -93,9 +93,9 @@ jobs: | ||||
|           move "${{ github.workspace }}/../boost_*" "${{ env.boost_path }}" | ||||
|  | ||||
|       - name: Install Qt | ||||
|         uses: jurplel/install-qt-action@v3 | ||||
|         uses: jurplel/install-qt-action@v4 | ||||
|         with: | ||||
|           version: "6.7.0" | ||||
|           version: "6.7.3" | ||||
|           archives: qtbase qtsvg qttools | ||||
|           cache: true | ||||
|  | ||||
| @@ -153,26 +153,26 @@ jobs: | ||||
|           copy build/qbittorrent.pdb upload/qBittorrent | ||||
|           copy dist/windows/qt.conf upload/qBittorrent | ||||
|           # runtimes | ||||
|           copy "${{ env.Qt6_DIR }}/bin/Qt6Core.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt6_DIR }}/bin/Qt6Gui.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt6_DIR }}/bin/Qt6Network.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt6_DIR }}/bin/Qt6Sql.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt6_DIR }}/bin/Qt6Svg.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt6_DIR }}/bin/Qt6Widgets.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt6_DIR }}/bin/Qt6Xml.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Core.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Gui.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Network.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Sql.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Svg.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Widgets.dll" upload/qBittorrent | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Xml.dll" upload/qBittorrent | ||||
|           mkdir upload/qBittorrent/plugins/iconengines | ||||
|           copy "${{ env.Qt6_DIR }}/plugins/iconengines/qsvgicon.dll" upload/qBittorrent/plugins/iconengines | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/plugins/iconengines/qsvgicon.dll" upload/qBittorrent/plugins/iconengines | ||||
|           mkdir upload/qBittorrent/plugins/imageformats | ||||
|           copy "${{ env.Qt6_DIR }}/plugins/imageformats/qico.dll" upload/qBittorrent/plugins/imageformats | ||||
|           copy "${{ env.Qt6_DIR }}/plugins/imageformats/qsvg.dll" upload/qBittorrent/plugins/imageformats | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/plugins/imageformats/qico.dll" upload/qBittorrent/plugins/imageformats | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/plugins/imageformats/qsvg.dll" upload/qBittorrent/plugins/imageformats | ||||
|           mkdir upload/qBittorrent/plugins/platforms | ||||
|           copy "${{ env.Qt6_DIR }}/plugins/platforms/qwindows.dll" upload/qBittorrent/plugins/platforms | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/plugins/platforms/qwindows.dll" upload/qBittorrent/plugins/platforms | ||||
|           mkdir upload/qBittorrent/plugins/sqldrivers | ||||
|           copy "${{ env.Qt6_DIR }}/plugins/sqldrivers/qsqlite.dll" upload/qBittorrent/plugins/sqldrivers | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/plugins/sqldrivers/qsqlite.dll" upload/qBittorrent/plugins/sqldrivers | ||||
|           mkdir upload/qBittorrent/plugins/styles | ||||
|           copy "${{ env.Qt6_DIR }}/plugins/styles/qmodernwindowsstyle.dll" upload/qBittorrent/plugins/styles | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/plugins/styles/qmodernwindowsstyle.dll" upload/qBittorrent/plugins/styles | ||||
|           mkdir upload/qBittorrent/plugins/tls | ||||
|           copy "${{ env.Qt6_DIR }}/plugins/tls/qschannelbackend.dll" upload/qBittorrent/plugins/tls | ||||
|           copy "${{ env.Qt_ROOT_DIR }}/plugins/tls/qschannelbackend.dll" upload/qBittorrent/plugins/tls | ||||
|           # cmake additionals | ||||
|           mkdir upload/cmake | ||||
|           copy build/compile_commands.json upload/cmake | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/coverity-scan.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/coverity-scan.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -52,7 +52,7 @@ jobs: | ||||
|           mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}" | ||||
|  | ||||
|       - name: Install Qt | ||||
|         uses: jurplel/install-qt-action@v3 | ||||
|         uses: jurplel/install-qt-action@v4 | ||||
|         with: | ||||
|           version: ${{ matrix.qt_version }} | ||||
|           archives: icu qtbase qtdeclarative qtsvg qttools | ||||
|   | ||||
| @@ -78,11 +78,7 @@ repos: | ||||
|           m4/.* | | ||||
|           src/base/3rdparty/.* | | ||||
|           src/searchengine/nova3/socks.py | | ||||
|           src/webui/www/private/lang/.* | | ||||
|           src/webui/www/private/scripts/lib/.* | | ||||
|           src/webui/www/public/lang/.* | | ||||
|           src/webui/www/public/scripts/lib/.* | | ||||
|           src/webui/www/transifex/.* | ||||
|           src/webui/www/private/scripts/lib/.* | ||||
|         )$ | ||||
|       exclude_types: | ||||
|         - ts | ||||
| @@ -106,11 +102,7 @@ repos: | ||||
|           m4/.* | | ||||
|           src/base/3rdparty/.* | | ||||
|           src/searchengine/nova3/socks.py | | ||||
|           src/webui/www/private/lang/.* | | ||||
|           src/webui/www/private/scripts/lib/.* | | ||||
|           src/webui/www/public/lang/.* | | ||||
|           src/webui/www/public/scripts/lib/.* | | ||||
|           src/webui/www/transifex/.* | ||||
|           src/webui/www/private/scripts/lib/.* | ||||
|         )$ | ||||
|       exclude_types: | ||||
|         - svg | ||||
|   | ||||
							
								
								
									
										12
									
								
								.tx/config
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								.tx/config
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| [main] | ||||
| host = https://www.transifex.com | ||||
|  | ||||
| [o:sledgehammer999:p:qbittorrent:r:qbittorrent_master] | ||||
| [o:sledgehammer999:p:qbittorrent:r:qbittorrent_v50x] | ||||
| file_filter  = src/lang/qbittorrent_<lang>.ts | ||||
| source_file  = src/lang/qbittorrent_en.ts | ||||
| source_lang  = en | ||||
| @@ -9,7 +9,7 @@ type         = QT | ||||
| minimum_perc = 23 | ||||
| lang_map     = pt: pt_PT, zh: zh_CN | ||||
|  | ||||
| [o:sledgehammer999:p:qbittorrent:r:qbittorrent_webui] | ||||
| [o:sledgehammer999:p:qbittorrent:r:qbittorrent_webui_v50x] | ||||
| file_filter  = src/webui/www/translations/webui_<lang>.ts | ||||
| source_file  = src/webui/www/translations/webui_en.ts | ||||
| source_lang  = en | ||||
| @@ -17,14 +17,6 @@ type         = QT | ||||
| minimum_perc = 23 | ||||
| lang_map     = pt: pt_PT, zh: zh_CN | ||||
|  | ||||
| [o:sledgehammer999:p:qbittorrent:r:qbittorrent_webui_json] | ||||
| file_filter  = src/webui/www/transifex/<lang>.json | ||||
| source_file  = src/webui/www/transifex/en.json | ||||
| source_lang  = en | ||||
| type         = KEYVALUEJSON | ||||
| minimum_perc = 23 | ||||
| lang_map     = pt: pt_PT, zh: zh_CN | ||||
|  | ||||
| [o:sledgehammer999:p:qbittorrent:r:qbittorrentdesktop_master] | ||||
| source_file  = dist/unix/org.qbittorrent.qBittorrent.desktop | ||||
| source_lang  = en | ||||
|   | ||||
							
								
								
									
										106
									
								
								Changelog
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								Changelog
									
									
									
									
									
								
							| @@ -1,4 +1,67 @@ | ||||
| Unreleased - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.0 | ||||
| Sun Apr 13th 2025 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.5 | ||||
|     - FEATURE: Add an advanced setting for setting the "Add New Torrent" dialog as modal (glassez) | ||||
|     - BUGFIX: Improve command line parameters serialization (glassez) | ||||
|     - BUGFIX: Declare missing color IDs for theming (glassez) | ||||
|     - WINDOWS: NSIS: Update Swedish translation (Daniel Nylander) | ||||
|  | ||||
| Tue Feb 18th 2025 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.4 | ||||
|     - BUGFIX: Fix cannot remove trackers via WebAPI (Chocobo1) | ||||
|     - BUGFIX: Fix torrent content checkbox state under certain conditions (thalieht) | ||||
|     - BUGFIX: Hide zero and infinity values in peer list only when that setting is set to `Always` (thalieht) | ||||
|     - BUGFIX: Remove stopped torrent from "error" tracker filter (glassez) | ||||
|     - WEBUI: Fix memory leak in context menus (skomerko) | ||||
|     - WEBAPI: Don't trim string parameters (glassez) | ||||
|     - WINDOWS: Handle Qt style options uniformly (glassez) | ||||
|     - WINDOWS: NSIS: Update Portuguese translation (Hugo Carvalho) | ||||
|     - MACOS: Avoid memory leak (Chocobo1) | ||||
|  | ||||
| Mon Dec 16th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.3 | ||||
|     - BUGFIX: Discard obsolete "state update" events after torrent is reloaded (glassez) | ||||
|     - BUGFIX: Fix incorrect SQL column definition (glassez) | ||||
|     - BUGFIX: Avoid redundant requests of announce entries from libtorrent (glassez) | ||||
|     - WEBUI: Fix removing tracker URL with '|' character (Thomas Piccirello) | ||||
|     - WEBUI: Fix reloading page after login (Evgenii Ryshkov) | ||||
|     - WEBAPI: Fix incorrect key in torrent creator (Bartu Özen) | ||||
|     - RSS: Don't add duplicate episodes to previously matched (wavygecko) | ||||
|     - RSS: Use cached current time when parsing RSS feed (glassez) | ||||
|     - WINDOWS: Don't follow symlink when creating torrents on Windows (Chocobo1) | ||||
|     - WINDOWS: NSIS: Update Italian translation (Giacomo411) | ||||
|  | ||||
| Sun Nov 17th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.2 | ||||
|     - BUGFIX: Remove trackers from previous category when moved to new one (glassez) | ||||
|     - BUGFIX: Fix `.torrent` file could not be deleted when torrent is canceled (glassez) | ||||
|     - BUGFIX: Reset tracker entries when pausing the session (glassez) | ||||
|     - BUGFIX: Check real palette darkness to detect "dark theme" (glassez) | ||||
|     - BUGFIX: Correctly handle "torrent finished" events (glassez) | ||||
|     - BUGFIX: Preserve initial torrent progress while checking resume data (glassez) | ||||
|     - BUGFIX: Avoid reapplying Mark-of-the-Web when it already exists (Chocobo1) | ||||
|     - BUGFIX: Don't apply Mark-of-the-Web on existing files (Chocobo1) | ||||
|     - WEBUI: Add color scheme switcher (sledgehammer999) | ||||
|     - SEARCH: Correctly delete the moved search tab (glassez) | ||||
|     - WINDOWS: Correctly save and restore Qt style setting (glassez) | ||||
|     - WINDOWS: NSIS: update Luxembourgish, Simplified Chinese and Traditional Chinese translations (Ikko Eltociear Ashimine, 3gf8jv4dv) | ||||
|  | ||||
| Mon Oct 28th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.1 | ||||
|     - FEATURE: Add "Simple pread/pwrite" disk IO type (Hanabishi) | ||||
|     - BUGFIX: Don't ignore SSL errors (sledgehammer999) | ||||
|     - BUGFIX: Don't try to apply Mark-of-the-Web to nonexistent files (glassez) | ||||
|     - BUGFIX: Disable "Move to trash" option by default (glassez) | ||||
|     - BUGFIX: Disable the ability to create torrents with a piece size of 256MiB (stalkerok) | ||||
|     - BUGFIX: Allow to choose Qt style (glassez) | ||||
|     - BUGFIX: Always notify user about duplicate torrent (glassez) | ||||
|     - BUGFIX: Correctly handle "torrent finished after move" event (glassez) | ||||
|     - BUGFIX: Correctly apply filename filter when `!qB` extension is enabled (glassez) | ||||
|     - BUGFIX: Improve color scheme change detection (glassez) | ||||
|     - BUGFIX: Fix button state for SSL certificate check (Chocobo1) | ||||
|     - WEBUI: Fix CSS that results in hidden torrent list in some browsers (skomerko) | ||||
|     - WEBUI: Use proper text color to highlight items in all filter lists (skomerko) | ||||
|     - WEBUI: Fix 'rename files' dialog cannot be opened more than once (Chocobo1) | ||||
|     - WEBUI: Fix UI of Advanced Settings to show all settings (glassez) | ||||
|     - WEBUI: Free resources allocated by web session once it is destructed (dyseg) | ||||
|     - SEARCH: Import correct libraries (Chocobo1) | ||||
|     - OTHER: Sync flag icons with upstream (xavier2k6) | ||||
|  | ||||
| Sun Sep 29th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.0 | ||||
|     - FEATURE: Support creating .torrent with larger piece size (Chocobo1) | ||||
|     - FEATURE: Improve tracker entries handling (glassez) | ||||
|     - FEATURE: Add separate filter item for tracker errors (glassez) | ||||
| @@ -12,14 +75,30 @@ Unreleased - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.0 | ||||
|     - FEATURE: Enable Ctrl+F hotkey for more inputs (thalieht) | ||||
|     - FEATURE: Add seeding limits to RSS and Watched folders options UI (glassez) | ||||
|     - FEATURE: Subcategories implicitly follow the parent category options (glassez) | ||||
|     - FEATURE: Add support for SSL torrents (Chocobo1, Radu Carpa) | ||||
|     - FEATURE: Add option to name each qbittorrent instance (Chocobo1) | ||||
|     - FEATURE: Add button for sending test email (Thomas Piccirello) | ||||
|     - FEATURE: Allow torrents to override default share limit action (glassez) | ||||
|     - FEATURE: Use Start/Stop instead of Resume/Pause (thalieht) | ||||
|     - FEATURE: Add the Popularity metric (Aliaksei Urbanski) | ||||
|     - FEATURE: Focus on Download button if torrent link retrieved from the clipboard (glassez) | ||||
|     - FEATURE: Add ability to pause/resume entire BitTorrent session (glassez) | ||||
|     - FEATURE: Add an option to set BitTorrent session shutdown timeout (glassez) | ||||
|     - FEATURE: Apply "Excluded file names" to folder names as well (glassez) | ||||
|     - FEATURE: Allow to use regular expression to filter torrent content (glassez) | ||||
|     - FEATURE: Allow to move content files to Trash instead of deleting them (glassez) | ||||
|     - FEATURE: Add ability to display torrent "privateness" in UI (ManiMatter) | ||||
|     - FEATURE: Add a flag in `Peers` tab denoting a connection using NAT hole punching (stalkerok) | ||||
|     - BUGFIX: Display error message when unrecoverable error occurred (glassez) | ||||
|     - BUGFIX: Update size of selected files when selection is changed (glassez) | ||||
|     - BUGFIX: Normalize tags by trimming leading/trailing whitespace (glassez) | ||||
|     - BUGFIX: Correctly handle share limits in torrent options dialog (glassez) | ||||
|     - BUGFIX: Adjust tracker tier when adding additional trackers (Chocobo1) | ||||
|     - BUGFIX: Fix inconsistent naming between `Done/Progress` column (luzpaz) | ||||
|     - BUGFIX: Sanitize peer client names (Hanabishi) | ||||
|     - BUGFIX: Apply share limits immediately when torrent downloading is finished (glassez) | ||||
|     - BUGFIX: Show download progress for folders with zero byte size as 100 instead of 0 (vikas_c) | ||||
|     - BUGFIX: Fix highlighted piece color (Prince Gupta) | ||||
|     - BUGFIX: Apply "merge trackers" logic regardless of way the torrent is added (glassez) | ||||
|     - WEBUI: Improve WebUI responsiveness (Chocobo1) | ||||
|     - WEBUI: Do not exit the app when WebUI has failed to start (Hanabishi) | ||||
|     - WEBUI: Add `Moving` filter to side panel (xavier2k6) | ||||
| @@ -28,14 +107,37 @@ Unreleased - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.0 | ||||
|     - WEBUI: Leave the fields empty when value is invalid (Chocobo1) | ||||
|     - WEBUI: Use natural sorting (Chocobo1) | ||||
|     - WEBUI: Improve WebUI login behavior (JayRet) | ||||
|     - WEBUI: Conditionally show filters sidebar (Thomas Piccirello) | ||||
|     - WEBUI: Add support for running concurrent searches (Thomas Piccirello) | ||||
|     - WEBUI: Improve accuracy of trackers list (Thomas Piccirello) | ||||
|     - WEBUI: Fix error when category doesn't exist (Thomas Piccirello) | ||||
|     - WEBUI: Improve table scrolling and selection on mobile (Thomas Piccirello) | ||||
|     - WEBUI: Restore search tabs on load (Thomas Piccirello) | ||||
|     - WEBUI: Restore previously used tab on load (Thomas Piccirello) | ||||
|     - WEBUI: Increase default height of `Share ratio limit` dialog (thalieht) | ||||
|     - WEBUI: Use enabled search plugins by default (Thomas Piccirello) | ||||
|     - WEBUI: Add columns `Incomplete Save Path`, `Info Hash v1`, `Info Hash v2` (thalieht) | ||||
|     - WEBUI: Always create generic filter items (skomerko) | ||||
|     - WEBUI: Provide `Use Category paths in Manual Mode` option (skomerko) | ||||
|     - WEBUI: Provide `Merge trackers to existing torrent` option (skomerko) | ||||
|     - WEBAPI: Fix wrong timestamp values (Chocobo1) | ||||
|     - WEBAPI: Send binary data with filename and mime type specified (glassez) | ||||
|     - WEBAPI: Expose API for the torrent creator (glassez, Radu Carpa) | ||||
|     - WEBAPI: Add support for SSL torrents (Chocobo1, Radu Carpa) | ||||
|     - WEBAPI: Provide endpoint for listing directory content (Paweł Kotiuk) | ||||
|     - WEBAPI: Provide "private" flag via "torrents/info" endpoint (ManiMatter) | ||||
|     - WEBAPI: Add a way to download .torrent file using search plugin (glassez) | ||||
|     - WEBAPI: Add "private" filter for "torrents/info" endpoint (ManiMatter) | ||||
|     - WEBAPI: Add root_path to "torrents/info" result (David Newhall) | ||||
|     - RSS: Show RSS feed title in HTML browser (Jay) | ||||
|     - RSS: Allow to set delay between requests to the same host (jNullj) | ||||
|     - SEARCH: Allow users to specify Python executable path (Chocobo1) | ||||
|     - SEARCH: Lazy load search plugins (milahu) | ||||
|     - SEARCH: Add date column to the built-in search engine (ducalex) | ||||
|     - SEARCH: Allow to rearrange search tabs (glassez) | ||||
|     - WINDOWS: Use Fusion style on Windows 10+. It has better compatibility with dark mode (glassez) | ||||
|     - WINDOWS: Allow to set qBittorrent as default program (glassez) | ||||
|     - WINDOWS: Don't access "Favorites" folder unexpectedly (glassez) | ||||
|     - LINUX: Add support for systemd power management (Chocobo1) | ||||
|     - LINUX: Add support for localized man pages (Victor Chernyakin) | ||||
|     - LINUX: Specify a locale if none is set (Chocobo1) | ||||
|   | ||||
							
								
								
									
										4
									
								
								dist/mac/Info.plist
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								dist/mac/Info.plist
									
									
									
									
										vendored
									
									
								
							| @@ -55,7 +55,7 @@ | ||||
| 	<key>CFBundlePackageType</key> | ||||
| 	<string>APPL</string> | ||||
| 	<key>CFBundleShortVersionString</key> | ||||
| 	<string>5.0.0</string> | ||||
| 	<string>5.0.5</string> | ||||
| 	<key>CFBundleExecutable</key> | ||||
| 	<string>${EXECUTABLE_NAME}</string> | ||||
| 	<key>CFBundleIdentifier</key> | ||||
| @@ -67,7 +67,7 @@ | ||||
| 	<key>NSAppleScriptEnabled</key> | ||||
| 	<string>YES</string> | ||||
| 	<key>NSHumanReadableCopyright</key> | ||||
| 	<string>Copyright © 2006-2024 The qBittorrent project</string> | ||||
| 	<string>Copyright © 2006-2025 The qBittorrent project</string> | ||||
| 	<key>UTExportedTypeDeclarations</key> | ||||
| 	<array> | ||||
| 		<dict> | ||||
|   | ||||
							
								
								
									
										146
									
								
								dist/unix/org.qbittorrent.qBittorrent.desktop
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										146
									
								
								dist/unix/org.qbittorrent.qBittorrent.desktop
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -62,6 +62,6 @@ | ||||
|   <url type="contribute">https://github.com/qbittorrent/qBittorrent/blob/master/CONTRIBUTING.md</url> | ||||
|   <content_rating type="oars-1.1"/> | ||||
|   <releases> | ||||
|     <release version="5.0.0~beta1" date="2024-03-19"/> | ||||
|     <release version="5.0.5" date="2025-04-13"/> | ||||
|   </releases> | ||||
| </component> | ||||
|   | ||||
							
								
								
									
										4
									
								
								dist/windows/config.nsh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								dist/windows/config.nsh
									
									
									
									
										vendored
									
									
								
							| @@ -14,7 +14,7 @@ | ||||
| ; 4.5.1.3 -> good | ||||
| ; 4.5.1.3.2 -> bad | ||||
| ; 4.5.0beta -> bad | ||||
| !define /ifndef QBT_VERSION "5.0.0" | ||||
| !define /ifndef QBT_VERSION "5.0.5" | ||||
|  | ||||
| ; Option that controls the installer's window name | ||||
| ; If set, its value will be used like this: | ||||
| @@ -86,7 +86,7 @@ OutFile "qbittorrent_${QBT_INSTALLER_FILENAME}_setup.exe" | ||||
| ;Installer Version Information | ||||
| VIAddVersionKey "ProductName" "qBittorrent" | ||||
| VIAddVersionKey "CompanyName" "The qBittorrent project" | ||||
| VIAddVersionKey "LegalCopyright" "Copyright ©2006-2024 The qBittorrent project" | ||||
| VIAddVersionKey "LegalCopyright" "Copyright ©2006-2025 The qBittorrent project" | ||||
| VIAddVersionKey "FileDescription" "qBittorrent - A Bittorrent Client" | ||||
| VIAddVersionKey "FileVersion" "${QBT_VERSION}" | ||||
|  | ||||
|   | ||||
| @@ -29,7 +29,7 @@ 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_ITALIAN} "Questo installer funziona solo con versioni di Windows a 64bit." | ||||
| ;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 (1809) / Windows Server 2019." | ||||
| LangString inst_requires_win10 ${LANG_ITALIAN}  "This installer requires at least Windows 10 (1809) / Windows Server 2019." | ||||
| LangString inst_requires_win10 ${LANG_ITALIAN}  "Questo installer richiede almeno Windows 10 (1809) / Windows Server 2019." | ||||
| ;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent" | ||||
| LangString inst_uninstall_link_description ${LANG_ITALIAN} "Disinstalla qBittorrent" | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ LangString inst_magnet ${LANG_LUXEMBOURGISH} "Magnet-Linken mat qBittorrent opma | ||||
| ;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule" | ||||
| LangString inst_firewall ${LANG_LUXEMBOURGISH} "Reegel an der Windows Firewall dobäisetzen" | ||||
| ;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_LUXEMBOURGISH} "D'Windows path lenght (Padlängtbeschränkung) desaktivéieren (260 Zeechen MAX_PATH Beschränkung, erfuerdert min. Windows 10 1607)" | ||||
| LangString inst_pathlimit ${LANG_LUXEMBOURGISH} "D'Windows path length (Padlängtbeschränkung) desaktivéieren (260 Zeechen MAX_PATH Beschränkung, erfuerdert min. Windows 10 1607)" | ||||
| ;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule" | ||||
| LangString inst_firewallinfo ${LANG_LUXEMBOURGISH} "Reegel an der Windows Firewall dobäisetzen" | ||||
| ;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing." | ||||
|   | ||||
| @@ -7,7 +7,7 @@ LangString inst_desktop ${LANG_PORTUGUESE} "Criar atalho no ambiente de trabalho | ||||
| ;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut" | ||||
| LangString inst_startmenu ${LANG_PORTUGUESE} "Criar atalho no menu Iniciar" | ||||
| ;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up" | ||||
| LangString inst_startup ${LANG_PORTUGUESE} "Iniciar o qBittorrent na inicialização do Windows" | ||||
| LangString inst_startup ${LANG_PORTUGUESE} "Iniciar o qBittorrent no arranque do Windows" | ||||
| ;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent" | ||||
| LangString inst_torrent ${LANG_PORTUGUESE} "Abrir ficheiros .torrent com o qBittorrent" | ||||
| ;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent" | ||||
| @@ -29,7 +29,7 @@ LangString launch_qbt ${LANG_PORTUGUESE} "Iniciar qBittorrent." | ||||
| ;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions." | ||||
| LangString inst_requires_64bit ${LANG_PORTUGUESE} "Este instalador funciona apenas em versões Windows de 64 bits." | ||||
| ;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 (1809) / Windows Server 2019." | ||||
| LangString inst_requires_win10 ${LANG_PORTUGUESE}  "This installer requires at least Windows 10 (1809) / Windows Server 2019." | ||||
| LangString inst_requires_win10 ${LANG_PORTUGUESE}  "Este instalador requer, pelo menos, o Windows 10 (1809) / Windows Server 2019." | ||||
| ;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent" | ||||
| LangString inst_uninstall_link_description ${LANG_PORTUGUESE} "Desinstalar qBittorrent" | ||||
|  | ||||
|   | ||||
| @@ -23,13 +23,13 @@ LangString inst_warning ${LANG_SIMPCHINESE} "qBittorrent 正在运行。 安装 | ||||
| ;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact." | ||||
| LangString inst_uninstall_question ${LANG_SIMPCHINESE} "当前版本会被卸载。 用户设置和种子会被完整保留。" | ||||
| ;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version." | ||||
| LangString inst_unist ${LANG_SIMPCHINESE} "卸载以前的版本。" | ||||
| LangString inst_unist ${LANG_SIMPCHINESE} "正在卸载以前的版本。" | ||||
| ;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent." | ||||
| LangString launch_qbt ${LANG_SIMPCHINESE} "启动 qBittorrent。" | ||||
| ;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions." | ||||
| LangString inst_requires_64bit ${LANG_SIMPCHINESE} "此安装程序仅支持 64 位 Windows 系统。" | ||||
| ;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 (1809) / Windows Server 2019." | ||||
| LangString inst_requires_win10 ${LANG_SIMPCHINESE}  "This installer requires at least Windows 10 (1809) / Windows Server 2019." | ||||
| LangString inst_requires_win10 ${LANG_SIMPCHINESE}  "此安装程序仅支持 Windows 10 (1809) / Windows Server 2019 或更新的系统。" | ||||
| ;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent" | ||||
| LangString inst_uninstall_link_description ${LANG_SIMPCHINESE} "卸载 qBittorrent" | ||||
|  | ||||
|   | ||||
							
								
								
									
										12
									
								
								dist/windows/installer-translations/swedish.nsh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								dist/windows/installer-translations/swedish.nsh
									
									
									
									
										vendored
									
									
								
							| @@ -7,21 +7,21 @@ LangString inst_desktop ${LANG_SWEDISH} "Skapa skrivbordsgenväg" | ||||
| ;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut" | ||||
| LangString inst_startmenu ${LANG_SWEDISH} "Skapa startmenygenväg" | ||||
| ;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up" | ||||
| LangString inst_startup ${LANG_SWEDISH} "Starta qBittorrent vid Windows start" | ||||
| LangString inst_startup ${LANG_SWEDISH} "Starta qBittorrent vid Windows-uppstart" | ||||
| ;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent" | ||||
| LangString inst_torrent ${LANG_SWEDISH} "Öppna .torrent-filer med qBittorrent" | ||||
| ;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent" | ||||
| LangString inst_magnet ${LANG_SWEDISH} "Öppna magnetlänkar med qBittorrent" | ||||
| ;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule" | ||||
| LangString inst_firewall ${LANG_SWEDISH} "Lägg till Windows-brandväggregel" | ||||
| LangString inst_firewall ${LANG_SWEDISH} "Lägg till Windows-brandväggsregel" | ||||
| ;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_SWEDISH} "Inaktivera gränsen för Windows-sökvägslängd (260 tecken MAX_PATH-begränsning, kräver Windows 10 1607 eller senare)" | ||||
| ;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule" | ||||
| LangString inst_firewallinfo ${LANG_SWEDISH} "Lägger till Windows-brandväggregel" | ||||
| LangString inst_firewallinfo ${LANG_SWEDISH} "Lägger till Windows-brandväggsregel" | ||||
| ;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing." | ||||
| LangString inst_warning ${LANG_SWEDISH} "qBittorrent körs. Vänligen stäng programmet innan du installerar." | ||||
| LangString inst_warning ${LANG_SWEDISH} "qBittorrent körs. Stäng programmet innan du installerar." | ||||
| ;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact." | ||||
| LangString inst_uninstall_question ${LANG_SWEDISH} "Nuvarande version avinstalleras. Användarinställningar och torrenter kommer att förbli intakta." | ||||
| LangString inst_uninstall_question ${LANG_SWEDISH} "Aktuell version avinstalleras. Användarinställningar och torrenter kommer att förbli intakta." | ||||
| ;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version." | ||||
| LangString inst_unist ${LANG_SWEDISH} "Avinstallerar tidigare version." | ||||
| ;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent." | ||||
| @@ -53,7 +53,7 @@ LangString remove_firewallinfo ${LANG_SWEDISH} "Tar bort Windows-brandväggsrege | ||||
| ;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data" | ||||
| LangString remove_cache ${LANG_SWEDISH} "Ta bort torrenter och cachade data" | ||||
| ;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling." | ||||
| LangString uninst_warning ${LANG_SWEDISH} "qBittorrent körs. Vänligen stäng programmet innan du avinstallerar." | ||||
| LangString uninst_warning ${LANG_SWEDISH} "qBittorrent körs. Stäng programmet innan du avinstallerar." | ||||
| ;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:" | ||||
| LangString uninst_tor_warn ${LANG_SWEDISH} "Tar inte bort .torrent-association. Den är associerad med:" | ||||
| ;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:" | ||||
|   | ||||
| @@ -29,7 +29,7 @@ LangString launch_qbt ${LANG_TRADCHINESE} "啟動 qBittorrent" | ||||
| ;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions." | ||||
| LangString inst_requires_64bit ${LANG_TRADCHINESE} "此安裝程式僅支援 64 位元版本的 Windows。" | ||||
| ;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 (1809) / Windows Server 2019." | ||||
| LangString inst_requires_win10 ${LANG_TRADCHINESE}  "This installer requires at least Windows 10 (1809) / Windows Server 2019." | ||||
| LangString inst_requires_win10 ${LANG_TRADCHINESE}  "此安裝程式僅支援 Windows 10 (1809) / Windows Server 2019 以上的系統。" | ||||
| ;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent" | ||||
| LangString inst_uninstall_link_description ${LANG_TRADCHINESE} "移除 qBittorrent" | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
|  * Bittorrent Client using Qt and libtorrent. | ||||
|  * Copyright (C) 2015-2024  Vladimir Golovnev <glassez@yandex.ru> | ||||
|  * Copyright (C) 2015-2025  Vladimir Golovnev <glassez@yandex.ru> | ||||
|  * Copyright (C) 2006  Christophe Dumez | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
| @@ -124,6 +124,28 @@ namespace | ||||
|     const int PIXMAP_CACHE_SIZE = 64 * 1024 * 1024;  // 64MiB | ||||
| #endif | ||||
|  | ||||
|     const QString PARAM_ADDSTOPPED = u"@addStopped"_s; | ||||
|     const QString PARAM_CATEGORY = u"@category"_s; | ||||
|     const QString PARAM_FIRSTLASTPIECEPRIORITY = u"@firstLastPiecePriority"_s; | ||||
|     const QString PARAM_SAVEPATH = u"@savePath"_s; | ||||
|     const QString PARAM_SEQUENTIAL = u"@sequential"_s; | ||||
|     const QString PARAM_SKIPCHECKING = u"@skipChecking"_s; | ||||
|     const QString PARAM_SKIPDIALOG = u"@skipDialog"_s; | ||||
|  | ||||
|     QString bindParamValue(const QStringView paramName, const QStringView paramValue) | ||||
|     { | ||||
|         return paramName + u'=' + paramValue; | ||||
|     } | ||||
|  | ||||
|     std::pair<QStringView, QStringView> parseParam(const QStringView param) | ||||
|     { | ||||
|         const qsizetype sepIndex = param.indexOf(u'='); | ||||
|         if (sepIndex >= 0) | ||||
|             return {param.first(sepIndex), param.sliced(sepIndex + 1)}; | ||||
|  | ||||
|         return {param, {}}; | ||||
|     } | ||||
|  | ||||
|     QString serializeParams(const QBtCommandLineParameters ¶ms) | ||||
|     { | ||||
|         QStringList result; | ||||
| @@ -138,85 +160,86 @@ namespace | ||||
|         const BitTorrent::AddTorrentParams &addTorrentParams = params.addTorrentParams; | ||||
|  | ||||
|         if (!addTorrentParams.savePath.isEmpty()) | ||||
|             result.append(u"@savePath=" + addTorrentParams.savePath.data()); | ||||
|             result.append(bindParamValue(PARAM_SAVEPATH, addTorrentParams.savePath.data())); | ||||
|  | ||||
|         if (addTorrentParams.addStopped.has_value()) | ||||
|             result.append(*addTorrentParams.addStopped ? u"@addStopped=1"_s : u"@addStopped=0"_s); | ||||
|             result.append(bindParamValue(PARAM_ADDSTOPPED, (*addTorrentParams.addStopped ? u"1" : u"0"))); | ||||
|  | ||||
|         if (addTorrentParams.skipChecking) | ||||
|             result.append(u"@skipChecking"_s); | ||||
|             result.append(PARAM_SKIPCHECKING); | ||||
|  | ||||
|         if (!addTorrentParams.category.isEmpty()) | ||||
|             result.append(u"@category=" + addTorrentParams.category); | ||||
|             result.append(bindParamValue(PARAM_CATEGORY, addTorrentParams.category)); | ||||
|  | ||||
|         if (addTorrentParams.sequential) | ||||
|             result.append(u"@sequential"_s); | ||||
|             result.append(PARAM_SEQUENTIAL); | ||||
|  | ||||
|         if (addTorrentParams.firstLastPiecePriority) | ||||
|             result.append(u"@firstLastPiecePriority"_s); | ||||
|             result.append(PARAM_FIRSTLASTPIECEPRIORITY); | ||||
|  | ||||
|         if (params.skipDialog.has_value()) | ||||
|             result.append(*params.skipDialog ? u"@skipDialog=1"_s : u"@skipDialog=0"_s); | ||||
|             result.append(bindParamValue(PARAM_SKIPDIALOG, (*params.skipDialog ? u"1" : u"0"))); | ||||
|  | ||||
|         result += params.torrentSources; | ||||
|  | ||||
|         return result.join(PARAMS_SEPARATOR); | ||||
|     } | ||||
|  | ||||
|     QBtCommandLineParameters parseParams(const QString &str) | ||||
|     QBtCommandLineParameters parseParams(const QStringView str) | ||||
|     { | ||||
|         QBtCommandLineParameters parsedParams; | ||||
|         BitTorrent::AddTorrentParams &addTorrentParams = parsedParams.addTorrentParams; | ||||
|  | ||||
|         for (QString param : asConst(str.split(PARAMS_SEPARATOR, Qt::SkipEmptyParts))) | ||||
|         for (QStringView param : asConst(str.split(PARAMS_SEPARATOR, Qt::SkipEmptyParts))) | ||||
|         { | ||||
|             param = param.trimmed(); | ||||
|             const auto [paramName, paramValue] = parseParam(param); | ||||
|  | ||||
|             // Process strings indicating options specified by the user. | ||||
|  | ||||
|             if (param.startsWith(u"@savePath=")) | ||||
|             if (paramName == PARAM_SAVEPATH) | ||||
|             { | ||||
|                 addTorrentParams.savePath = Path(param.mid(10)); | ||||
|                 addTorrentParams.savePath = Path(paramValue.toString()); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (param.startsWith(u"@addStopped=")) | ||||
|             if (paramName == PARAM_ADDSTOPPED) | ||||
|             { | ||||
|                 addTorrentParams.addStopped = (QStringView(param).mid(11).toInt() != 0); | ||||
|                 addTorrentParams.addStopped = (paramValue.toInt() != 0); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (param == u"@skipChecking") | ||||
|             if (paramName == PARAM_SKIPCHECKING) | ||||
|             { | ||||
|                 addTorrentParams.skipChecking = true; | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (param.startsWith(u"@category=")) | ||||
|             if (paramName == PARAM_CATEGORY) | ||||
|             { | ||||
|                 addTorrentParams.category = param.mid(10); | ||||
|                 addTorrentParams.category = paramValue.toString(); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (param == u"@sequential") | ||||
|             if (paramName == PARAM_SEQUENTIAL) | ||||
|             { | ||||
|                 addTorrentParams.sequential = true; | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (param == u"@firstLastPiecePriority") | ||||
|             if (paramName == PARAM_FIRSTLASTPIECEPRIORITY) | ||||
|             { | ||||
|                 addTorrentParams.firstLastPiecePriority = true; | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (param.startsWith(u"@skipDialog=")) | ||||
|             if (paramName == PARAM_SKIPDIALOG) | ||||
|             { | ||||
|                 parsedParams.skipDialog = (QStringView(param).mid(12).toInt() != 0); | ||||
|                 parsedParams.skipDialog = (paramValue.toInt() != 0); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             parsedParams.torrentSources.append(param); | ||||
|             parsedParams.torrentSources.append(param.toString()); | ||||
|         } | ||||
|  | ||||
|         return parsedParams; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
|  * Bittorrent Client using Qt and libtorrent. | ||||
|  * Copyright (C) 2014-2023  Vladimir Golovnev <glassez@yandex.ru> | ||||
|  * Copyright (C) 2014-2024  Vladimir Golovnev <glassez@yandex.ru> | ||||
|  * Copyright (C) 2006  Christophe Dumez <chris@qbittorrent.org> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
| @@ -58,10 +58,6 @@ | ||||
| #include <QSplashScreen> | ||||
| #include <QTimer> | ||||
|  | ||||
| #ifdef Q_OS_WIN | ||||
| #include <QOperatingSystemVersion> | ||||
| #endif | ||||
|  | ||||
| #ifdef QBT_STATIC_QT | ||||
| #include <QtPlugin> | ||||
| Q_IMPORT_PLUGIN(QICOPlugin) | ||||
| @@ -189,11 +185,6 @@ int main(int argc, char *argv[]) | ||||
|     // We must save it here because QApplication constructor may change it | ||||
|     const bool isOneArg = (argc == 2); | ||||
|  | ||||
| #if !defined(DISABLE_GUI) && defined(Q_OS_WIN) | ||||
|     if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10) | ||||
|         QApplication::setStyle(u"Fusion"_s); | ||||
| #endif | ||||
|  | ||||
|     // `app` must be declared out of try block to allow display message box in case of exception | ||||
|     std::unique_ptr<Application> app; | ||||
|     try | ||||
|   | ||||
| @@ -38,6 +38,8 @@ add_library(qbt_base STATIC | ||||
|     bittorrent/torrent.h | ||||
|     bittorrent/torrentcontenthandler.h | ||||
|     bittorrent/torrentcontentlayout.h | ||||
|     bittorrent/torrentcontentremoveoption.h | ||||
|     bittorrent/torrentcontentremover.h | ||||
|     bittorrent/torrentcreationmanager.h | ||||
|     bittorrent/torrentcreationtask.h | ||||
|     bittorrent/torrentcreator.h | ||||
| @@ -145,6 +147,7 @@ add_library(qbt_base STATIC | ||||
|     bittorrent/sslparameters.cpp | ||||
|     bittorrent/torrent.cpp | ||||
|     bittorrent/torrentcontenthandler.cpp | ||||
|     bittorrent/torrentcontentremover.cpp | ||||
|     bittorrent/torrentcreationmanager.cpp | ||||
|     bittorrent/torrentcreationtask.cpp | ||||
|     bittorrent/torrentcreator.cpp | ||||
|   | ||||
| @@ -157,10 +157,36 @@ void AddTorrentManager::handleAddTorrentFailed(const QString &source, const QStr | ||||
|     emit addTorrentFailed(source, reason); | ||||
| } | ||||
|  | ||||
| void AddTorrentManager::handleDuplicateTorrent(const QString &source, BitTorrent::Torrent *torrent, const QString &message) | ||||
| void AddTorrentManager::handleDuplicateTorrent(const QString &source | ||||
|         , const BitTorrent::TorrentDescriptor &torrentDescr, BitTorrent::Torrent *existingTorrent) | ||||
| { | ||||
|     const bool hasMetadata = torrentDescr.info().has_value(); | ||||
|     if (hasMetadata) | ||||
|     { | ||||
|         // Trying to set metadata to existing torrent in case if it has none | ||||
|         existingTorrent->setMetadata(*torrentDescr.info()); | ||||
|     } | ||||
|  | ||||
|     const bool isPrivate = existingTorrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate()); | ||||
|     QString message; | ||||
|     if (!btSession()->isMergeTrackersEnabled()) | ||||
|     { | ||||
|         message = tr("Merging of trackers is disabled"); | ||||
|     } | ||||
|     else if (isPrivate) | ||||
|     { | ||||
|         message = tr("Trackers cannot be merged because it is a private torrent"); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // merge trackers and web seeds | ||||
|         existingTorrent->addTrackers(torrentDescr.trackers()); | ||||
|         existingTorrent->addUrlSeeds(torrentDescr.urlSeeds()); | ||||
|         message = tr("Trackers are merged from new source"); | ||||
|     } | ||||
|  | ||||
|     LogMsg(tr("Detected an attempt to add a duplicate torrent. Source: %1. Existing torrent: %2. Result: %3") | ||||
|             .arg(source, torrent->name(), message)); | ||||
|             .arg(source, existingTorrent->name(), message)); | ||||
|     emit addTorrentFailed(source, message); | ||||
| } | ||||
|  | ||||
| @@ -169,11 +195,9 @@ void AddTorrentManager::setTorrentFileGuard(const QString &source, std::shared_p | ||||
|     m_guardedTorrentFiles.emplace(source, std::move(torrentFileGuard)); | ||||
| } | ||||
|  | ||||
| void AddTorrentManager::releaseTorrentFileGuard(const QString &source) | ||||
| std::shared_ptr<TorrentFileGuard> AddTorrentManager::releaseTorrentFileGuard(const QString &source) | ||||
| { | ||||
|     auto torrentFileGuard = m_guardedTorrentFiles.take(source); | ||||
|     if (torrentFileGuard) | ||||
|         torrentFileGuard->setAutoRemove(false); | ||||
|     return m_guardedTorrentFiles.take(source); | ||||
| } | ||||
|  | ||||
| bool AddTorrentManager::processTorrent(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr | ||||
| @@ -184,32 +208,7 @@ bool AddTorrentManager::processTorrent(const QString &source, const BitTorrent:: | ||||
|     if (BitTorrent::Torrent *torrent = btSession()->findTorrent(infoHash)) | ||||
|     { | ||||
|         // a duplicate torrent is being added | ||||
|  | ||||
|         const bool hasMetadata = torrentDescr.info().has_value(); | ||||
|         if (hasMetadata) | ||||
|         { | ||||
|             // Trying to set metadata to existing torrent in case if it has none | ||||
|             torrent->setMetadata(*torrentDescr.info()); | ||||
|         } | ||||
|  | ||||
|         if (!btSession()->isMergeTrackersEnabled()) | ||||
|         { | ||||
|             handleDuplicateTorrent(source, torrent, tr("Merging of trackers is disabled")); | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         const bool isPrivate = torrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate()); | ||||
|         if (isPrivate) | ||||
|         { | ||||
|             handleDuplicateTorrent(source, torrent, tr("Trackers cannot be merged because it is a private torrent")); | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // merge trackers and web seeds | ||||
|         torrent->addTrackers(torrentDescr.trackers()); | ||||
|         torrent->addUrlSeeds(torrentDescr.urlSeeds()); | ||||
|  | ||||
|         handleDuplicateTorrent(source, torrent, tr("Trackers are merged from new source")); | ||||
|         handleDuplicateTorrent(source, torrentDescr, torrent); | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -72,9 +72,9 @@ protected: | ||||
|     bool addTorrentToSession(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr | ||||
|             , const BitTorrent::AddTorrentParams &addTorrentParams); | ||||
|     void handleAddTorrentFailed(const QString &source, const QString &reason); | ||||
|     void handleDuplicateTorrent(const QString &source, BitTorrent::Torrent *torrent, const QString &message); | ||||
|     void handleDuplicateTorrent(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr, BitTorrent::Torrent *existingTorrent); | ||||
|     void setTorrentFileGuard(const QString &source, std::shared_ptr<TorrentFileGuard> torrentFileGuard); | ||||
|     void releaseTorrentFileGuard(const QString &source); | ||||
|     std::shared_ptr<TorrentFileGuard> releaseTorrentFileGuard(const QString &source); | ||||
|  | ||||
| private: | ||||
|     void onDownloadFinished(const Net::DownloadResult &result); | ||||
|   | ||||
| @@ -40,7 +40,6 @@ | ||||
| #include <QRegularExpression> | ||||
| #include <QThread> | ||||
|  | ||||
| #include "base/algorithm.h" | ||||
| #include "base/exceptions.h" | ||||
| #include "base/global.h" | ||||
| #include "base/logger.h" | ||||
|   | ||||
| @@ -240,11 +240,11 @@ void CustomDiskIOThread::handleCompleteFiles(lt::storage_index_t storage, const | ||||
|  | ||||
| lt::storage_interface *customStorageConstructor(const lt::storage_params ¶ms, lt::file_pool &pool) | ||||
| { | ||||
|     return new CustomStorage {params, pool}; | ||||
|     return new CustomStorage(params, pool); | ||||
| } | ||||
|  | ||||
| CustomStorage::CustomStorage(const lt::storage_params ¶ms, lt::file_pool &filePool) | ||||
|     : lt::default_storage {params, filePool} | ||||
|     : lt::default_storage(params, filePool) | ||||
|     , m_savePath {params.path} | ||||
| { | ||||
| } | ||||
|   | ||||
| @@ -67,7 +67,7 @@ namespace | ||||
| { | ||||
|     const QString DB_CONNECTION_NAME = u"ResumeDataStorage"_s; | ||||
|  | ||||
|     const int DB_VERSION = 7; | ||||
|     const int DB_VERSION = 8; | ||||
|  | ||||
|     const QString DB_TABLE_META = u"meta"_s; | ||||
|     const QString DB_TABLE_TORRENTS = u"torrents"_s; | ||||
| @@ -628,7 +628,31 @@ void BitTorrent::DBResumeDataStorage::updateDB(const int fromVersion) const | ||||
|         } | ||||
|  | ||||
|         if (fromVersion <= 6) | ||||
|             addColumn(DB_TABLE_TORRENTS, DB_COLUMN_SHARE_LIMIT_ACTION, "TEXTNOT NULL DEFAULT `Default`"); | ||||
|             addColumn(DB_TABLE_TORRENTS, DB_COLUMN_SHARE_LIMIT_ACTION, "TEXT NOT NULL DEFAULT `Default`"); | ||||
|  | ||||
|         if (fromVersion == 7) | ||||
|         { | ||||
|             const QString TEMP_COLUMN_NAME = DB_COLUMN_SHARE_LIMIT_ACTION.name + u"_temp"; | ||||
|  | ||||
|             auto queryStr = u"ALTER TABLE %1 ADD %2 %3"_s | ||||
|                     .arg(quoted(DB_TABLE_TORRENTS), TEMP_COLUMN_NAME, u"TEXT NOT NULL DEFAULT `Default`"); | ||||
|             if (!query.exec(queryStr)) | ||||
|                 throw RuntimeError(query.lastError().text()); | ||||
|  | ||||
|             queryStr = u"UPDATE %1 SET %2 = %3"_s | ||||
|                     .arg(quoted(DB_TABLE_TORRENTS), quoted(TEMP_COLUMN_NAME), quoted(DB_COLUMN_SHARE_LIMIT_ACTION.name)); | ||||
|             if (!query.exec(queryStr)) | ||||
|                 throw RuntimeError(query.lastError().text()); | ||||
|  | ||||
|             queryStr = u"ALTER TABLE %1 DROP %2"_s.arg(quoted(DB_TABLE_TORRENTS), quoted(DB_COLUMN_SHARE_LIMIT_ACTION.name)); | ||||
|             if (!query.exec(queryStr)) | ||||
|                 throw RuntimeError(query.lastError().text()); | ||||
|  | ||||
|             queryStr = u"ALTER TABLE %1 RENAME %2 TO %3"_s | ||||
|                     .arg(quoted(DB_TABLE_TORRENTS), quoted(TEMP_COLUMN_NAME), quoted(DB_COLUMN_SHARE_LIMIT_ACTION.name)); | ||||
|             if (!query.exec(queryStr)) | ||||
|                 throw RuntimeError(query.lastError().text()); | ||||
|         } | ||||
|  | ||||
|         const QString updateMetaVersionQuery = makeUpdateStatement(DB_TABLE_META, {DB_COLUMN_NAME, DB_COLUMN_VALUE}); | ||||
|         if (!query.prepare(updateMetaVersionQuery)) | ||||
|   | ||||
| @@ -367,6 +367,10 @@ void PeerInfo::determineFlags() | ||||
|     if (useUTPSocket()) | ||||
|         updateFlags(u'P', C_UTP); | ||||
|  | ||||
|     // h = Peer is using NAT hole punching | ||||
|     if (isHolepunched()) | ||||
|         updateFlags(u'h', tr("Peer is using NAT hole punching")); | ||||
|  | ||||
|     m_flags.chop(1); | ||||
|     m_flagsDescription.chop(1); | ||||
| } | ||||
|   | ||||
| @@ -37,17 +37,12 @@ | ||||
| #include "addtorrentparams.h" | ||||
| #include "categoryoptions.h" | ||||
| #include "sharelimitaction.h" | ||||
| #include "torrentcontentremoveoption.h" | ||||
| #include "trackerentry.h" | ||||
| #include "trackerentrystatus.h" | ||||
|  | ||||
| class QString; | ||||
|  | ||||
| enum DeleteOption | ||||
| { | ||||
|     DeleteTorrent, | ||||
|     DeleteTorrentAndFiles | ||||
| }; | ||||
|  | ||||
| namespace BitTorrent | ||||
| { | ||||
|     class InfoHash; | ||||
| @@ -58,6 +53,12 @@ namespace BitTorrent | ||||
|     struct CacheStatus; | ||||
|     struct SessionStatus; | ||||
|  | ||||
|     enum class TorrentRemoveOption | ||||
|     { | ||||
|         KeepContent, | ||||
|         RemoveContent | ||||
|     }; | ||||
|  | ||||
|     // 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 | ||||
| @@ -91,7 +92,8 @@ namespace BitTorrent | ||||
|         { | ||||
|             Default = 0, | ||||
|             MMap = 1, | ||||
|             Posix = 2 | ||||
|             Posix = 2, | ||||
|             SimplePreadPwrite = 3 | ||||
|         }; | ||||
|         Q_ENUM_NS(DiskIOType) | ||||
|  | ||||
| @@ -425,7 +427,7 @@ namespace BitTorrent | ||||
|         virtual void setExcludedFileNamesEnabled(bool enabled) = 0; | ||||
|         virtual QStringList excludedFileNames() const = 0; | ||||
|         virtual void setExcludedFileNames(const QStringList &newList) = 0; | ||||
|         virtual bool isFilenameExcluded(const QString &fileName) const = 0; | ||||
|         virtual void applyFilenameFilter(const PathList &files, QList<BitTorrent::DownloadPriority> &priorities) = 0; | ||||
|         virtual QStringList bannedIPs() const = 0; | ||||
|         virtual void setBannedIPs(const QStringList &newList) = 0; | ||||
|         virtual ResumeDataStorageType resumeDataStorageType() const = 0; | ||||
| @@ -434,6 +436,8 @@ namespace BitTorrent | ||||
|         virtual void setMergeTrackersEnabled(bool enabled) = 0; | ||||
|         virtual bool isStartPaused() const = 0; | ||||
|         virtual void setStartPaused(bool value) = 0; | ||||
|         virtual TorrentContentRemoveOption torrentContentRemoveOption() const = 0; | ||||
|         virtual void setTorrentContentRemoveOption(TorrentContentRemoveOption option) = 0; | ||||
|  | ||||
|         virtual bool isRestored() const = 0; | ||||
|  | ||||
| @@ -453,7 +457,7 @@ namespace BitTorrent | ||||
|  | ||||
|         virtual bool isKnownTorrent(const InfoHash &infoHash) const = 0; | ||||
|         virtual bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) = 0; | ||||
|         virtual bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteOption::DeleteTorrent) = 0; | ||||
|         virtual bool removeTorrent(const TorrentID &id, TorrentRemoveOption deleteOption = TorrentRemoveOption::KeepContent) = 0; | ||||
|         virtual bool downloadMetadata(const TorrentDescriptor &torrentDescr) = 0; | ||||
|         virtual bool cancelDownloadMetadata(const TorrentID &id) = 0; | ||||
|  | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -41,6 +41,7 @@ | ||||
| #include <QElapsedTimer> | ||||
| #include <QHash> | ||||
| #include <QMap> | ||||
| #include <QMutex> | ||||
| #include <QPointer> | ||||
| #include <QSet> | ||||
| #include <QVector> | ||||
| @@ -75,6 +76,7 @@ namespace BitTorrent | ||||
|     class InfoHash; | ||||
|     class ResumeDataStorage; | ||||
|     class Torrent; | ||||
|     class TorrentContentRemover; | ||||
|     class TorrentDescriptor; | ||||
|     class TorrentImpl; | ||||
|     class Tracker; | ||||
| @@ -402,7 +404,7 @@ namespace BitTorrent | ||||
|         void setExcludedFileNamesEnabled(bool enabled) override; | ||||
|         QStringList excludedFileNames() const override; | ||||
|         void setExcludedFileNames(const QStringList &excludedFileNames) override; | ||||
|         bool isFilenameExcluded(const QString &fileName) const override; | ||||
|         void applyFilenameFilter(const PathList &files, QList<BitTorrent::DownloadPriority> &priorities) override; | ||||
|         QStringList bannedIPs() const override; | ||||
|         void setBannedIPs(const QStringList &newList) override; | ||||
|         ResumeDataStorageType resumeDataStorageType() const override; | ||||
| @@ -411,6 +413,8 @@ namespace BitTorrent | ||||
|         void setMergeTrackersEnabled(bool enabled) override; | ||||
|         bool isStartPaused() const override; | ||||
|         void setStartPaused(bool value) override; | ||||
|         TorrentContentRemoveOption torrentContentRemoveOption() const override; | ||||
|         void setTorrentContentRemoveOption(TorrentContentRemoveOption option) override; | ||||
|  | ||||
|         bool isRestored() const override; | ||||
|  | ||||
| @@ -430,7 +434,7 @@ namespace BitTorrent | ||||
|  | ||||
|         bool isKnownTorrent(const InfoHash &infoHash) const override; | ||||
|         bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) override; | ||||
|         bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteTorrent) override; | ||||
|         bool removeTorrent(const TorrentID &id, TorrentRemoveOption deleteOption = TorrentRemoveOption::KeepContent) override; | ||||
|         bool downloadMetadata(const TorrentDescriptor &torrentDescr) override; | ||||
|         bool cancelDownloadMetadata(const TorrentID &id) override; | ||||
|  | ||||
| @@ -472,6 +476,8 @@ namespace BitTorrent | ||||
|         void addMappedPorts(const QSet<quint16> &ports); | ||||
|         void removeMappedPorts(const QSet<quint16> &ports); | ||||
|  | ||||
|         QDateTime fromLTTimePoint32(const lt::time_point32 &timePoint) const; | ||||
|  | ||||
|         template <typename Func> | ||||
|         void invoke(Func &&func) | ||||
|         { | ||||
| @@ -487,11 +493,11 @@ namespace BitTorrent | ||||
|         void configureDeferred(); | ||||
|         void readAlerts(); | ||||
|         void enqueueRefresh(); | ||||
|         void processShareLimits(); | ||||
|         void generateResumeData(); | ||||
|         void handleIPFilterParsed(int ruleCount); | ||||
|         void handleIPFilterError(); | ||||
|         void fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames); | ||||
|         void torrentContentRemovingFinished(const QString &torrentName, const QString &errorMessage); | ||||
|  | ||||
|     private: | ||||
|         struct ResumeSessionContext; | ||||
| @@ -507,8 +513,9 @@ namespace BitTorrent | ||||
|         struct RemovingTorrentData | ||||
|         { | ||||
|             QString name; | ||||
|             Path pathToRemove; | ||||
|             DeleteOption deleteOption {}; | ||||
|             Path contentStoragePath; | ||||
|             PathList fileNames; | ||||
|             TorrentRemoveOption removeOption {}; | ||||
|         }; | ||||
|  | ||||
|         explicit SessionImpl(QObject *parent = nullptr); | ||||
| @@ -535,7 +542,7 @@ namespace BitTorrent | ||||
|         void populateAdditionalTrackers(); | ||||
|         void enableIPFilter(); | ||||
|         void disableIPFilter(); | ||||
|         void processTrackerStatuses(); | ||||
|         void processTorrentShareLimits(TorrentImpl *torrent); | ||||
|         void populateExcludedFileNamesRegExpList(); | ||||
|         void prepareStartup(); | ||||
|         void handleLoadedResumeData(ResumeSessionContext *context); | ||||
| @@ -588,6 +595,7 @@ namespace BitTorrent | ||||
|  | ||||
|         void moveTorrentStorage(const MoveStorageJob &job) const; | ||||
|         void handleMoveTorrentStorageJobFinished(const Path &newPath); | ||||
|         void processPendingFinishedTorrents(); | ||||
|  | ||||
|         void loadCategories(); | ||||
|         void storeCategories() const; | ||||
| @@ -597,15 +605,9 @@ namespace BitTorrent | ||||
|         void saveStatistics() const; | ||||
|         void loadStatistics(); | ||||
|  | ||||
|         void updateTrackerEntryStatuses(lt::torrent_handle torrentHandle, QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>> updatedTrackers); | ||||
|         void updateTrackerEntryStatuses(lt::torrent_handle torrentHandle); | ||||
|  | ||||
|         // BitTorrent | ||||
|         lt::session *m_nativeSession = nullptr; | ||||
|         NativeSessionExtension *m_nativeSessionExtension = nullptr; | ||||
|  | ||||
|         bool m_deferredConfigureScheduled = false; | ||||
|         bool m_IPFilteringConfigured = false; | ||||
|         mutable bool m_listenInterfaceConfigured = false; | ||||
|         void handleRemovedTorrent(const TorrentID &torrentID, const QString &partfileRemoveError = {}); | ||||
|  | ||||
|         CachedSettingValue<QString> m_DHTBootstrapNodes; | ||||
|         CachedSettingValue<bool> m_isDHTEnabled; | ||||
| @@ -731,8 +733,16 @@ namespace BitTorrent | ||||
|         CachedSettingValue<int> m_I2POutboundQuantity; | ||||
|         CachedSettingValue<int> m_I2PInboundLength; | ||||
|         CachedSettingValue<int> m_I2POutboundLength; | ||||
|         CachedSettingValue<TorrentContentRemoveOption> m_torrentContentRemoveOption; | ||||
|         SettingValue<bool> m_startPaused; | ||||
|  | ||||
|         lt::session *m_nativeSession = nullptr; | ||||
|         NativeSessionExtension *m_nativeSessionExtension = nullptr; | ||||
|  | ||||
|         bool m_deferredConfigureScheduled = false; | ||||
|         bool m_IPFilteringConfigured = false; | ||||
|         mutable bool m_listenInterfaceConfigured = false; | ||||
|  | ||||
|         bool m_isRestored = false; | ||||
|         bool m_isPaused = isStartPaused(); | ||||
|  | ||||
| @@ -766,6 +776,7 @@ namespace BitTorrent | ||||
|         QThreadPool *m_asyncWorker = nullptr; | ||||
|         ResumeDataStorage *m_resumeDataStorage = nullptr; | ||||
|         FileSearcher *m_fileSearcher = nullptr; | ||||
|         TorrentContentRemover *m_torrentContentRemover = nullptr; | ||||
|  | ||||
|         QHash<TorrentID, lt::torrent_handle> m_downloadedMetadata; | ||||
|  | ||||
| @@ -783,6 +794,7 @@ namespace BitTorrent | ||||
|         // This field holds amounts of peers reported by trackers in their responses to announces | ||||
|         // (torrent.tracker_name.tracker_local_endpoint.protocol_version.num_peers) | ||||
|         QHash<lt::torrent_handle, QHash<std::string, QHash<lt::tcp::endpoint, QMap<int, int>>>> m_updatedTrackerStatuses; | ||||
|         QMutex m_updatedTrackerStatusesMutex; | ||||
|  | ||||
|         // I/O errored torrents | ||||
|         QSet<TorrentID> m_recentErroredTorrents; | ||||
| @@ -809,6 +821,11 @@ namespace BitTorrent | ||||
|         QTimer *m_wakeupCheckTimer = nullptr; | ||||
|         QDateTime m_wakeupCheckTimestamp; | ||||
|  | ||||
|         QList<TorrentImpl *> m_pendingFinishedTorrents; | ||||
|  | ||||
|         QDateTime m_qNow; | ||||
|         lt::clock_type::time_point m_ltNow; | ||||
|  | ||||
|         friend void Session::initInstance(); | ||||
|         friend void Session::freeInstance(); | ||||
|         friend Session *Session::instance(); | ||||
|   | ||||
| @@ -215,7 +215,15 @@ namespace BitTorrent | ||||
|         virtual int piecesCount() const = 0; | ||||
|         virtual int piecesHave() const = 0; | ||||
|         virtual qreal progress() const = 0; | ||||
|  | ||||
|         virtual QDateTime addedTime() const = 0; | ||||
|         virtual QDateTime completedTime() const = 0; | ||||
|         virtual QDateTime lastSeenComplete() const = 0; | ||||
|         virtual qlonglong activeTime() const = 0; | ||||
|         virtual qlonglong finishedTime() const = 0; | ||||
|         virtual qlonglong timeSinceUpload() const = 0; | ||||
|         virtual qlonglong timeSinceDownload() const = 0; | ||||
|         virtual qlonglong timeSinceActivity() const = 0; | ||||
|  | ||||
|         // Share limits | ||||
|         virtual qreal ratioLimit() const = 0; | ||||
| @@ -228,6 +236,7 @@ namespace BitTorrent | ||||
|         virtual void setShareLimitAction(ShareLimitAction action) = 0; | ||||
|  | ||||
|         virtual PathList filePaths() const = 0; | ||||
|         virtual PathList actualFilePaths() const = 0; | ||||
|  | ||||
|         virtual TorrentInfo info() const = 0; | ||||
|         virtual bool isFinished() const = 0; | ||||
| @@ -253,8 +262,6 @@ namespace BitTorrent | ||||
|         virtual QString error() const = 0; | ||||
|         virtual qlonglong totalDownload() const = 0; | ||||
|         virtual qlonglong totalUpload() const = 0; | ||||
|         virtual qlonglong activeTime() const = 0; | ||||
|         virtual qlonglong finishedTime() const = 0; | ||||
|         virtual qlonglong eta() const = 0; | ||||
|         virtual int seedsCount() const = 0; | ||||
|         virtual int peersCount() const = 0; | ||||
| @@ -262,11 +269,6 @@ namespace BitTorrent | ||||
|         virtual int totalSeedsCount() const = 0; | ||||
|         virtual int totalPeersCount() const = 0; | ||||
|         virtual int totalLeechersCount() const = 0; | ||||
|         virtual QDateTime lastSeenComplete() const = 0; | ||||
|         virtual QDateTime completedTime() const = 0; | ||||
|         virtual qlonglong timeSinceUpload() const = 0; | ||||
|         virtual qlonglong timeSinceDownload() const = 0; | ||||
|         virtual qlonglong timeSinceActivity() const = 0; | ||||
|         virtual int downloadLimit() const = 0; | ||||
|         virtual int uploadLimit() const = 0; | ||||
|         virtual bool superSeeding() const = 0; | ||||
|   | ||||
							
								
								
									
										50
									
								
								src/base/bittorrent/torrentcontentremoveoption.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/base/bittorrent/torrentcontentremoveoption.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| /* | ||||
|  * Bittorrent Client using Qt and libtorrent. | ||||
|  * Copyright (C) 2024  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 TorrentContentRemoveOptionNS | ||||
|     { | ||||
|         Q_NAMESPACE | ||||
|  | ||||
|         enum class TorrentContentRemoveOption | ||||
|         { | ||||
|             Delete, | ||||
|             MoveToTrash | ||||
|         }; | ||||
|  | ||||
|         Q_ENUM_NS(TorrentContentRemoveOption) | ||||
|     } | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user