diff --git a/.github/repo-settings.json b/.github/repo-settings.json index 91df619..c76e833 100644 --- a/.github/repo-settings.json +++ b/.github/repo-settings.json @@ -1,10 +1,10 @@ { - "description": "Finds public proxies that work on the sites you need. Browse a 150-source catalog, collect supported feeds, check against your services, and use ready lists, a rotating gateway and an API. macOS/Windows app, CLI, Docker, 12 languages.", + "description": "Desktop proxy workbench for macOS and Windows, plus CLI and Docker. Browse 150 cataloged sources, collect 106 supported feeds, verify proxies against your own services, then use ranked exports, pools, a rotating gateway and a local API.", "homepage_from_pages": true, "has_discussions": true, "has_issues": true, "has_wiki": false, "has_projects": false, - "topics": ["proxy", "proxy-checker", "proxy-list", "free-proxy", "free-proxy-list", "proxy-scraper", "socks5", "socks5-proxy", "http-proxy", "proxy-tester", "elite-proxy", "anonymity", "web-scraping", "dnsbl", "geoip", "python", "asyncio", "rotating-proxy", "self-hosted", "docker"], + "topics": ["proxy", "proxy-checker", "proxy-list", "free-proxy", "http-proxy", "socks4", "socks5", "rotating-proxy", "proxy-gateway", "proxy-api", "desktop-app", "macos", "windows", "anonymity", "web-scraping", "dnsbl", "geoip", "python", "self-hosted", "docker"], "pages": {"branch": "main", "path": "/docs"} } diff --git a/CHANGELOG.md b/CHANGELOG.md index 33a4b20..109a838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ The format follows Keep a Changelog and semantic versioning. +## [3.0.3] — 2026-09-27 + +### Fixed + +- Scan target URLs remain visible beside their HTTP/HTTPS selector on desktop and tablet screens. +- The Results page keeps proxy rows unobstructed; bulk scope actions sit below the table until a row is selected. +- Example proxy and denylist placeholders use reserved documentation IP ranges. +- Export publication retries brief Windows file locks while preserving the previous published files if a lock persists. + +### Documentation + +- Rebuilt screenshots, the interface tour and social preview from the current app with synthetic data; refreshed English and Russian guides and the project website to describe all eight tabs, installation choices and limits accurately. + ## [3.0.2] — 2026-09-27 ### Fixed diff --git a/README.md b/README.md index f492d4b..46b5960 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,29 @@
-Proxy Workbench: find every free proxy, keep the ones that work +Proxy Workbench — local proxy discovery and checking # Proxy Workbench -### Finds free proxies that actually work — on the sites you need +### Find proxies that work for the sites you use -Proxy Workbench collects free proxies from **150 public sources**, tests every one against the sites and services **you** care about, and keeps only the ones that work. You get ready-made lists, one **rotating proxy** for your browser, Telegram and any app, or an **API** for your scripts. +Collect addresses from public lists or your own files, check them against your services, and use the results in apps, exports, or scripts. Proxy Workbench runs locally with a browser interface, CLI, rotating proxy gateway, and API. -Runs on your own computer: macOS and Windows app, command line, Docker · HTTP, HTTPS, SOCKS4, SOCKS5 · 12 languages · no sign-up, no telemetry +**Windows · macOS · Linux**  |  **HTTP(S) · SOCKS4 · SOCKS5**  |  **12 interface languages** +[![CI](https://github.com/DavidVoitenko/proxy-workbench/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/DavidVoitenko/proxy-workbench/actions/workflows/ci.yml) +[![Latest release](https://img.shields.io/github/v/release/DavidVoitenko/proxy-workbench?label=release)](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) ![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python&logoColor=white) ![License: MIT](https://img.shields.io/badge/license-MIT-2ea44f) -![Platforms](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-5f6b73) -![Dependencies](https://img.shields.io/badge/dependencies-httpx%20%2B%20keyring-42bbaa) -![Runs locally](https://img.shields.io/badge/runs-100%25%20local-209c8b) **English** · [Русский](README.ru.md) -[Quick start](#-quick-start) · [Features](#-features) · [How it works](#-how-it-works) · [CLI](#-command-line) · [FAQ](#-faq) · [Roadmap](#-roadmap) +[Download](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) · [Website](https://davidvoitenko.github.io/proxy-workbench/) · [Quick start](#-quick-start) · [Interface](#-the-eight-tabs) · [CLI](#-command-line) · [API](#-local-api-use-the-proxies-from-your-own-code)
-Proxy Workbench demo: scan, rank, filter elite proxies +Proxy Workbench interface demo -Quick tour: set up a check → ranking → “Elite only” filter → per-attempt details → sources → switching language (synthetic data). +Interface tour with synthetic example data. Actual proxy availability depends on the sources and your checks.
@@ -32,78 +31,64 @@ Runs on your own computer: macOS and Windows app, command line, Docker · HTTP, ## What it does -Free proxy lists are everywhere, but most addresses in them are dead, slow or blocked by exactly the site you care about. Proxy Workbench does the tedious part for you: +Free proxy lists go stale quickly. Proxy Workbench turns candidates into a list measured against your own success criteria: -1. **Collect.** Downloads addresses from 150 public sources (106 enabled out of the box) or your own files and removes duplicates. -2. **Check.** Sends real requests through every proxy to your sites — several times — and checks the status code, required text on the page and speed. It also finds the country, the anonymity level (transparent / anonymous / elite) and whether the IP is blacklisted. -3. **Deliver.** The best proxies land in TXT / CSV / JSON files, browser, Clash and sing-box configs, a rotating proxy at `127.0.0.1:8899`, and an API. Pools and schedules keep the list fresh on their own. +1. **Collect:** choose from a catalog of **150 entries**; **106 supported feeds** are enabled by default for new installations. You can also import your own list. Addresses are normalized and deduplicated. +2. **Check:** make real requests through each candidate to one or more target URLs. Set accepted HTTP status codes, body text or hash, retry threshold, timeouts, and optional reputation or anonymity checks. +3. **Use:** filter and export the results, connect to the local rotating gateway at `127.0.0.1:8899`, or read the latest published list from the API. Pools and schedules can refresh it. -Everything runs on your machine. The GUI binds to `127.0.0.1` only. +The interface and its local API bind to loopback by default. The headless service can be exposed deliberately with a separate API token. ## 📸 Screenshots - - + + - - + + + + + + + + + +
Scan setup and live progress
Scan — pick services, success rules and watch live progress
Ranked results
Results — ranked by quality or speed, with cleanliness verdicts
Scan page with targets and live progress
Scan — configure targets and follow progress
Results page with proxy filters and ranking
Results — review, filter, rank, and export
Per-attempt details
Details — every attempt for every service
Light theme
Light theme — one click in the header
Details for individual proxy check attempts
Details — inspect individual attempts and errors
Results page in light theme
Light theme — switch from the header
Sources page with bundled catalog and custom lists
Sources — bundled catalog and your own lists
Gateway page showing local route controls while offline
Rotating Gateway — connection setup and route controls; offline until started
Pools and schedules page with target, reserve and schedule controls
Pools & Schedules — desired size, reserve, and refresh rules
API Keys page showing access controls without secrets
API Keys — permissions and limits; no secrets shown
-Screenshots use synthetic data from documentation IP ranges (RFC 5737). The interface speaks 12 languages (language menu in the header). +Proxy results, metrics, and locations shown here are synthetic; IPs use RFC 5737 documentation ranges. The Sources catalog is the bundled catalog. No working public proxy is implied. -## ✨ Features +## 🧭 The eight tabs -| | | +| Tab | What you do there | | --- | --- | -| **150 catalog entries / 106 collectable feeds** | The catalog includes **117 public-free entries**; the remaining entries describe other access conditions. Supported lists have source-specific text, JSON, CSV or HTML adapters. Unsupported formats, unavailable snapshots and restricted sources remain visible with their reasons. | -| **Unknown protocol? No problem** | Addresses without a protocol can be tried as HTTP, SOCKS4 and SOCKS5 at once; the checks keep whichever works. | -| **Protocols** | HTTP, HTTPS/CONNECT, explicit `https://` proxies, SOCKS4, SOCKS5 / SOCKS5h, IPv4 and IPv6. | -| **Test against your services** | Several targets per profile (up to 20 in the GUI). A proxy passes only if it works for **all** of them. | -| **Strict success rules** | Allowed status codes, required body substring, expected SHA-256, `GET`/`HEAD`, safe custom headers. Catches captcha and stub pages that still return `200`. | -| **Repeated measurements** | N attempts per target (default 3), a per-target success threshold (e.g. 2 of 3), median latency and jitter. | -| **Just a few proxies? Specific country?** | `--want 20` stops as soon as 20 proxies match; previously working addresses are tried first. `--country DE,NL` skips every other country *before* checking, so a country-specific search takes minutes, not hours. | -| **Always fresh** | **Re-check only matching proxies** refreshes the current list in minutes; **Keep fresh** in the GUI (or `--watch 30`) does it automatically every 30 minutes, and the API and rotating proxy pick up each new list. Every proxy keeps an uptime history, so you can sort by the ones that survive re-checks. | -| **Source ratings** | The Sources tab shows how many working proxies each public list produced, so you can drop dead lists and scan faster. | -| **Presets** | Quick, Balanced and Thorough set attempts, timeouts and workers in one click. | -| **Anonymity levels** | Point it at any echo “judge” page and every working proxy is rated **transparent** (leaks your IP), **anonymous** (reveals itself with `Via` / `X-Forwarded-For`) or **elite**. Filter with one click or `--min-anonymity elite`. | -| **Cleanliness checks** | Local IP / CIDR / exact-proxy denylist plus optional DNSBL zones. Verdicts: `clean`, `listed`, `local_denied`, `unknown`, with an optional strict mode. | -| **Built for big lists** | Bounded worker queue, rate limiter, automatic file-descriptor fitting. A **quick pre-check** drops addresses that do not even accept a TCP connection before the full check, **fail-fast** skips the remaining attempts once a proxy can no longer pass, and a short **connect timeout** drops dead hosts early. Tested with 190,000 simulated candidates. | -| **Stop & resume** | Progress is stored in SQLite. `Ctrl+C` or **Stop** keeps finished work; the same command continues where it left off. | -| **Ranking & export** | Sort by `quality`, `speed`, `stability` or `uptime`; filter by protocol, country, maximum latency, anonymity and success rate; search by address or port and copy a page with one click. Export top N (or all) to `proxies.txt`, `ranked.csv`, `ranked.json`, plus `http.txt` / `https.txt` / `socks4.txt` / `socks5.txt` / `hostport.txt` in plain `host:port` format, a ready `proxychains.txt`, a browser `proxy.pac` and a Clash / Mihomo `clash.yaml` with automatic fastest-proxy selection. A protocol and country summary sits above the files. Crash-safe export generations. | -| **Rotating proxy gateway** | Set `127.0.0.1:8899` as the HTTP or SOCKS5 proxy in a browser, Telegram, a scraper or any app. Every new connection goes out through the next working proxy; failing ones are skipped and rested automatically. | -| **Recommended first** | The default order puts first the proxies that are fast, survive re-checks, come from lists with a good record and are offered by few lists (less crowded, so they live longer). | -| **Scripts and more clients** | `proxy-workbench get --country DE --top 5` prints working proxies, `proxy-workbench test socks5://…` checks your own; sing-box config and a **Use in Telegram** button for the rotating proxy. | -| **For scrapers** | Gateway user names choose per client: `country-de`, `protocol-socks5`, `latency-800`, `session-abc` (one IP per session). A per-proxy connection cap and `/status` stats. | -| **Real speed and provider** | Optional speed test in Mbit/s with a bandwidth sort; every proxy shows its provider (AS number) and hosting / data-centre ranges can be skipped. | -| **Ready-made checks** | One click adds a check for Google, YouTube, Telegram, Discord, Instagram, the OpenAI API, GitHub, Wikipedia or Cloudflare. | -| **Exit country** | The anonymity judge also reports the address the traffic really leaves from; the table shows `DE → NL` when it differs from the proxy's own country. | -| **Local API for your code** | The GUI (or `serve` on a server) answers `GET /random?protocol=socks5&country=DE` or `/proxies?max_latency=800&format=txt` with the freshest working proxies, so scripts, scrapers and bots can pick a proxy with one HTTP request. | -| **Safe by default** | Loopback-only GUI with a per-session token, CSRF/Host checks, SSRF-hardened source fetching (no private/metadata IPs, validated redirects, size limits), credential-like headers rejected. | -| **Desktop app** | Runs in the macOS menu bar with pause/start, optional start at login and one running instance; recovers correctly after sleep. The browser interface opens from it. | -| **Pools** | A named pool keeps N working proxies for a profile, with a reserve, quotas and budgets; it refills and re-checks itself and says why it is short. | -| **Schedules** | Re-check a collection or a pool on an interval in your time zone, with quiet hours, request/byte budgets and notifications when a proxy changes state. | -| **Profiles and import** | Save targets and rules as named profiles with revisions. Import your own lists from TXT, URI, CSV, JSON, Clash or sing-box with a preview, column mapping and a report of every rejected line. | -| **API keys** | Named keys with permissions, collection/pool scope, rate and concurrency limits, expiry, rotation and an audit log — on the **Keys** page or with `api-key`. | -| **Diagnostics** | A funnel shows where candidates were lost, “why 0 results” explains an empty run in plain words, and a redacted diagnostic bundle can be reviewed before saving. | -| **Backup and restore** | Backups, restore, rollback and retention cleanup, each previewed before it runs; data folders from older versions are upgraded automatically with a backup taken first. | -| **12 languages** | English, Russian, Ukrainian, German, Spanish, French, Italian, Portuguese, Polish, Turkish, Japanese and Chinese; defaults to your system language. Redesigned dark and light themes that adapt to phones and tablets. | -| **Zero setup** | A macOS `.dmg`, a Windows installer (or portable `.zip`), `pipx install`, Docker Compose, or a double-click launcher that creates its own virtual environment. | +| **Scan** | Choose target sites and success rules, use a preset or tune the check, start and resume a scan, and follow live progress. | +| **Results** | Inspect fresh, expired, failed, and unknown results; filter and sort proxies; review individual attempts; build TXT, CSV, JSON, PAC, Clash, and sing-box exports. | +| **Rotating Gateway** | See gateway health and pool size, copy its local HTTP/SOCKS5 endpoint, and get client setup examples. | +| **Mobile & Clients** | Copy or download sing-box and Clash/Mihomo configs. Set up Telegram through a link, or a QR code after enabling authenticated LAN mode. | +| **Sources** | Select supported public feeds, import your own lists, inspect source yield and errors, and manage the optional country database. | +| **Pools & Schedules** | Keep a target number of passing proxies for a list and profile; set refresh intervals, quiet hours, and budgets. | +| **API Keys** | Issue and manage scoped keys for the authenticated `/v1` control API. Secrets are shown once. | +| **How it works** | Follow the workflow, read setup guidance, investigate empty results, and access diagnostics and maintenance tools. | + +The interface has dark and light themes and 12 languages. HTTP(S), SOCKS4, SOCKS5 and IPv6 are supported. Checks can use several target URLs, repeated attempts, status/body/hash conditions, a local denylist, optional DNSBL zones, and an optional anonymity judge. The full options are documented in the [CLI](#-command-line), [gateway](#-rotating-proxy-gateway), and [API](#-local-api-use-the-proxies-from-your-own-code) sections below. ## 🚀 Quick start -Pick one way to install: +Choose the build for your system. The [latest release](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) has installers, portable archives, checksums, and a Python wheel. -| Way | How | Needs | +| System | Install or run | Requirements | | --- | --- | --- | -| **macOS app** | Download `proxy-workbench-…-macos-arm64.dmg` from the [latest release](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) and drag `Proxy Workbench.app` into Applications | macOS 11+, Apple Silicon (`arm64`) or Intel (`x86_64`) | -| **Windows app** | Download `proxy-workbench-…-windows-x64-setup.exe` from the [latest release](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) and run it; there is a portable `.zip` too, and a separate `proxy-workbench-cli.exe` for the command line | nothing else | -| **pipx** (Windows, macOS, Linux) | `pipx install git+https://github.com/DavidVoitenko/proxy-workbench` then `proxy-workbench` | Python 3.11+ and [pipx](https://pypa.io/pipx/) | -| **Source folder** | Download the code (**Code → Download ZIP** or `git clone`), then double-click `Start.bat` (Windows) / `Start.command` (macOS) or run `./run.sh` (Linux) | Python 3.11+ | -| **Docker** | Set `PROXY_WORKBENCH_API_TOKEN`, then run `docker compose up -d` with the bundled [`compose.yml`](compose.yml) (checker + API + rotating proxy) | Docker | +| **macOS, Apple Silicon** | Download `proxy-workbench-3.0.3-macos-arm64.dmg`; drag the app into Applications. | No Python needed | +| **macOS, Intel** | Download `proxy-workbench-3.0.3-macos-x86_64.dmg`; drag the app into Applications. | No Python needed | +| **Windows x64** | Run `proxy-workbench-3.0.3-windows-x64-setup.exe`; a portable ZIP and separate CLI `.exe` are also available. | No Python needed | +| **Linux, or any OS with Python** | `pipx install git+https://github.com/DavidVoitenko/proxy-workbench` then `proxy-workbench` | Python 3.11+ and [pipx](https://pypa.io/pipx/) | +| **Source checkout** | `Start.bat` on Windows, `Start.command` on macOS, or `./run.sh` on Linux. | Python 3.11+ | +| **Docker server/NAS** | Set `PROXY_WORKBENCH_API_TOKEN` and run `docker compose up -d` with [`compose.yml`](compose.yml). | Docker; headless CLI/API/gateway, no GUI | `proxy-workbench` without arguments starts the application: the interface opens in your browser, and on macOS a menu bar item shows what is happening and offers pause, start, “start at login” and quit. Starting it a second time reaches the one that is already running instead of opening a rival. `proxy-workbench run …` and the other commands below work the same way as `./run.sh …`. @@ -116,14 +101,16 @@ proxy-workbench --print-paths # which data/cache/log folders this launch woul Installed builds keep their data in your own per-user folders (`%LOCALAPPDATA%\proxy-workbench`, `~/Library/Application Support/proxy-workbench` or `~/.local/share/proxy-workbench`) and never write into their own program folder; a source checkout keeps `data/` next to the project; `PROXY_WORKBENCH_DATA` overrides all of it. Portable mode is opt-in: put an empty `proxy-workbench-portable.json` next to the program and it keeps its data beside itself. -Release artifacts are **not code-signed**: this project has no signing certificate, and the release notes and the manifest say `signed: false` rather than claiming otherwise. macOS Gatekeeper therefore asks you to confirm the first start, and Windows SmartScreen may too (**More info → Run anyway**). Every release lists its SHA-256 checksum, which proves the file is the one that was published — it does not identify a publisher. +Release installers are **not code-signed**. macOS Gatekeeper or Windows SmartScreen may ask you to confirm the first run. Compare the published SHA-256 checksum if you want to verify the downloaded file; a checksum does not establish the publisher's identity. -1. **Scan** tab: add one or more service URLs, allowed status codes and (recommended) a text that must appear in the response. -2. Press **Find and check** (“Найти и проверить”). Watch progress, speed, ETA and the number of matching proxies. -3. **Results** tab: choose order, success threshold and how many to keep, press **Build export**, then download TXT / CSV / JSON. +1. In **Scan**, add your target URL and success rules (status code and, when useful, expected text). A proxy must pass each selected target. +2. Press **Find and check**. You can stop and later resume from saved progress. +3. In **Results**, review attempts, select filters and sort order, press **Build export**, and download the format you need. Closing the browser tab does not stop the check. Quitting from the menu bar (or `Ctrl+C` in a terminal launch) stops it. +**Scope and limits:** free proxy addresses can disappear or change without notice; a passing check applies to the targets and time measured, not every site or future connection. Country lookup needs the optional offline database, and anonymity classification needs a judge endpoint. The local gateway handles TCP through HTTP or SOCKS5; it does not support SOCKS5 UDP ASSOCIATE. Docker runs without the browser GUI. + ## 🧭 How it works ```mermaid @@ -180,7 +167,7 @@ cp service.example.json data/service.json ./run.sh update-geoip # once: offline country database (DB-IP Lite, ~7 MB) ./run.sh run --country DE,NL --protocol socks5 --want 20 --attempts 1 -# Refresh only the proxies that currently pass (minutes, not hours) +# Refresh only the proxies that currently pass ./run.sh scan --recheck-passing # ...or keep the list fresh automatically every 30 minutes (Ctrl+C to stop) ./run.sh run --want 50 --watch 30 @@ -427,7 +414,7 @@ Delete it any time with `./run.sh clear-data --yes` or the button on the **How i No. Proxy Workbench measures _reachability and latency_. A public proxy sees your IP, your destination and — for plain HTTP — your traffic. Never send passwords, cookies or tokens through untrusted public proxies. Proxy Workbench itself sends no telemetry and has no accounts. **How long does a full scan take?** -It depends on how many candidates respond. With the defaults (3 attempts, 8 s request timeout, 4 s connect timeout, fail-fast, 128 workers) even ~190,000 completely dead addresses take about 3.5 hours, because each dead proxy is dropped after two short connect failures; in practice most fail much faster. Raise `--workers`, lower `--connect-timeout`, or use fewer sources for quicker runs. You can stop and resume at any time. +There is no fixed duration: it depends on the number of candidates, their timeouts, the target services, and your connection. Use fewer sources or the **Quick** preset for a shorter run. Progress is saved so you can stop and resume later. **Why did a proxy that works in my browser fail here?** Redirects are not followed, TLS certificates are verified, and each target must pass on its own threshold. Check **Details** for the exact error of every attempt. @@ -448,7 +435,7 @@ Use an **`http://`** judge: through an HTTPS tunnel a proxy cannot add headers, No. Set **Stop after finding** in the GUI or `--want 20` in the CLI. Addresses that worked in earlier scans are tried first, the rest in random order, and the scan stops as soon as 20 match. Run it again later to continue where it stopped. The **Quick** preset (1 attempt, short timeouts) makes it even faster. **Free proxies die quickly. How do I keep my list working?** -Press **Re-check only matching proxies** (or `./run.sh scan --recheck-passing`): only the proxies that currently pass are measured again, which takes minutes. `--watch 30` repeats this every 30 minutes and rewrites the export files each time. Sort by **uptime** to put the proxies that survived the most re-checks first. +Press **Re-check only matching proxies** (or `./run.sh scan --recheck-passing`): only the proxies that currently pass are measured again. `--watch 30` repeats this every 30 minutes and rewrites the export files each time. Sort by **uptime** to put the proxies that survived the most re-checks first. **How do I get proxies from a specific country?** Download the country database once (**Sources → Country database**, or `./run.sh update-geoip`), then enter the countries (`DE, NL`) in the GUI or pass `--country DE,NL`. Addresses from other countries are skipped before any request is sent. Results from a country-limited run are kept, so a later run for all countries does not check them again. Country data: [DB-IP](https://db-ip.com) (CC BY 4.0) plus the country field of Geonode sources. @@ -459,8 +446,8 @@ The IP is not in your local denylist and (if enabled) not listed by the DNSBL zo **Can I use my own proxy list only?** Yes: `--no-sources --input my.txt`, or paste/upload a TXT on the **Sources** tab. -**Is running it legal?** -Checking public lists is generally fine, but you are responsible for respecting the terms of the services you test and the laws where you live. Only test endpoints you are allowed to test. +**What may I check?** +Check only endpoints and sources you are allowed to use, and follow the applicable service terms and laws. ## 🗺 Roadmap @@ -481,17 +468,17 @@ Checking public lists is generally fine, but you are responsible for respecting - [x] Source ratings and proxychains export - [x] Docker image for headless servers -Have an idea? Open a [feature request](../../issues/new/choose) or start a [discussion](../../discussions). +Have an idea? Open a [feature request](https://github.com/DavidVoitenko/proxy-workbench/issues/new/choose) or start a [discussion](https://github.com/DavidVoitenko/proxy-workbench/discussions). ## 🤝 Contributing -Bug reports, new sources, translations and code are welcome — open an [issue](../../issues) or a pull request. Tests run entirely on local mocks: +Bug reports, new sources, translations and code are welcome — open an [issue](https://github.com/DavidVoitenko/proxy-workbench/issues) or a pull request. Tests run entirely on local mocks: ```sh python -m unittest discover -s tests -v ``` -Found a vulnerability? Please report it privately through [GitHub security advisories](../../security/advisories/new) rather than a public issue. +Found a vulnerability? Please report it privately through [GitHub security advisories](https://github.com/DavidVoitenko/proxy-workbench/security/advisories/new) rather than a public issue. If Proxy Workbench saved you time, **a ⭐ on GitHub helps other people find it.** diff --git a/README.ru.md b/README.ru.md index a993049..e6bd8f2 100644 --- a/README.ru.md +++ b/README.ru.md @@ -1,146 +1,114 @@
-Proxy Workbench +Proxy Workbench — локальный поиск и проверка прокси # Proxy Workbench -### Находит бесплатные прокси, которые реально работают — на нужных вам сайтах +### Найдите прокси, которые работают с нужными вам сайтами -Программа сама собирает бесплатные прокси из **150 открытых источников**, проверяет каждый на тех сайтах и сервисах, которые нужны **именно вам**, и оставляет только рабочие. Результат — готовые списки, один **ротирующий прокси** для браузера, Telegram и любых программ или **API** для ваших скриптов. +Соберите адреса из открытых списков или своих файлов, проверьте их на выбранных сервисах и используйте результаты в приложениях, файлах экспорта или скриптах. Proxy Workbench работает локально: браузерный интерфейс, CLI, ротирующий прокси-шлюз и API. -Работает на вашем компьютере: приложение для macOS и Windows, командная строка, Docker · HTTP, HTTPS, SOCKS4, SOCKS5 · 12 языков · без регистрации и телеметрии +**Windows · macOS · Linux**  |  **HTTP(S) · SOCKS4 · SOCKS5**  |  **12 языков интерфейса** +[![CI](https://github.com/DavidVoitenko/proxy-workbench/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/DavidVoitenko/proxy-workbench/actions/workflows/ci.yml) +[![Последний релиз](https://img.shields.io/github/v/release/DavidVoitenko/proxy-workbench?label=release)](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) ![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python&logoColor=white) -![License: MIT](https://img.shields.io/badge/license-MIT-2ea44f) -![Platforms](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-5f6b73) -![Dependencies](https://img.shields.io/badge/dependencies-httpx%20%2B%20keyring-42bbaa) -![Runs locally](https://img.shields.io/badge/runs-100%25%20local-209c8b) +![Лицензия MIT](https://img.shields.io/badge/license-MIT-2ea44f) [English](README.md) · **Русский** -[Быстрый старт](#-быстрый-старт) · [Возможности](#-возможности) · [Командная строка](#запуск-через-командную-строку) · [Чистота](#проверка-чистоты-и-локальный-denylist) · [Анонимность](#проверка-анонимности) · [FAQ](#-частые-вопросы) · [Планы](#-планы) +[Скачать](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) · [Сайт](https://davidvoitenko.github.io/proxy-workbench/) · [Быстрый старт](#-быстрый-старт) · [Вкладки](#-восемь-вкладок) · [CLI](#запуск-через-командную-строку) · [API](#локальное-api-прокси-в-своих-программах)
-Демо Proxy Workbench: проверка, рейтинг, фильтр элитных прокси +Демонстрация интерфейса Proxy Workbench -Коротко: настройка проверки → рейтинг → фильтр «только элитные» → детали попыток → источники → смена языка (синтетические данные). +Демонстрация с синтетическими данными. Доступность реальных прокси зависит от источников и параметров проверки.
--- -> **Статус:** публичная beta. Проект измеряет доступность и задержку; он не обещает анонимность, безопасность или стабильную работу сторонних прокси. - ## Что делает программа -Списков бесплатных прокси много, но большинство адресов в них мёртвые, медленные или заблокированы как раз на том сайте, который вам нужен. Proxy Workbench делает всю грязную работу за три шага: +Открытые списки прокси быстро устаревают. Proxy Workbench превращает адреса-кандидаты в список, измеренный по вашим условиям: -1. **Собирает.** Скачивает адреса из 150 открытых источников (106 подключены сразу) или из ваших файлов и убирает дубликаты. -2. **Проверяет.** Отправляет через каждый прокси настоящие запросы к вашим сайтам — по несколько раз — и смотрит код ответа, нужный текст на странице и скорость. Дополнительно определяет страну, анонимность (прозрачный / анонимный / элитный) и чистоту IP. -3. **Отдаёт готовое.** Лучшие прокси — в файлах TXT / CSV / JSON, в конфигурациях для браузера, Clash и sing-box, через ротирующий прокси `127.0.0.1:8899` или через API. Пулы и расписания держат список свежим сами. +1. **Сбор:** выбирает из каталога **150 записей**; **106 поддерживаемых лент** включены по умолчанию при новой установке. Можно импортировать свой список. Адреса приводятся к единому виду, дубликаты удаляются. +2. **Проверка:** отправляет реальные запросы через каждый адрес к одному или нескольким URL. Можно задать HTTP-коды, текст или хеш ответа, порог успешных попыток, таймауты и дополнительные проверки репутации или анонимности. +3. **Использование:** фильтры и экспорт, локальный ротирующий шлюз `127.0.0.1:8899` или API для последнего опубликованного списка. Пулы и расписания помогают обновлять результаты. -Всё работает на вашем компьютере. Интерфейс слушает только `127.0.0.1`. +Интерфейс и локальное API по умолчанию доступны только на этом компьютере. Открыть серверное API для сети можно явно, с отдельным токеном. ## 📸 Скриншоты - - + + + + + + - - + + + + + +
Настройка и прогресс проверки
Проверка — сервисы, правила успеха и живой прогресс
Рейтинг прокси
Результаты — рейтинг по качеству или скорости с оценкой чистоты
Вкладка проверки: цели и ход работы
Проверка — цели и прогресс
Вкладка результатов: фильтры и рейтинг
Результаты — фильтры, сортировка и экспорт
Подробности отдельных попыток проверки
Детали — отдельные попытки и ошибки
Результаты в светлой теме
Светлая тема — переключается в шапке
Детали попыток
Детали — каждая попытка по каждому сервису
Светлая тема
Светлая тема — переключается одной кнопкой
Вкладка источников с каталогом и своими списками
Источники — встроенный каталог и свои списки
Вкладка шлюза в выключенном состоянии
Ротирующий шлюз — настройка локального маршрута; на кадре выключен
Вкладка пулов и расписаний с настройкой размера и резерва
Пулы и расписания — цель, резерв и обновление
Вкладка ключей API без раскрытых секретов
Ключи API — права и лимиты без раскрытых секретов
-На скриншотах синтетические данные из документационных диапазонов IP (RFC 5737). +Результаты, метрики и география на скриншотах синтетические; IP-адреса взяты из диапазонов для документации (RFC 5737). Каталог источников настоящий, встроенный в проект. Скриншоты не подразумевают наличие рабочих публичных прокси. -## ✨ Возможности +## 🧭 Восемь вкладок -| | | +| Вкладка | Что в ней можно делать | | --- | --- | -| **150 записей каталога / 106 лент для сбора** | В каталоге **117 публичных бесплатных записей**; остальные относятся к другим условиям доступа. Текст, JSON, CSV и HTML читаются адаптерами конкретных источников. Неподдерживаемые форматы, недоступные снимки и ограничения сбора остаются видны с причинами. | -| **Протокол неизвестен? Не проблема** | Адреса без протокола можно проверить сразу как HTTP, SOCKS4 и SOCKS5: останется тот вариант, который работает. | -| **Протоколы** | HTTP, HTTPS/CONNECT, явные `https://`-прокси, SOCKS4, SOCKS5 / SOCKS5h, IPv4 и IPv6. | -| **Проверка на ваших сервисах** | Несколько targets в одном профиле (до 20 в GUI). Прокси проходит, только если работает со **всеми**. | -| **Строгие условия успеха** | Допустимые HTTP-коды, обязательный текст в ответе, ожидаемый SHA-256, `GET`/`HEAD`, безопасные заголовки. Отсекает капчи и заглушки с кодом `200`. | -| **Повторные замеры** | N попыток на сервис (по умолчанию 3), порог успешности для каждого сервиса, медиана задержки и разброс. | -| **Нужно всего несколько прокси или конкретная страна?** | `--want 20` останавливает проверку, как только найдено 20 подходящих; сначала проверяются адреса, которые уже работали. `--country DE,NL` пропускает все остальные страны *до* проверки, поэтому поиск по стране занимает минуты, а не часы. | -| **Всегда свежий список** | «Перепроверить только подходящие» обновляет текущий список за минуты; `--watch 30` делает это автоматически каждые 30 минут. У каждого прокси есть история живучести, по ней можно сортировать. | -| **Рейтинг источников** | На вкладке «Источники» видно, сколько рабочих прокси дал каждый список: мёртвые списки легко отключить и ускорить сбор. | -| **Пресеты** | «Быстро», «Баланс» и «Тщательно» настраивают попытки, таймауты и воркеры одной кнопкой. | -| **Уровни анонимности** | Укажите любую echo-страницу (judge), и каждый рабочий прокси получит уровень **transparent** (выдаёт ваш IP), **anonymous** (выдаёт себя заголовками `Via` / `X-Forwarded-For`) или **elite**. Фильтр в один клик или `--min-anonymity elite`. | -| **Проверка чистоты** | Локальный denylist (IP / CIDR / точный адрес) и опциональные DNSBL-зоны. Вердикты `clean`, `listed`, `local_denied`, `unknown`, строгий режим. | -| **Большие списки** | Ограниченная очередь, лимит частоты запросов, автоподбор числа воркеров. **Быстрая предпроверка** отсеивает адреса, которые даже не принимают TCP-подключение, ещё до полной проверки; **досрочная отбраковка** пропускает оставшиеся попытки, когда прокси уже не пройдёт порог, а короткий **таймаут подключения** быстро отсеивает мёртвые адреса. Проверено на 190 000 синтетических кандидатов. | -| **Остановка и продолжение** | Прогресс хранится в SQLite. `Ctrl+C` или **Остановить** сохраняет готовое; повторный запуск продолжает. | -| **Рейтинг и экспорт** | Сортировка `quality`, `speed`, `stability` или `uptime`; фильтры по протоколу, стране, максимальной задержке, анонимности и успешности; поиск по адресу или порту и копирование страницы в один клик. Экспорт топ-N или всех в `proxies.txt`, `ranked.csv`, `ranked.json`, а также `http.txt` / `https.txt` / `socks5.txt` / `hostport.txt` в формате `host:port` и готовый `proxychains.txt`. Crash-safe поколения экспорта. | -| **Локальное API для своих программ** | GUI (или команда `serve` на сервере) отвечает на `GET /random?protocol=socks5&country=DE` или `/proxies?max_latency=800&format=txt` самыми свежими рабочими прокси: скрипт, парсер или бот берёт прокси одним HTTP-запросом. | -| **Ротирующий прокси-шлюз** | Укажите `127.0.0.1:8899` как HTTP- или SOCKS5-прокси в браузере, Telegram, парсере или любой программе. Каждое новое соединение уходит через следующий рабочий прокси; неработающие автоматически пропускаются. | -| **Сначала рекомендуемые** | По умолчанию первыми идут прокси, которые быстрые, переживают перепроверки, пришли из списков с хорошей историей и встречаются в немногих списках: ими меньше пользуются, поэтому живут дольше. | -| **Скрипты и другие клиенты** | `proxy-workbench get --country DE --top 5` выводит рабочие прокси, `proxy-workbench test socks5://…` проверяет ваши; конфиг sing-box и кнопка **Открыть в Telegram** для ротирующего прокси. | -| **Для парсеров** | В имени пользователя шлюза выбирается всё нужное: `country-de`, `protocol-socks5`, `latency-800`, `session-abc` (один IP на сессию). Лимит соединений на прокси и статистика `/status`. | -| **Реальная скорость и провайдер** | Необязательный замер скорости в Мбит/с и сортировка по ней; у каждого прокси виден провайдер (ASN), хостинг и дата-центры можно пропускать. | -| **Готовые проверки** | Один клик добавляет проверку Google, YouTube, Telegram, Discord, Instagram, OpenAI API, GitHub, Wikipedia или Cloudflare. | -| **Страна выхода** | Judge показывает, с какого адреса трафик на самом деле выходит в интернет; если страна отличается от страны прокси, в таблице видно `DE → NL`. | -| **Готовые конфиги** | `proxy.pac` для браузера и `clash.yaml` для Clash / Mihomo с автоматическим выбором самого быстрого прокси; над файлами сводка по протоколам и странам. | -| **Безопасность по умолчанию** | GUI только на loopback с токеном сессии и проверкой Host/Origin, защищённая загрузка источников (без private/metadata IP, проверка redirects, лимиты размера), credential-like заголовки отклоняются. | -| **Приложение для рабочего стола** | Живёт в меню-баре macOS: пауза и запуск, автозапуск при входе по желанию, один экземпляр, корректное восстановление после сна. Интерфейс в браузере открывается из него. | -| **Пулы** | Именованный пул держит N рабочих прокси для профиля с резервом, квотами и бюджетами; сам пополняется, перепроверяется и объясняет, почему не хватает. | -| **Расписания** | Перепроверка коллекции или пула по интервалу в вашем часовом поясе, тихие часы, бюджеты запросов и трафика, уведомления о смене состояния прокси. | -| **Профили и импорт** | Цели и правила сохраняются как именованные профили с ревизиями. Импорт своих списков из TXT, URI, CSV, JSON, Clash и sing-box с предпросмотром, сопоставлением колонок и отчётом по каждой отклонённой строке. | -| **API-ключи** | Именованные ключи с правами, областью действия (коллекции и пулы), лимитами, сроком, ротацией и журналом аудита — на странице **Ключи** или командой `api-key`. | -| **Диагностика** | Воронка показывает, где потерялись кандидаты; «почему 0 результатов» объясняет пустой прогон простыми словами; диагностический пакет без секретов можно просмотреть перед сохранением. | -| **Резервные копии** | Backup, восстановление, откат и очистка по сроку хранения — каждое действие сначала показывает предпросмотр; папки данных старых версий обновляются автоматически, перед этим делается копия. | -| **12 языков** | Русский, английский, украинский, немецкий, испанский, французский, итальянский, португальский, польский, турецкий, японский и китайский; по умолчанию язык системы. Переработанные тёмная и светлая темы, адаптация под телефоны и планшеты. | -| **Без настройки** | `.dmg` для macOS, установщик (или portable `.zip`) для Windows, `pipx install`, Docker Compose или запуск двойным кликом, который сам создаёт виртуальное окружение. | +| **Проверка** | Задать сайты и условия успеха, выбрать пресет или точные параметры, запустить и продолжить проверку, следить за прогрессом. | +| **Результаты** | Смотреть свежие, просроченные, неудачные и неизвестные результаты; фильтровать и сортировать; изучать попытки; экспортировать TXT, CSV, JSON, PAC, Clash и sing-box. | +| **Ротирующий шлюз** | Проверить состояние и размер пула, скопировать локальный HTTP/SOCKS5-адрес, получить инструкции для клиентов. | +| **Мобильные клиенты** | Скопировать или скачать конфиги sing-box и Clash/Mihomo. Настроить Telegram через ссылку либо через QR-код после включения защищённого LAN-режима. | +| **Источники** | Выбрать поддерживаемые открытые ленты, импортировать свои списки, посмотреть отдачу и ошибки источников, управлять дополнительной базой стран. | +| **Пулы и расписания** | Поддерживать нужное количество подходящих прокси для списка и профиля, настроить интервалы, тихие часы и бюджеты. | +| **Ключи API** | Создать и управлять ключами с ограниченными правами для API `/v1`. Секрет показывается один раз. | +| **Как это работает** | Изучить процесс и инструкции, разобраться с пустым результатом, открыть диагностику и инструменты обслуживания. | + +Интерфейс поддерживает тёмную и светлую темы и 12 языков. Доступны HTTP(S), SOCKS4, SOCKS5 и IPv6. Проверка умеет работать с несколькими URL, повторными попытками, условиями по коду/телу/хешу, локальным denylist, дополнительными DNSBL-зонами и judge-сервисом для оценки анонимности. Подробности — в разделах [CLI](#запуск-через-командную-строку), [шлюза](#ротирующий-прокси-шлюз) и [API](#локальное-api-прокси-в-своих-программах). ## 🚀 Быстрый старт -Выберите способ установки: +Выберите сборку для своей системы. В [последнем релизе](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) есть установщики, portable-архивы, контрольные суммы и Python wheel. -| Способ | Как | Что нужно | +| Система | Установка или запуск | Что нужно | | --- | --- | --- | -| **Программа для macOS** | Скачайте `proxy-workbench-…-macos-arm64.dmg` из [последнего релиза](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) и перетащите `Proxy Workbench.app` в «Программы» | macOS 11+, Apple Silicon (`arm64`) или Intel (`x86_64`) | -| **Программа для Windows** | Скачайте `proxy-workbench-…-windows-x64-setup.exe` из [последнего релиза](https://github.com/DavidVoitenko/proxy-workbench/releases/latest) и запустите установщик; есть portable-архив `.zip` и отдельный `proxy-workbench-cli.exe` для командной строки | больше ничего | -| **pipx** (Windows, macOS, Linux) | `pipx install git+https://github.com/DavidVoitenko/proxy-workbench`, затем `proxy-workbench` | Python 3.11+ и [pipx](https://pypa.io/pipx/) | -| **Папка с кодом** | Скачайте код (**Code → Download ZIP** или `git clone`) и запустите, как в таблице ниже | Python 3.11+ | -| **Docker** | Задайте `PROXY_WORKBENCH_API_TOKEN`, затем запустите `docker compose up -d` с готовым [`compose.yml`](compose.yml): проверка + API + ротирующий прокси | Docker | +| **macOS, Apple Silicon** | Скачайте `proxy-workbench-3.0.3-macos-arm64.dmg` и перетащите приложение в «Программы». | Python не нужен | +| **macOS, Intel** | Скачайте `proxy-workbench-3.0.3-macos-x86_64.dmg` и перетащите приложение в «Программы». | Python не нужен | +| **Windows x64** | Запустите `proxy-workbench-3.0.3-windows-x64-setup.exe`. Есть portable ZIP и отдельный CLI `.exe`. | Python не нужен | +| **Linux или любая ОС с Python** | `pipx install git+https://github.com/DavidVoitenko/proxy-workbench`, затем `proxy-workbench`. | Python 3.11+ и [pipx](https://pypa.io/pipx/) | +| **Папка с исходниками** | `Start.bat` на Windows, `Start.command` на macOS или `./run.sh` на Linux. | Python 3.11+ | +| **Сервер/NAS с Docker** | Задайте `PROXY_WORKBENCH_API_TOKEN` и выполните `docker compose up -d` с готовым [`compose.yml`](compose.yml). | Docker; CLI/API/шлюз без GUI | -`proxy-workbench` без аргументов запускает приложение: интерфейс открывается в браузере, а на macOS в меню-баре появляется значок с состоянием и пунктами «пауза», «запуск проверки», «запускать при входе» и «выход». Повторный запуск обращается к уже работающему экземпляру, а не поднимает вторую копию. `proxy-workbench run …` и остальные команды работают так же, как `./run.sh …`. +Команда `proxy-workbench` без аргументов открывает интерфейс в браузере. На macOS появляется значок в строке меню для запуска, паузы и выхода. Повторный запуск обращается к уже работающему экземпляру. Команды `proxy-workbench run …` и `./run.sh run …` выполняют одну и ту же задачу. ```sh -proxy-workbench # приложение: интерфейс + меню-бар + один экземпляр -proxy-workbench gui # только интерфейс, без меню-бара -proxy-workbench --no-desktop # то же самое, другими словами -proxy-workbench --print-paths # какие папки data/cache/logs выберет этот запуск +proxy-workbench # приложение и локальный интерфейс +proxy-workbench gui # только интерфейс +proxy-workbench --print-paths # выбранные папки данных, кэша и журналов ``` -Установленная сборка хранит данные в персональных папках пользователя (`%LOCALAPPDATA%\proxy-workbench`, `~/Library/Application Support/proxy-workbench` или `~/.local/share/proxy-workbench`) и **никогда** не пишет в собственную папку программы; исходники продолжают использовать `data/` рядом с проектом; переменная `PROXY_WORKBENCH_DATA` задаёт папку явно. Portable-режим включается только явно: положите пустой файл `proxy-workbench-portable.json` рядом с программой, и она будет хранить данные рядом с собой. - -Артефакты релизов **не подписаны сертификатом**: у проекта нет ключа подписи, и в заметках о релизе и в манифесте стоит `signed: false`, а не утверждение о подписи. Поэтому при первом запуске macOS попросит подтвердить открытие, а SmartScreen может попросить то же (**Подробнее → Выполнить в любом случае**). У каждого релиза опубликована контрольная сумма SHA-256: она доказывает, что файл именно тот, что опубликован, но не называет издателя. - -Запуск из папки с кодом: - -| ОС | Запуск интерфейса | -| --- | --- | -| **Windows** | двойной клик по `Start.bat` | -| **macOS** | двойной клик по `Start.command` | -| **Linux** | `./run.sh` (или `./run.sh gui`) | - -На Windows нужен Python 3.11+ с Python Launcher (`py`). Первый запуск создаст `.venv/` и установит зависимость, затем откроется локальная страница в вашем браузере. По умолчанию включена тёмная тема; кнопка вверху переключает на светлую. Рядом кнопка EN/RU переключает язык интерфейса: по умолчанию используется язык браузера (русский для `ru`, иначе английский). Оба выбора сохраняются в браузере. Сервер доступен только на этом устройстве. Повторный запуск открывает уже работающий интерфейс. +Установленная сборка хранит данные в папке пользователя (`%LOCALAPPDATA%\proxy-workbench` на Windows, `~/Library/Application Support/proxy-workbench` на macOS, `~/.local/share/proxy-workbench` на Linux); исходники используют `data/` рядом с проектом. `PROXY_WORKBENCH_DATA` задаёт папку явно. Для portable-режима положите пустой `proxy-workbench-portable.json` рядом с программой. -1. В разделе **Проверка** добавьте один или несколько сервисов, HTTP-коды и при необходимости текст ответа. Условие **«все сервисы»** действует всегда. -2. При необходимости откройте **Источники**: редактируйте URL, добавьте свои списки вставкой или TXT-файлом. SOCKS-списки указываются как `socks4 URL` / `socks5 URL`, список с неизвестным протоколом — как `auto URL`, любая веб-страница или CSV — как `text URL`, Geonode JSON API — как `geonode URL`. -3. Нажмите **Найти и проверить**. Справа: прогресс, скорость обхода, оставшееся время и число подходящих прокси. **Остановить** сохраняет завершённые результаты; **Продолжить базу** продолжает текущий профиль без повторной загрузки источников. -4. В **Результатах** выберите порядок, порог успешности и количество, нажмите **Сформировать экспорт**, затем TXT / CSV / JSON. Кнопка **Детали** показывает каждую попытку по каждому сервису. Таблица обновляется при открытии, завершении проверки или кнопкой **Обновить таблицу**. +Установщики релиза **не подписаны сертификатом**. macOS Gatekeeper или Windows SmartScreen могут запросить подтверждение первого запуска. Опубликованная контрольная сумма SHA-256 помогает сверить загруженный файл, но не подтверждает личность издателя. -Кнопка **Перепроверить всю базу заново** заменяет результаты текущего профиля новыми. Изменение URL или параметров замера создаёт другой профиль. Настройки сохраняются по кнопке и при запуске. Завершённый экспорт остаётся доступным при следующем открытии. +1. Во вкладке **Проверка** добавьте URL и условия успеха: HTTP-код и, при необходимости, ожидаемый текст. Прокси должен пройти каждый выбранный сервис. +2. Нажмите **Найти и проверить**. Работу можно остановить и затем продолжить с сохранённого прогресса. +3. Во вкладке **Результаты** изучите попытки, задайте фильтры и сортировку, нажмите **Сформировать экспорт** и скачайте нужный формат. -Не закрывайте окно терминала, пока пользуетесь интерфейсом. Закрытие вкладки браузера не останавливает работу. Для выхода нажмите Ctrl+C в окне приложения: проверка остановится с сохранением прогресса. +Закрытие вкладки браузера не останавливает проверку. Для выхода используйте меню приложения или `Ctrl+C` при запуске из терминала. -Если переносите папку на другое устройство, не переносите `.venv`: на новом устройстве запускающий файл создаст окружение заново. ZIP содержит только исходники и инструкции, без баз, настроек и секретов. +**Границы работы:** открытые прокси могут исчезнуть или измениться без предупреждения; успешная проверка относится к выбранным сервисам и моменту измерения. Для определения страны нужна дополнительная локальная база, для оценки анонимности — judge-сервис. Локальный шлюз передаёт TCP через HTTP или SOCKS5; SOCKS5 UDP ASSOCIATE не поддерживается. Docker работает без браузерного GUI. ## Запуск через командную строку @@ -152,7 +120,7 @@ proxy-workbench --print-paths # какие папки data/cache/logs выб ./run.sh run ``` -Первый запуск создаст `.venv` и установит зависимость. Launcher сохраняет SHA-256 `requirements.txt` и повторно обновляет окружение при изменении зависимостей. Затем загрузит публичные списки из `sources.json`, удалит дубликаты и проверит **все** адреса. Число кандидатов зависит от источников: 190 тысяч не гарантированы. Нет ограничения на количество проверяемых адресов, общего таймера прохода или остановки при заполнении пула. Фильтры по стране, ChatGPT и инвойсам не выполняются; отдельно доступны локальный denylist и опциональные DNSBL-сигналы. +Первый запуск создаст `.venv` и установит зависимости. Launcher сверяет SHA-256 `requirements.txt` и обновляет окружение при изменении файла. Затем загрузит выбранные публичные ленты, удалит дубликаты и проверит адреса. Число кандидатов зависит от источников; 190 тысяч не гарантированы. По умолчанию нет ограничения на количество результатов и общего таймера прохода; при необходимости используйте `--want`, бюджеты запросов и трафика, а также фильтр страны. Отдельно доступны локальный denylist и опциональные DNSBL-сигналы. По умолчанию: HTTPS-запрос к `https://example.com/`, 3 независимых замера на адрес, таймаут 8 секунд на запрос, до 100 стартов запросов/секунду. Нужны успешные ответы в двух из трёх попыток. При ограничении файловых дескрипторов число воркеров автоматически снижается. @@ -252,7 +220,7 @@ python -m venv .venv Бесплатные прокси быстро умирают. Чтобы не проверять всю базу заново: ```sh -./run.sh scan --recheck-passing # перепроверить только подходящие (минуты) +./run.sh scan --recheck-passing # перепроверить только подходящие ./run.sh run --want 50 --watch 30 # найти 50 и перепроверять их каждые 30 минут (Ctrl+C — стоп) ``` @@ -324,7 +292,7 @@ python -m venv .venv URL, содержимое, заголовки, request-профиль, политика denylist/DNSBL, число попыток, таймаут и размер ответа определяют профиль. В профиль также входит digest фактического набора заголовков пресета, поэтому изменение версии продукта не смешивает старые и новые результаты. Повторный запуск того же профиля продолжает проход; для обновления старых оценок нужен `--recheck`. Профили версии 1 после обновления получают новый профиль версии 2, поэтому первый запуск может начать новый проход. Прерванный посреди попыток адрес проверяется заново. Завершённые результаты пишутся в SQLite пакетами; Ctrl+C сохраняет текущий пакет, аварийное завершение может потребовать повторить последний пакет. -Прогресс и оценка оставшегося времени обновляются каждые 2 секунды. По умолчанию включены досрочная отбраковка (`--fail-fast`) и таймаут подключения 4 секунды (`--connect-timeout`): мёртвый адрес отбрасывается после двух коротких неудачных подключений вместо трёх полных таймаутов. Поэтому даже 190 тысяч полностью неотвечающих адресов на 128 воркерах проверяются примерно за 3,5 часа вместо 10; на практике быстрее. `--no-fail-fast` возвращает прежний режим, когда выполняются все попытки. Несколько targets увеличивают число запросов. Ограничение скорости и параллельности настраиваются: +Прогресс и оценка оставшегося времени обновляются каждые 2 секунды. По умолчанию включены досрочная отбраковка (`--fail-fast`) и таймаут подключения 4 секунды (`--connect-timeout`): безответный адрес можно отбросить раньше, если порог успеха уже недостижим. Длительность прохода зависит от количества адресов, таймаутов, целевых сервисов и вашей сети. `--no-fail-fast` выполняет все попытки. Несколько targets увеличивают число запросов. Ограничение скорости и параллельности настраиваются: ```sh ./run.sh run --workers 256 --rate 100 --timeout 8 --connect-timeout 3 --attempts 3 @@ -332,7 +300,7 @@ URL, содержимое, заголовки, request-профиль, поли `--workers` здесь — потолок, а не число одновременных проверок: конвейер сам решает, сколько ему нужно, и до 256 одновременно дойдёт только тот прогон, которому это действительно требуется. Бюджеты прогона и команда `bench` описаны выше. -Не создаётся задача на каждый из 190 тысяч адресов: очередь ограничена удвоенным числом воркеров. Нет предварительного TCP-фильтра, который мог бы отсеять адрес до проверки сервиса. Попытки прекращаются досрочно, только если порог успешности уже недостижим (отключается `--no-fail-fast`). Одновременно разрешён один процесс на одну папку `data`. +Не создаётся задача на каждый адрес: очередь ограничена удвоенным числом воркеров. Включённая по умолчанию быстрая TCP-предпроверка отсеивает адреса, которые не принимают соединение, до проверки сервиса; её можно отключить параметром `--prefilter 0`. Попытки прекращаются досрочно, когда порог успешности уже недостижим (отключается `--no-fail-fast`). Одновременно разрешён один процесс на одну папку `data`. ## Свои списки и независимые наборы @@ -570,11 +538,11 @@ IP нет в вашем локальном denylist и (если включен - [x] Рейтинг источников и экспорт для proxychains - [x] Docker-образ для серверов без GUI -Есть идея? Создайте [feature request](../../issues/new/choose) или откройте [обсуждение](../../discussions). +Есть идея? Создайте [запрос функции](https://github.com/DavidVoitenko/proxy-workbench/issues/new/choose) или откройте [обсуждение](https://github.com/DavidVoitenko/proxy-workbench/discussions). ## 🤝 Участие -Рады баг-репортам, новым источникам, переводам и коду — откройте [issue](../../issues) или pull request. Об уязвимостях сообщайте приватно через [GitHub security advisories](../../security/advisories/new), а не в публичном issue. +Рады сообщениям об ошибках, новым источникам, переводам и коду — откройте [issue](https://github.com/DavidVoitenko/proxy-workbench/issues) или pull request. Об уязвимостях сообщайте приватно через [GitHub security advisories](https://github.com/DavidVoitenko/proxy-workbench/security/advisories/new), а не в публичном issue. Если проект сэкономил вам время — **поставьте ⭐, это помогает другим его найти.** diff --git a/docs/assets/demo.gif b/docs/assets/demo.gif index 1e98757..76945b0 100644 Binary files a/docs/assets/demo.gif and b/docs/assets/demo.gif differ diff --git a/docs/assets/screenshots/details-dark.png b/docs/assets/screenshots/details-dark.png index ead8005..2032c43 100644 Binary files a/docs/assets/screenshots/details-dark.png and b/docs/assets/screenshots/details-dark.png differ diff --git a/docs/assets/screenshots/gateway-dark.png b/docs/assets/screenshots/gateway-dark.png new file mode 100644 index 0000000..d09250b Binary files /dev/null and b/docs/assets/screenshots/gateway-dark.png differ diff --git a/docs/assets/screenshots/keys-dark.png b/docs/assets/screenshots/keys-dark.png new file mode 100644 index 0000000..e51c4c0 Binary files /dev/null and b/docs/assets/screenshots/keys-dark.png differ diff --git a/docs/assets/screenshots/pools-dark.png b/docs/assets/screenshots/pools-dark.png new file mode 100644 index 0000000..c771de2 Binary files /dev/null and b/docs/assets/screenshots/pools-dark.png differ diff --git a/docs/assets/screenshots/results-dark.png b/docs/assets/screenshots/results-dark.png index e606226..0bbe656 100644 Binary files a/docs/assets/screenshots/results-dark.png and b/docs/assets/screenshots/results-dark.png differ diff --git a/docs/assets/screenshots/results-light.png b/docs/assets/screenshots/results-light.png index aee9def..22dbdf8 100644 Binary files a/docs/assets/screenshots/results-light.png and b/docs/assets/screenshots/results-light.png differ diff --git a/docs/assets/screenshots/ru/details-dark.png b/docs/assets/screenshots/ru/details-dark.png index f9e573f..50e6938 100644 Binary files a/docs/assets/screenshots/ru/details-dark.png and b/docs/assets/screenshots/ru/details-dark.png differ diff --git a/docs/assets/screenshots/ru/gateway-dark.png b/docs/assets/screenshots/ru/gateway-dark.png new file mode 100644 index 0000000..def01dc Binary files /dev/null and b/docs/assets/screenshots/ru/gateway-dark.png differ diff --git a/docs/assets/screenshots/ru/keys-dark.png b/docs/assets/screenshots/ru/keys-dark.png new file mode 100644 index 0000000..451ead1 Binary files /dev/null and b/docs/assets/screenshots/ru/keys-dark.png differ diff --git a/docs/assets/screenshots/ru/pools-dark.png b/docs/assets/screenshots/ru/pools-dark.png new file mode 100644 index 0000000..c5c4f03 Binary files /dev/null and b/docs/assets/screenshots/ru/pools-dark.png differ diff --git a/docs/assets/screenshots/ru/results-dark.png b/docs/assets/screenshots/ru/results-dark.png index b47d3b9..ca3c5f8 100644 Binary files a/docs/assets/screenshots/ru/results-dark.png and b/docs/assets/screenshots/ru/results-dark.png differ diff --git a/docs/assets/screenshots/ru/results-light.png b/docs/assets/screenshots/ru/results-light.png index d7c58b6..61bc375 100644 Binary files a/docs/assets/screenshots/ru/results-light.png and b/docs/assets/screenshots/ru/results-light.png differ diff --git a/docs/assets/screenshots/ru/scan-dark.png b/docs/assets/screenshots/ru/scan-dark.png index 270802f..917983a 100644 Binary files a/docs/assets/screenshots/ru/scan-dark.png and b/docs/assets/screenshots/ru/scan-dark.png differ diff --git a/docs/assets/screenshots/ru/sources-dark.png b/docs/assets/screenshots/ru/sources-dark.png new file mode 100644 index 0000000..a714cff Binary files /dev/null and b/docs/assets/screenshots/ru/sources-dark.png differ diff --git a/docs/assets/screenshots/scan-dark.png b/docs/assets/screenshots/scan-dark.png index 2201610..6249820 100644 Binary files a/docs/assets/screenshots/scan-dark.png and b/docs/assets/screenshots/scan-dark.png differ diff --git a/docs/assets/screenshots/sources-dark.png b/docs/assets/screenshots/sources-dark.png new file mode 100644 index 0000000..6ce8a1a Binary files /dev/null and b/docs/assets/screenshots/sources-dark.png differ diff --git a/docs/assets/social-preview.png b/docs/assets/social-preview.png index a7f55bb..bce6fa8 100644 Binary files a/docs/assets/social-preview.png and b/docs/assets/social-preview.png differ diff --git a/docs/index.html b/docs/index.html index c2e4cd2..e1c34ce 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,153 +1,342 @@ - - -Proxy Workbench — free proxy checker for your own sites - - - - - - - - - - - - - + + + + + Proxy Workbench — find and verify public proxies + + + + + + + + + + + + + + + + + -
- - -
-

