A desktop tool for downloading files from "Index of" directory listing pages. Scan a website, browse its file tree, filter by type, and download what you need.
- Recursive directory scanning with pause/resume
- File tree with expand/collapse, search, and type filtering
- Multi-threaded downloads (1-10 concurrent) with per-file progress
- Pause/resume/cancel individual downloads
- Automatic retry on server errors (3 attempts, exponential backoff)
- Preserves original directory structure
- Multi-site task queue (Electron) — scan/download multiple sites in tabs
- File preview (images + text) via double-click (Electron)
- Shift+click range selection and sort by name/size/type (Electron)
- Dark mode UI
| Python (CustomTkinter) | Electron (React + TypeScript) | |
|---|---|---|
| Location | src/index_ripper/ |
electron-app/ |
| UI | CustomTkinter with emoji icons | React + Tailwind + shadcn/ui |
| Backend | Python requests + BeautifulSoup | Node.js http + cheerio |
| Multi-site tabs | No | Yes |
| File preview | No | Yes (images + text) |
| Build | PyInstaller | electron-builder |
cd electron-app
npm install
npm run dev# Install uv (one-time)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install and run
uv sync
uv run python -m index_ripperDownload from Releases or CI Artifacts:
| Platform | Electron | Python |
|---|---|---|
| Windows | .exe (NSIS installer) |
.exe (PyInstaller) |
| macOS | .dmg (Universal) |
.app |
| Linux | .AppImage |
Binary |
macOS note: The app is unsigned. First launch: right-click -> Open, or run
xattr -dr com.apple.quarantine IndexRipper.app.
- Enter a URL pointing to an "Index of" directory listing
- Click Scan to discover files and directories
- Browse the file tree, filter by type, search by name
- Select files (click, Shift+click for range, Ctrl+A for all)
- Click Download to start downloading
| Shortcut | Action |
|---|---|
Ctrl/Cmd + F |
Focus search |
Ctrl/Cmd + A |
Select all files |
Escape |
Clear search |
Enter |
Start scan (when URL input focused) |
| Double-click | Preview file (Electron) |
cd electron-app
npm install
# Development
npm run dev
# Build for current platform
npm run build:mac # macOS .dmg
npm run build:win # Windows .exe
npm run build:linux # Linux .AppImageuv sync
uv pip install pyinstaller
# macOS
uv run pyinstaller -F --windowed --name=IndexRipper \
--collect-all customtkinter --icon=app.png --paths src src/index_ripper/__main__.py
# Windows
uv run pyinstaller --onefile --windowed --icon=app.png --name=IndexRipper \
--collect-all customtkinter --paths src src/index_ripper/__main__.py
# Linux
uv run pyinstaller --onefile --windowed --name=IndexRipper \
--collect-all customtkinter --icon=app.png --paths src src/index_ripper/__main__.pyIndex-Ripper/
├── electron-app/ # Electron version
│ ├── src/main/ # Main process (scanner, downloader, IPC)
│ ├── src/renderer/ # React UI
│ ├── src/shared/ # Shared types
│ └── src/preload/ # Context bridge
├── src/index_ripper/ # Python version
│ ├── app.py # Main UI (CustomTkinter)
│ ├── backend.py # Scanner & downloader
│ └── ui/ # UI components
├── tests/ # Python tests
└── docs/ # Design specs & plans
- Fork the repo
- Create a feature branch (
git checkout -b feat/my-feature) - Commit your changes
- Push and open a Pull Request