Compare commits

...

2 Commits

Author SHA1 Message Date
Kostiantyn Chernenok
c878a09d27 Swap add file/link buttons on toolbar
Swap "Add torrent file" with "Add torrent link" button to be consistent with order in File menu.

Closes #22420.
PR #22557.

Signed-off-by: Kostiantyn <kos.chernenok@gmail.com>
2025-04-19 07:57:39 +08:00
Chocobo1
2aee875642 Enforce SOCKS proxy setting in search engine plugins
Previously it require each plugin to import helpers.py to setup SOCKS proxy.
Now it is enforced by default for all plugins.
Also added a function for plugins to ignore/restore the socket to
default state.

PR #22554.
2025-04-19 07:11:50 +08:00
5 changed files with 43 additions and 35 deletions

View File

@@ -149,8 +149,8 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionDownloadFromURL"/>
<addaction name="actionOpen"/>
<addaction name="actionDownloadFromURL"/>
<addaction name="actionDelete"/>
<addaction name="separator"/>
<addaction name="actionStart"/>

View File

@@ -1,4 +1,4 @@
#VERSION: 1.52
# VERSION: 1.53
# Author:
# Christophe DUMEZ (chris@qbittorrent.org)
@@ -61,32 +61,32 @@ def _getBrowserUserAgent() -> str:
_headers: dict[str, Any] = {'User-Agent': _getBrowserUserAgent()}
_original_socket = socket.socket
def injectSOCKSProxySocket() -> None:
socksURL = os.environ.get("qbt_socks_proxy")
if socksURL is not None:
parts = urllib.parse.urlsplit(socksURL)
resolveHostname = (parts.scheme == "socks4a") or (parts.scheme == "socks5h")
if (parts.scheme == "socks4") or (parts.scheme == "socks4a"):
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, parts.hostname, parts.port, resolveHostname)
socket.socket = socks.socksocket # type: ignore[misc]
elif (parts.scheme == "socks5") or (parts.scheme == "socks5h"):
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, parts.hostname, parts.port, resolveHostname, parts.username, parts.password)
socket.socket = socks.socksocket # type: ignore[misc]
def enable_socks_proxy(enable: bool) -> None:
if enable:
socksURL = os.environ.get("qbt_socks_proxy")
if socksURL is not None:
parts = urllib.parse.urlsplit(socksURL)
resolveHostname = (parts.scheme == "socks4a") or (parts.scheme == "socks5h")
if (parts.scheme == "socks4") or (parts.scheme == "socks4a"):
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, parts.hostname, parts.port, resolveHostname)
socket.socket = socks.socksocket # type: ignore[misc]
elif (parts.scheme == "socks5") or (parts.scheme == "socks5h"):
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, parts.hostname, parts.port, resolveHostname, parts.username, parts.password)
socket.socket = socks.socksocket # type: ignore[misc]
else:
# the following code provide backward compatibility for older qbt versions
# TODO: scheduled be removed with qbt >= 5.3
legacySocksURL = os.environ.get("sock_proxy")
if legacySocksURL is not None:
legacySocksURL = f"socks5h://{legacySocksURL.strip()}"
parts = urllib.parse.urlsplit(legacySocksURL)
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, parts.hostname, parts.port, True, parts.username, parts.password)
socket.socket = socks.socksocket # type: ignore[misc]
else:
# the following code provide backward compatibility for older qbt versions
# TODO: scheduled be removed with qbt >= 5.3
legacySocksURL = os.environ.get("sock_proxy")
if legacySocksURL is not None:
legacySocksURL = f"socks5h://{legacySocksURL.strip()}"
parts = urllib.parse.urlsplit(legacySocksURL)
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, parts.hostname, parts.port, True, parts.username, parts.password)
socket.socket = socks.socksocket # type: ignore[misc]
# monkey patching, run it now
injectSOCKSProxySocket()
socket.socket = _original_socket # type: ignore[misc]
# This is only provided for backward compatibility, new code should not use it