Find every free proxy.
Keep the ones that work.

-

Proxy Workbench collects public HTTP, HTTPS, SOCKS4 and SOCKS5 proxies from a catalog of 150 sources (106 collected out of the box), tests every one against your own sites, rates anonymity and drops blacklisted IPs, all on your own machine.

-
- ⬇ Download latest release - ★ Star on GitHub + + -
-

Why people use it

-
-

Tests against your sites

A proxy passes only if it works for every service you list: status codes, required text in the body, even a SHA-256 of the response. Captcha pages with status 200 don't pass.

-

Anonymity levels

Every working proxy is rated elite, anonymous or transparent through an echo “judge” page. Keep only elite ones with one click.

-

Clean IPs only

A local IP/CIDR denylist and optional DNSBL zones flag blacklisted addresses before they reach your export.

-

Ranked by real speed

Several attempts per service, median latency, jitter and success rate combined into one quality score.

-

Big lists, stop & resume

Bounded worker queue and rate limiter, tested with 190,000 candidates. Progress lives in SQLite, so stopping never loses work.

-

Ready-to-use exports

TXT, CSV, JSON plus http.txt, https.txt, socks5.txt in plain host:port format for your scraper or browser.

-

Recommended first

Fast proxies that survive re-checks, come from lists with a good record and appear in few lists go to the top: less crowded, so they live longer.

