mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-07-15 12:27:24 +00:00
Compare commits
2 Commits
4ebe41fafd
...
af46dd5fc9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af46dd5fc9 | ||
|
|
847696b301 |
@@ -107,8 +107,8 @@ provider, prefix the query (`--proxy nordvpn:us`).
|
||||
|
||||
!!! note "Auto-loading providers"
|
||||
Most providers only load when you configure them under `proxy_providers:`. Three are
|
||||
special: **ExpressVPN** and **Proton VPN** also load automatically if their cookie
|
||||
file already exists on disk (even with no YAML), and **Hola** loads automatically
|
||||
special: **ExpressVPN** and **Proton VPN** also load automatically once their cached
|
||||
session file exists on disk (even with no YAML), and **Hola** loads automatically
|
||||
whenever the `hola-proxy` binary is found on your `PATH`.
|
||||
|
||||
### Connection feedback
|
||||
@@ -347,24 +347,24 @@ Understanding what Gluetun does behind the scenes helps when something goes wron
|
||||
|
||||
## ExpressVPN
|
||||
|
||||
ExpressVPN emulates the flow used by the ExpressVPN browser extension: it authenticates
|
||||
with cookies (or a cached token), obtains proxy-capable locations from ExpressVPN's API,
|
||||
and returns an authenticated HTTPS proxy. Because it relies on browser cookies rather than
|
||||
service credentials, setup is slightly more involved than the credential-based providers.
|
||||
ExpressVPN mirrors the ExpressVPN Android TV app: it signs in through Express's OAuth 2.0
|
||||
device-login flow, obtains proxy-capable locations from Express's API, and returns an
|
||||
authenticated HTTPS proxy. The device login runs once; after that the cached refresh token
|
||||
keeps the session alive headlessly.
|
||||
|
||||
ExpressVPN **auto-loads** if its cookie file exists, so once the cookie is in place you do
|
||||
not strictly need a YAML block, but you can add one to pin regions or servers.
|
||||
Enable it and run a download interactively once:
|
||||
|
||||
**Default file locations:**
|
||||
```yaml title="unshackle.yaml"
|
||||
proxy_providers:
|
||||
expressvpn:
|
||||
enable: true
|
||||
```
|
||||
|
||||
| File | Default path |
|
||||
|---|---|
|
||||
| Browser cookies | `{cookies}/vpn/expressvpn.txt` |
|
||||
| Token cache | `{cache}/global/expressvpn_tokens.json` |
|
||||
|
||||
Where `{cookies}` and `{cache}` are your configured cookie and cache directories. The
|
||||
cookie file may be a Netscape `cookies.txt`, a JSON cookie array, or a JSON dict. Export
|
||||
your ExpressVPN session cookies from a logged-in browser into one of those forms.
|
||||
With `enable: true` and an interactive terminal, unshackle prints a code and a URL to
|
||||
enter it at. Once approved, the tokens are cached and reused automatically, so later runs
|
||||
need no terminal. ExpressVPN also **auto-loads** once its token cache exists, so you can
|
||||
drop `enable` after the first login, but you can keep a YAML block to pin regions or
|
||||
servers:
|
||||
|
||||
```yaml title="unshackle.yaml (optional)"
|
||||
proxy_providers:
|
||||
@@ -376,6 +376,14 @@ proxy_providers:
|
||||
myserver: usny-newyork-2
|
||||
```
|
||||
|
||||
**Default file location:**
|
||||
|
||||
| File | Default path |
|
||||
|---|---|
|
||||
| Token cache | `{cache}/vpn/expressvpn_tokens.json` |
|
||||
|
||||
Where `{cache}` is your configured cache directory.
|
||||
|
||||
**Query forms:**
|
||||
|
||||
| Query | Meaning |
|
||||
|
||||
@@ -668,7 +668,7 @@ the full provider guide. Recognised providers and their exit ports:
|
||||
| NordVPN | `nordvpn` | 48-char **service** credentials | `https://...:89` |
|
||||
| Surfshark | `surfsharkvpn` | 48-char **service** credentials | `https://...:443` |
|
||||
| Windscribe | `windscribevpn` | service credentials | `https://...:443` |
|
||||
| ExpressVPN | `expressvpn` | browser cookies / token cache | `https://cat:...@...:443` |
|
||||
| ExpressVPN | `expressvpn` | device login (`enable: true`) / token cache | `https://cat:...@...:443` |
|
||||
| ProtonVPN | `protonvpn` | TV login or exported cookies | `https://...:4443` (or `:443` Secure Core) |
|
||||
| Gluetun | `gluetun` | per-VPN keys/creds | `http://localhost:{port}` (local Docker) |
|
||||
| Hola | *(none, auto)* | none | `http://...:{peer}` |
|
||||
@@ -688,7 +688,7 @@ proxy_providers:
|
||||
!!! note "Provider loading differs between CLI and REST server"
|
||||
The `dl` CLI loads all providers, including `windscribevpn` and `gluetun`. The REST API /
|
||||
remote-client path uses a separate resolver that does **not** load `windscribevpn` or
|
||||
`gluetun`. ExpressVPN and ProtonVPN also auto-load when their cookie file exists, and Hola
|
||||
`gluetun`. ExpressVPN and ProtonVPN also auto-load when their cached session exists, and Hola
|
||||
auto-loads whenever the `hola-proxy` binary is present.
|
||||
|
||||
---
|
||||
|
||||
@@ -1049,7 +1049,7 @@ class dl:
|
||||
self.proxy_providers.append(Basic(**config.proxy_providers["basic"]))
|
||||
# ExpressVPN/ProtonVPN auto-load when their default cookie file exists (no yaml needed)
|
||||
expressvpn = ExpressVPN(**(config.proxy_providers.get("expressvpn") or {}))
|
||||
if config.proxy_providers.get("expressvpn") or expressvpn.cookie_path.is_file():
|
||||
if config.proxy_providers.get("expressvpn") or expressvpn.cache_path.is_file():
|
||||
self.proxy_providers.append(expressvpn)
|
||||
if config.proxy_providers.get("nordvpn"):
|
||||
self.proxy_providers.append(NordVPN(**config.proxy_providers["nordvpn"]))
|
||||
|
||||
@@ -68,7 +68,7 @@ def search(ctx: click.Context, no_proxy: bool, profile: Optional[str] = None, pr
|
||||
if config.proxy_providers.get("basic"):
|
||||
proxy_providers.append(Basic(**config.proxy_providers["basic"]))
|
||||
expressvpn = ExpressVPN(**(config.proxy_providers.get("expressvpn") or {}))
|
||||
if config.proxy_providers.get("expressvpn") or expressvpn.cookie_path.is_file():
|
||||
if config.proxy_providers.get("expressvpn") or expressvpn.cache_path.is_file():
|
||||
proxy_providers.append(expressvpn)
|
||||
if config.proxy_providers.get("nordvpn"):
|
||||
proxy_providers.append(NordVPN(**config.proxy_providers["nordvpn"]))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,7 @@ def initialize_proxy_providers() -> List[Any]:
|
||||
proxy_providers.append(Basic(**proxy_config["basic"]))
|
||||
# ExpressVPN/ProtonVPN auto-load when their default cookie file exists (no yaml needed)
|
||||
expressvpn = ExpressVPN(**(proxy_config.get("expressvpn") or {}))
|
||||
if proxy_config.get("expressvpn") or expressvpn.cookie_path.is_file():
|
||||
if proxy_config.get("expressvpn") or expressvpn.cache_path.is_file():
|
||||
proxy_providers.append(expressvpn)
|
||||
if proxy_config.get("nordvpn"):
|
||||
proxy_providers.append(NordVPN(**proxy_config["nordvpn"]))
|
||||
|
||||
@@ -543,6 +543,11 @@ class Video(Track):
|
||||
e.returncode,
|
||||
duration_ms=round((time.monotonic() - cc_start) * 1000, 1),
|
||||
)
|
||||
if e.returncode < 0:
|
||||
logging.getLogger("Video").warning(
|
||||
f"ccextractor crashed (signal {-e.returncode}) on {self.path.name}; skipping CC extraction"
|
||||
)
|
||||
return out_path.exists()
|
||||
if e.returncode != 10: # 10 = No captions found
|
||||
raise
|
||||
return out_path.exists()
|
||||
|
||||
Reference in New Issue
Block a user