View File

@@ -1,4 +1,4 @@
#VERSION: 1.48
# VERSION: 1.49
# Author:
# Fabien Devaux <fab AT gnux DOT info>
@@ -46,6 +46,16 @@ from multiprocessing import Pool, cpu_count
from os import path
from typing import Optional
# qbt tend to run this script in 'isolate mode' so append the current path manually
current_path = str(pathlib.Path(__file__).parent.resolve())
if current_path not in sys.path:
sys.path.append(current_path)
import helpers
# enable SOCKS proxy for all plugins by default
helpers.enable_socks_proxy(True)
THREADED: bool = True
try:
MAX_THREADS: int = cpu_count()
@@ -182,11 +192,6 @@ def run_search(search_params: tuple[type[Engine], str, Category]) -> bool:
if __name__ == "__main__":
def main() -> int:
# qbt tend to run this script in 'isolate mode' so append the current path manually
current_path = str(pathlib.Path(__file__).parent.resolve())
if current_path not in sys.path:
sys.path.append(current_path)
# https://docs.python.org/3/library/sys.html#sys.exit
class ExitCode(Enum):
OK = 0

View File

@@ -1,4 +1,4 @@
#VERSION: 1.24
# VERSION: 1.25
# Author:
# Christophe DUMEZ (chris@qbittorrent.org)
@@ -38,7 +38,10 @@ current_path = str(pathlib.Path(__file__).parent.resolve())
if current_path not in sys.path:
sys.path.append(current_path)
from helpers import download_file
import helpers
# enable SOCKS proxy for all plugins by default
helpers.enable_socks_proxy(True)
if __name__ == '__main__':
if len(sys.argv) < 3:
@@ -58,6 +61,6 @@ if __name__ == '__main__':
if hasattr(engine, 'download_torrent'):
engine.download_torrent(download_param)
else:
print(download_file(download_param))
print(helpers.download_file(download_param))
sys.exit(0)

View File

@@ -111,8 +111,8 @@
</div>
<div id="mochaToolbar">
&nbsp;&nbsp;
<a id="downloadButton"><img class="mochaToolButton" title="QBT_TR(Add Torrent Link...)QBT_TR[CONTEXT=MainWindow]" src="images/insert-link.svg" alt="QBT_TR(Add Torrent Link...)QBT_TR[CONTEXT=MainWindow]" width="24" height="24"></a>
<a id="uploadButton"><img class="mochaToolButton" title="QBT_TR(Add Torrent File...)QBT_TR[CONTEXT=MainWindow]" src="images/list-add.svg" alt="QBT_TR(Add Torrent File...)QBT_TR[CONTEXT=MainWindow]" width="24" height="24"></a>
<a id="downloadButton"><img class="mochaToolButton" title="QBT_TR(Add Torrent Link...)QBT_TR[CONTEXT=MainWindow]" src="images/insert-link.svg" alt="QBT_TR(Add Torrent Link...)QBT_TR[CONTEXT=MainWindow]" width="24" height="24"></a>
<a id="deleteButton"><img class="mochaToolButton" title="QBT_TR(Remove)QBT_TR[CONTEXT=TransferListWidget]" src="images/list-remove.svg" alt="QBT_TR(Remove)QBT_TR[CONTEXT=TransferListWidget]" width="24" height="24"></a>
<a id="startButton" class="divider"><img class="mochaToolButton" title="QBT_TR(Start)QBT_TR[CONTEXT=TransferListWidget]" src="images/torrent-start.svg" alt="QBT_TR(Start)QBT_TR[CONTEXT=TransferListWidget]" width="24" height="24"></a>
<a id="stopButton"><img class="mochaToolButton" title="QBT_TR(Stop)QBT_TR[CONTEXT=TransferListWidget]" src="images/torrent-stop.svg" alt="QBT_TR(Stop)QBT_TR[CONTEXT=TransferListWidget]" width="24" height="24"></a>