-

Real speed and provider

Optional speed test in Mbit/s; every proxy shows its provider, and hosting or data-centre ranges can be skipped.

-

Built for scrapers

Pick country, protocol and a sticky session in the proxy user name: country-de-session-1. Or script it: proxy-workbench get --top 5.

-

Rotating proxy gateway

Point a browser, Telegram or any app at 127.0.0.1:8899: every connection goes out through the next working proxy, dead ones are skipped.

-

Desktop app

A macOS menu-bar app and a Windows installer. One running instance, optional start at login, correct recovery after sleep.

-

Pools and schedules

Keep N working proxies per profile with a reserve and budgets, and re-check them on a schedule in your time zone with quiet hours.

-

12 languages, new design

English, Russian, Ukrainian, German, Spanish, French, Italian, Portuguese, Polish, Turkish, Japanese and Chinese. Dark and light themes for desktop, tablet and phone.

-

Keys, diagnostics, backups

API keys with permissions and audit, a funnel that explains an empty result, and backups you can preview before restoring.

-

Local API for your code

GET /random?protocol=socks5&country=DE returns a fresh working proxy, so scripts and bots pick one with a single request.

-
-
+
+
+
+

Open source · Runs on your machine

+

Find public proxies.
Verify the ones you use.

+

Collect from supported public sources or bring your own list. Check each proxy against the services you choose, understand the result, then export or connect through a rotating gateway and local API.

+ +
    +
  • HTTP, HTTPS, SOCKS4 & SOCKS5
  • +
  • macOS, Windows, Linux & Docker
  • +
  • 12 interface languages
  • +
+
+
Tour of the Proxy Workbench interface, from scan setup to ranked results and proxy details
+
Interface tour with synthetic proxy data. The app opens in your browser and keeps its data locally.
+
+
-
-

What the anonymity levels mean

-
-
Elite

The site sees neither your IP nor any sign of a proxy.

-
Anonymous

Your IP is hidden, but the proxy announces itself with Via or X-Forwarded-For.

-
Transparent

Your real IP is passed to the site. Avoid these for anything private.

-
-

Your own public IP is learned with one direct request to the judge and kept in memory only. It is never written to the database, exports or logs.

-
+
+
+

A clear path to usable results

+

From a public list to a proxy that passes your checks.

+

You decide what a successful request means. Results keep the evidence behind each decision.

+
+
+
+ +

Choose the sources and targets

+

Use the supported source feeds or import your own lists. Add service URLs and set allowed responses, required text, or a response hash.

+
+
+ +

Run real checks

+

Make repeated requests through candidates, with a threshold for each target. Optional judge and denylist checks add anonymity and IP verdicts.

+
+
+ +

Inspect and use the results

+

See individual attempts, filter and rank the working set, then build files, client configs, a gateway pool, or a fresh local API snapshot.

+
+
+
-
-

Get started in a minute

-
-
1

Download

macOS: the .dmg; Windows: the installer or portable .zip from the latest release, nothing else needed. Anywhere else: pipx install git+https://github.com/DavidVoitenko/proxy-workbench, or Docker Compose.

-
2

Start it

Open the app or run proxy-workbench: the interface opens in your browser, together with the local API and the rotating proxy.

-
3

Check & export

Add your site, press Find and check, then download the best proxies from the Results tab.

-
-

Prefer the terminal or a server?

-
# command line
-./run.sh run --url https://example.org/health --judge-url http://judge.example/azenv.php --min-anonymity elite
+      
+
+

The workspace

+

Every part of the workflow has a place.

+

Eight tabs connect discovery, verification, delivery, and maintenance in the current desktop interface.

+
+
+

Scan

Set service rules and check presets; start, stop, resume, or recheck while watching live progress.

+

Results

Separate fresh, expired, failed, and unknown results. Search, filter, inspect attempts, and build exports.

+

Rotating Gateway

Use one local HTTP or SOCKS5 endpoint for your verified proxies, with connection stats and client setup.

+

Mobile & Clients

Copy or download sing-box and Clash configs, or connect Telegram through the gateway.

+

Sources

Browse 150 catalog entries. Fresh installs select 106 supported feeds; you can add your own lists and manage their scope.

+

Pools & Schedules

Keep a chosen number of working proxies for a profile and schedule checks with time and budget limits.

+

API Keys

Create scoped keys for the control API, with permissions, limits, rotation, and an audit trail.

+

How it works

Follow the built-in guide, review diagnostics, and manage settings, backups, and local data.

+
+
-# Docker (CLI only) -docker build -t proxy-workbench . -docker run --rm --user "$(id -u):$(id -g)" -v "$PWD/data:/app/data" proxy-workbench run --url https://example.org/health
-
+
+
+

Inside the interface

+

See the check. See the reason.

+

Current screens show ranking, source selection, gateway setup, pools, keys, and the evidence behind each check. All examples use synthetic documentation data.

+
+
+
Results screen with synthetic ranked proxies, status groups, filters, and export controls
Results · filter and export the verified set
+
Proxy details showing individual check attempts and their outcomes
Details · inspect why a proxy passed or failed
+
Sources screen with the public feed catalog and controls for custom lists
Sources · choose feeds and bring your own lists
+
Rotating Gateway screen with connection status and client setup options
Gateway · connect clients through one local endpoint
+
Pools and Schedules screen showing pool configuration and a scheduled check
Pools & Schedules · keep a working set fresh
+
API Keys screen with scoped permissions and key management
API Keys · control access to automation
+
+

The pictured addresses come from reserved documentation ranges (RFC 5737); they are examples, not usable public proxies. Availability of real public proxies and feeds changes over time.

+
-
-

Private by design

-
-

Runs locally

The interface listens on 127.0.0.1 only. No accounts, no telemetry, no cloud backend.

-

Hardened fetching

Source downloads are size-limited, redirects are validated and private or metadata IPs are blocked.

-

Honest about limits

It measures availability and latency. A public proxy still sees your traffic, so never send passwords through one.

-
-
+
+
+
+

One checked set, several ways to use it

+

Move from results to your tools.

+

Use an export when you need a file, the gateway when an app needs one proxy address, or the API when your code needs current results.

+
+
    +
  • Exports: TXT, CSV, JSON, PAC, Clash / Mihomo, sing-box, and protocol lists.
  • +
  • Gateway: HTTP and SOCKS5 at 127.0.0.1:8899 while it is running.
  • +
  • Read-only API: /random, /proxies, /status, /pac, and /clash.
  • +
+
+
-
- Proxy Workbench · MIT License · Документация на русском - Issues · Releases +
+
+

Get started

+

Pick the way you want to run it.

+

Desktop builds open the local browser interface. The Python package works across platforms; Docker runs the checker and services without the browser GUI.

+
+
+ + +
Python 3.11+

Linux & other systems

Install with pipx or run from a source checkout; the command opens the local interface.

Read install steps ↗
+
Server & NAS

Docker

Use the bundled Compose setup for the checker, API, and rotating gateway.

Read Docker steps ↗
+
+

Desktop installers are currently unsigned; macOS or Windows may ask you to confirm the first launch. Published release checksums let you verify a download.

+
+ +
+
+

For scripts and services

+

Take a working proxy with one request.

+

The read-only API serves the most recent export on your computer. The separate /v1 control API uses scoped keys for jobs, results, and administration.

+
+
+
+

Local by default

+

While the GUI is open, the read-only endpoint listens on 127.0.0.1:8765. Filter by protocol, country, latency, or anonymity. A network-facing deployment requires a token.

+ Explore the API documentation → +
+
curl "http://127.0.0.1:8765/random?protocol=socks5&country=DE&format=txt"
+
+
+ +
+
+

Control and clarity

+

Know what was measured.

+
+
+

Checks you define

Set target URLs, response rules, attempts, and success thresholds. A reachable proxy is not automatically a match for your service.

+

Evidence you can inspect

View per-attempt outcomes, latency, quality, and optional anonymity or DNSBL verdicts before you export.

+

Data kept local

The GUI runs on loopback, with no account or telemetry. Public proxies can still see your traffic, so avoid sending secrets through them.

+
+
+ +
+
+ -
- diff --git a/packaging/windows-installer.iss b/packaging/windows-installer.iss index 0ea289f..ccf8dd7 100644 --- a/packaging/windows-installer.iss +++ b/packaging/windows-installer.iss @@ -1,6 +1,6 @@ ; Per-user installer for the Windows desktop build. ; -; iscc /DProductVersion=3.0.2 /DOutDir=C:\path\to\dist /DSourceDir=C:\path\to\dist packaging\windows-installer.iss +; iscc /DProductVersion=3.0.3 /DOutDir=C:\path\to\dist /DSourceDir=C:\path\to\dist packaging\windows-installer.iss ; ; PrivilegesRequired=lowest is the whole point: the app writes to per-user ; folders, so it never needs an administrator, and it never installs anything diff --git a/proxy_workbench/branding.py b/proxy_workbench/branding.py index 87d50f4..5ac61d9 100644 --- a/proxy_workbench/branding.py +++ b/proxy_workbench/branding.py @@ -11,7 +11,7 @@ PRODUCT_NAME = "Proxy Workbench" PRODUCT_ID = "ProxyWorkbench" -PRODUCT_VERSION = "3.0.2" +PRODUCT_VERSION = "3.0.3" DEFAULT_REQUEST_PROFILE = "workbench" PROJECT_URL = "https://github.com/DavidVoitenko/proxy-workbench" # Newest built-in source list, fetched only when the user asks for it. This is diff --git a/proxy_workbench/exportsvc.py b/proxy_workbench/exportsvc.py index b710eaa..4dda6ee 100644 --- a/proxy_workbench/exportsvc.py +++ b/proxy_workbench/exportsvc.py @@ -48,7 +48,7 @@ from . import core, formats from .i18n import tr from .proxytool import (PROTOCOL_ALIASES, PROTOCOL_EXPORTS, PROTOCOLS, PROXYCHAINS_TYPES, - proxy_protocol, reputation_status) + proxy_protocol, reputation_status, retry_file_access) __all__ = [ 'ARTIFACT_KINDS', 'CLIENT_BINARY_ENV', 'CLIENT_SIDECAR_NAME', 'CLIENT_TARGET_ENV', 'DIAGNOSTIC_POINTER_NAME', @@ -1488,8 +1488,8 @@ def _atomic_write(path: Path, content: str) -> None: """Replace one file in one step; a reader never sees a half-written pointer.""" path.parent.mkdir(parents=True, exist_ok=True) temporary = path.with_name(path.name + '.tmp') - temporary.write_bytes(content.encode('utf-8')) - os.replace(temporary, path) + retry_file_access(lambda: temporary.write_bytes(content.encode('utf-8'))) + retry_file_access(lambda: os.replace(temporary, path)) def write_snapshot(directory: Any, rows: Sequence[Mapping[str, Any]], *, scope: ExportScope, diff --git a/proxy_workbench/proxytool.py b/proxy_workbench/proxytool.py index 5dd235f..e173ab2 100644 --- a/proxy_workbench/proxytool.py +++ b/proxy_workbench/proxytool.py @@ -560,23 +560,27 @@ def public_url(value): ATOMIC_REPLACE_ATTEMPTS = 40 -def atomic(path, content): - path = Path(path) - path.parent.mkdir(parents=True, exist_ok=True) - temp = path.with_name(path.name + '.tmp') - temp.write_text(content, encoding='utf-8') - # Windows refuses to replace a file another process has open for reading - # (the GUI polls progress while the CLI writes it); such locks are brief. +def retry_file_access(operation): + """Retry a brief Windows file lock without hiding a persistent I/O error.""" for attempt in range(ATOMIC_REPLACE_ATTEMPTS): try: - temp.replace(path) - return + return operation() except PermissionError: if attempt == ATOMIC_REPLACE_ATTEMPTS - 1: raise time.sleep(0.05) +def atomic(path, content): + path = Path(path) + path.parent.mkdir(parents=True, exist_ok=True) + temp = path.with_name(path.name + '.tmp') + retry_file_access(lambda: temp.write_text(content, encoding='utf-8')) + # Windows refuses to replace a file another process has open for reading + # (the GUI polls progress while the CLI writes it); such locks are brief. + retry_file_access(lambda: temp.replace(path)) + + EXPORT_GENERATION_RETENTION = 3 SNAPSHOT_SCHEMA_VERSION = 1 MIN_FRESHNESS_SECONDS = 2 * 60 * 60 @@ -758,21 +762,21 @@ def _publish_legacy_files(directory, generation, names, report, before_commit=No for name in legacy_names: source = generation/name temporary = directory/(name+'.publish-tmp') - temporary.unlink(missing_ok=True) + retry_file_access(lambda: temporary.unlink(missing_ok=True)) if name == 'status.json': - temporary.write_text(json.dumps(report, indent=2) + '\n', encoding='utf-8') + retry_file_access(lambda: temporary.write_text(json.dumps(report, indent=2) + '\n', encoding='utf-8')) else: - shutil.copyfile(source, temporary) + retry_file_access(lambda: shutil.copyfile(source, temporary)) staged[name] = temporary for name in legacy_names: target = directory/name if target.exists() or target.is_symlink(): backup = directory/('.'+name+'.publish-backup') - backup.unlink(missing_ok=True) - target.replace(backup) + retry_file_access(lambda: backup.unlink(missing_ok=True)) + retry_file_access(lambda: target.replace(backup)) backups[name] = backup for name, temporary in staged.items(): - temporary.replace(directory/name) + retry_file_access(lambda: temporary.replace(directory/name)) installed.append(directory/name) if before_commit is not None: before_commit() @@ -782,7 +786,7 @@ def _publish_legacy_files(directory, generation, names, report, before_commit=No path.unlink() for name, backup in reversed(list(backups.items())): with contextlib.suppress(OSError): - backup.replace(directory/name) + retry_file_access(lambda: backup.replace(directory/name)) raise finally: for temporary in staged.values(): diff --git a/proxy_workbench/ui/app.js b/proxy_workbench/ui/app.js index be644a3..7047a7e 100644 --- a/proxy_workbench/ui/app.js +++ b/proxy_workbench/ui/app.js @@ -125,7 +125,7 @@ const messages = { 'identity.denylist': 'Local denylist', 'identity.local': 'Local denylist', 'identity.localHint': 'IPs or CIDR blocks permanently excluded from tests and exports.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# comment', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# comment', 'identity.denylistHint': 'IP, CIDR or exact proxy address. Stored only in data/denylist.txt and never included in the code.', 'identity.applyDenylist': 'Apply the local denylist during collection, checks and export', 'profile.workbench': 'Workbench profile', @@ -1426,7 +1426,7 @@ const messages = { 'identity.denylist': 'Локальный denylist', 'identity.local': 'Локальный denylist', 'identity.localHint': 'IP и CIDR, навсегда исключённые из проверок и экспорта.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# комментарий', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# комментарий', 'identity.denylistHint': 'IP, CIDR или точный адрес прокси. Хранится только в data/denylist.txt и не включается в код.', 'identity.applyDenylist': 'Применять локальный denylist при сборе, проверке и экспорте', 'profile.workbench': 'Рабочий профиль', @@ -5143,8 +5143,8 @@ function updateSelectionUI() { if (bar) { const hasRows = document.querySelectorAll('.proxy-select-box').length > 0; - // The bar is also the only home of the bulk-scope selector: keep it visible - // on a non-empty table even with nothing ticked, hiding selection-only controls. + // The bar is also the only home of the bulk-scope selector. With no rows + // selected, CSS keeps it in the page flow instead of covering table rows. const isVisible = count > 0 || (currentTab === 'results' && hasRows); bar.classList.toggle('hidden', !isVisible); bar.classList.toggle('active', isVisible); diff --git a/proxy_workbench/ui/i18n/de.js b/proxy_workbench/ui/i18n/de.js index e5dff49..b0b5416 100644 --- a/proxy_workbench/ui/i18n/de.js +++ b/proxy_workbench/ui/i18n/de.js @@ -102,7 +102,7 @@ 'identity.denylist': 'Lokale Sperrliste', 'identity.local': 'Lokale Sperrliste', 'identity.localHint': 'IPs oder CIDR-Blöcke, die dauerhaft von Tests und Exporten ausgeschlossen sind.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# Kommentar', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# Kommentar', 'identity.denylistHint': 'IP, CIDR oder exakte Proxy-Adresse. Wird nur in data/denylist.txt gespeichert und nie im Code mitgeliefert.', 'identity.applyDenylist': 'Lokale Sperrliste bei Erfassung, Prüfungen und Export anwenden', 'profile.workbench': 'Workbench-Profil', diff --git a/proxy_workbench/ui/i18n/es.js b/proxy_workbench/ui/i18n/es.js index a6f967f..4b9de82 100644 --- a/proxy_workbench/ui/i18n/es.js +++ b/proxy_workbench/ui/i18n/es.js @@ -102,7 +102,7 @@ 'identity.denylist': 'Lista de bloqueo local', 'identity.local': 'Lista de bloqueo local', 'identity.localHint': 'IP o bloques CIDR excluidos permanentemente de las pruebas y las exportaciones.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# comentario', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# comentario', 'identity.denylistHint': 'IP, CIDR o dirección exacta de proxy. Se guarda solo en data/denylist.txt y nunca se incluye en el código.', 'identity.applyDenylist': 'Aplicar la lista de bloqueo local durante la recopilación, las comprobaciones y la exportación', 'profile.workbench': 'Perfil Workbench', diff --git a/proxy_workbench/ui/i18n/fr.js b/proxy_workbench/ui/i18n/fr.js index c4fa8fe..5ec6475 100644 --- a/proxy_workbench/ui/i18n/fr.js +++ b/proxy_workbench/ui/i18n/fr.js @@ -102,7 +102,7 @@ 'identity.denylist': 'Liste d\'exclusion locale', 'identity.local': 'Liste d\'exclusion locale', 'identity.localHint': 'IP ou blocs CIDR exclus définitivement des tests et des exports.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# commentaire', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# commentaire', 'identity.denylistHint': 'IP, CIDR ou adresse de proxy exacte. Stocké uniquement dans data/denylist.txt et jamais inclus dans le code.', 'identity.applyDenylist': 'Appliquer la liste d\'exclusion locale pendant la collecte, les vérifications et l\'export', 'profile.workbench': 'Profil Workbench', diff --git a/proxy_workbench/ui/i18n/it.js b/proxy_workbench/ui/i18n/it.js index 081094e..30fe136 100644 --- a/proxy_workbench/ui/i18n/it.js +++ b/proxy_workbench/ui/i18n/it.js @@ -102,7 +102,7 @@ 'identity.denylist': 'Lista di esclusione locale', 'identity.local': 'Lista di esclusione locale', 'identity.localHint': 'IP o blocchi CIDR esclusi in modo permanente da test ed esportazioni.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# commento', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# commento', 'identity.denylistHint': 'IP, CIDR o indirizzo proxy esatto. Salvato solo in data/denylist.txt e mai incluso nel codice.', 'identity.applyDenylist': 'Applica la lista di esclusione locale durante raccolta, verifiche ed esportazione', 'profile.workbench': 'Profilo Workbench', diff --git a/proxy_workbench/ui/i18n/ja.js b/proxy_workbench/ui/i18n/ja.js index 940aa6a..4c47937 100644 --- a/proxy_workbench/ui/i18n/ja.js +++ b/proxy_workbench/ui/i18n/ja.js @@ -102,7 +102,7 @@ 'identity.denylist': 'ローカル拒否リスト', 'identity.local': 'ローカル拒否リスト', 'identity.localHint': 'テストとエクスポートから恒久的に除外するIPまたはCIDRブロック。', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# コメント', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# コメント', 'identity.denylistHint': 'IP、CIDRまたは正確なプロキシアドレス。data/denylist.txt のみに保存され、コードには含まれません。', 'identity.applyDenylist': '収集・チェック・エクスポート時にローカル拒否リストを適用する', 'profile.workbench': 'Workbenchプロファイル', diff --git a/proxy_workbench/ui/i18n/pl.js b/proxy_workbench/ui/i18n/pl.js index fd169bd..ac50ffc 100644 --- a/proxy_workbench/ui/i18n/pl.js +++ b/proxy_workbench/ui/i18n/pl.js @@ -102,7 +102,7 @@ 'identity.denylist': 'Lokalna lista blokowania', 'identity.local': 'Lokalna lista blokowania', 'identity.localHint': 'Adresy IP lub bloki CIDR trwale wykluczone z testów i eksportów.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# komentarz', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# komentarz', 'identity.denylistHint': 'IP, CIDR lub dokładny adres proxy. Zapisywane tylko w data/denylist.txt i nigdy nie dołączane do kodu.', 'identity.applyDenylist': 'Stosuj lokalną listę blokowania podczas zbierania, sprawdzania i eksportu', 'profile.workbench': 'Profil Workbench', diff --git a/proxy_workbench/ui/i18n/pt.js b/proxy_workbench/ui/i18n/pt.js index 3fbba37..9ecaf5a 100644 --- a/proxy_workbench/ui/i18n/pt.js +++ b/proxy_workbench/ui/i18n/pt.js @@ -102,7 +102,7 @@ 'identity.denylist': 'Lista de bloqueio local', 'identity.local': 'Lista de bloqueio local', 'identity.localHint': 'IPs ou blocos CIDR permanentemente excluídos dos testes e exportações.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# comentário', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# comentário', 'identity.denylistHint': 'IP, CIDR ou endereço exato de proxy. Armazenado apenas em data/denylist.txt e nunca incluído no código.', 'identity.applyDenylist': 'Aplicar a lista de bloqueio local durante coleta, verificações e exportação', 'profile.workbench': 'Perfil Workbench', diff --git a/proxy_workbench/ui/i18n/tr.js b/proxy_workbench/ui/i18n/tr.js index fd2e076..812ed36 100644 --- a/proxy_workbench/ui/i18n/tr.js +++ b/proxy_workbench/ui/i18n/tr.js @@ -102,7 +102,7 @@ 'identity.denylist': 'Yerel engel listesi', 'identity.local': 'Yerel engel listesi', 'identity.localHint': 'Testlerden ve dışa aktarmalardan kalıcı olarak hariç tutulan IP\'ler veya CIDR blokları.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# yorum', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# yorum', 'identity.denylistHint': 'IP, CIDR veya tam proxy adresi. Yalnızca data/denylist.txt içinde saklanır ve asla koda dahil edilmez.', 'identity.applyDenylist': 'Toplama, kontroller ve dışa aktarma sırasında yerel engel listesini uygula', 'profile.workbench': 'Workbench profili', diff --git a/proxy_workbench/ui/i18n/uk.js b/proxy_workbench/ui/i18n/uk.js index 8fd094f..ebed8d1 100644 --- a/proxy_workbench/ui/i18n/uk.js +++ b/proxy_workbench/ui/i18n/uk.js @@ -102,7 +102,7 @@ 'identity.denylist': 'Локальний чорний список', 'identity.local': 'Локальний чорний список', 'identity.localHint': 'IP або CIDR-блоки, назавжди виключені з тестів та експортів.', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# коментар', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# коментар', 'identity.denylistHint': 'IP, CIDR або точна адреса проксі. Зберігається лише в data/denylist.txt і ніколи не включається в код.', 'identity.applyDenylist': 'Застосовувати локальний чорний список під час збору, перевірок та експорту', 'profile.workbench': 'Профіль Workbench', diff --git a/proxy_workbench/ui/i18n/zh.js b/proxy_workbench/ui/i18n/zh.js index ed5cb04..50b6ae2 100644 --- a/proxy_workbench/ui/i18n/zh.js +++ b/proxy_workbench/ui/i18n/zh.js @@ -102,7 +102,7 @@ 'identity.denylist': '本地黑名单', 'identity.local': '本地黑名单', 'identity.localHint': '永久排除在检测和导出之外的 IP 或 CIDR 网段。', - 'identity.denylistPlaceholder': '11.0.0.0/24\nhttp://11.0.0.1:8080\n# comment', + 'identity.denylistPlaceholder': '192.0.2.0/24\nhttp://192.0.2.10:8080\n# comment', 'identity.denylistHint': 'IP、CIDR 或精确代理地址。仅存储在 data/denylist.txt 中,绝不写入代码。', 'identity.applyDenylist': '在采集、检测和导出时应用本地黑名单', 'profile.workbench': 'Workbench 方案', diff --git a/proxy_workbench/ui/index.html b/proxy_workbench/ui/index.html index b250691..3406cd6 100644 --- a/proxy_workbench/ui/index.html +++ b/proxy_workbench/ui/index.html @@ -989,36 +989,6 @@

Proxy ranking

- - - + + + + @@ -1474,7 +1475,7 @@

Add your own list

- +