idm-cli 1.3.1__tar.gz → 1.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- idm_cli-1.3.4/CHANGELOG.md +113 -0
- idm_cli-1.3.4/MANIFEST.in +2 -0
- {idm_cli-1.3.1/idm_cli.egg-info → idm_cli-1.3.4}/PKG-INFO +211 -170
- {idm_cli-1.3.1 → idm_cli-1.3.4}/README.md +59 -18
- idm_cli-1.3.4/idm_cli/__init__.py +3 -0
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli/__main__.py +4 -4
- idm_cli-1.3.4/idm_cli/config.py +171 -0
- idm_cli-1.3.4/idm_cli/downloader/core.py +429 -0
- idm_cli-1.3.4/idm_cli/downloader/downloader.py +487 -0
- idm_cli-1.3.4/idm_cli/downloader/handlers.py +261 -0
- idm_cli-1.3.4/idm_cli/downloader/muxer.py +291 -0
- idm_cli-1.3.4/idm_cli/downloader/state.py +125 -0
- idm_cli-1.3.4/idm_cli/extractors/__init__.py +42 -0
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli/extractors/direct.py +30 -19
- idm_cli-1.3.4/idm_cli/extractors/winget.py +107 -0
- idm_cli-1.3.4/idm_cli/extractors/ytdlp.py +195 -0
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli/ui/cli.py +291 -206
- idm_cli-1.3.4/idm_cli/ui/progress.py +245 -0
- idm_cli-1.3.4/idm_cli/ui/prompts.py +364 -0
- idm_cli-1.3.4/idm_cli/ui/utils.py +236 -0
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli/update_checker.py +84 -74
- {idm_cli-1.3.1 → idm_cli-1.3.4/idm_cli.egg-info}/PKG-INFO +211 -170
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli.egg-info/SOURCES.txt +9 -4
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli.egg-info/requires.txt +3 -3
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli.egg-info/top_level.txt +0 -1
- idm_cli-1.3.4/pyproject.toml +63 -0
- {idm_cli-1.3.1 → idm_cli-1.3.4}/setup.cfg +4 -4
- idm_cli-1.3.4/tests/test_core.py +129 -0
- idm_cli-1.3.4/tests/test_core_handlers.py +267 -0
- idm_cli-1.3.4/tests/test_extractor_fixes.py +214 -0
- idm_cli-1.3.4/tests/test_muxer.py +121 -0
- idm_cli-1.3.4/tests/test_progress_update.py +124 -0
- idm_cli-1.3.4/tests/test_regressions.py +422 -0
- idm_cli-1.3.1/MANIFEST.in +0 -1
- idm_cli-1.3.1/idm_cli/__init__.py +0 -3
- idm_cli-1.3.1/idm_cli/config.py +0 -85
- idm_cli-1.3.1/idm_cli/downloader/core.py +0 -317
- idm_cli-1.3.1/idm_cli/downloader/downloader.py +0 -293
- idm_cli-1.3.1/idm_cli/downloader/handlers.py +0 -195
- idm_cli-1.3.1/idm_cli/downloader/muxer.py +0 -174
- idm_cli-1.3.1/idm_cli/downloader/state.py +0 -62
- idm_cli-1.3.1/idm_cli/extractors/__init__.py +0 -18
- idm_cli-1.3.1/idm_cli/extractors/winget.py +0 -76
- idm_cli-1.3.1/idm_cli/extractors/ytdlp.py +0 -139
- idm_cli-1.3.1/idm_cli/ui/utils.py +0 -153
- idm_cli-1.3.1/pyproject.toml +0 -45
- idm_cli-1.3.1/requirements.txt +0 -11
- idm_cli-1.3.1/setup.py +0 -44
- idm_cli-1.3.1/tests/__init__.py +0 -0
- idm_cli-1.3.1/tests/test_core.py +0 -76
- {idm_cli-1.3.1 → idm_cli-1.3.4}/LICENSE +0 -0
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli/downloader/__init__.py +0 -0
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli/ui/__init__.py +0 -0
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli.egg-info/dependency_links.txt +0 -0
- {idm_cli-1.3.1 → idm_cli-1.3.4}/idm_cli.egg-info/entry_points.txt +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to IDM-CLI are documented here.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- README "Security" section documenting what IDM-CLI does and does not protect
|
|
10
|
+
against (it is a download manager, not an antivirus).
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **UI palette reduced to two colours (cyan + white).** Status meaning is now
|
|
15
|
+
carried by a leading glyph instead of colour: `✓` success, `✗` error/cancel,
|
|
16
|
+
`•` neutral info, `»` an action starting, `‖` paused.
|
|
17
|
+
- **Version is now single-sourced.** `pyproject.toml` reads `__version__` from
|
|
18
|
+
`idm_cli/__init__.py` instead of repeating it, so the package and the
|
|
19
|
+
metadata can no longer disagree.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **Automated releases.** Pushing a `v*` tag runs `.github/workflows/release.yml`,
|
|
24
|
+
which builds, validates, and publishes to PyPI via Trusted Publishing (OIDC).
|
|
25
|
+
The workflow refuses to publish when the tag and the packaged version differ.
|
|
26
|
+
|
|
27
|
+
## [1.3.4] - 2026-10-11
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **Downloads failed with HTTP 403** on servers that reject the impersonated
|
|
32
|
+
Chrome User-Agent: chunks now retry with a fallback User-Agent.
|
|
33
|
+
- **Resume broke for direct files**: the extractor was resolved twice, and the
|
|
34
|
+
flaky network probe could return a different extractor the second time
|
|
35
|
+
("did not provide a downloadable URL"). The extractor is now resolved once and
|
|
36
|
+
reused; saved direct-file tasks never re-probe.
|
|
37
|
+
- **FFmpeg muxing failed (exit 234)**: the temp output kept a `.part` extension,
|
|
38
|
+
so ffmpeg could not infer the container format. The temp file now preserves
|
|
39
|
+
the real extension and is renamed atomically.
|
|
40
|
+
- **Quality menu never appeared**: the default YouTube player clients exposed
|
|
41
|
+
only 360p, so a single "resolution" auto-selected silently. The extractor now
|
|
42
|
+
tries several clients and keeps the one with the most resolutions
|
|
43
|
+
(1080p/720p/... when available).
|
|
44
|
+
- **Non-TTY crash**: `check_key_press()` raised `termios.error` (not an
|
|
45
|
+
`OSError`) when stdin was a pipe/file, killing downloads in scripts/CI.
|
|
46
|
+
- Corrupted resume metadata no longer aborts the download; it resets the chunk.
|
|
47
|
+
- `0`-byte files and `bool` chunk counts are handled correctly.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- Interactive runs now prompt for quality whenever a real terminal is available
|
|
52
|
+
(previously `idm <url>` silently used the configured default). The configured
|
|
53
|
+
default is marked `(default)` and pre-selected; `-q`/`-a` still skip the prompt.
|
|
54
|
+
- FFmpeg failures now show a short, single-line message; the full ffmpeg output
|
|
55
|
+
goes to the log file only.
|
|
56
|
+
|
|
57
|
+
### Security
|
|
58
|
+
|
|
59
|
+
- SSRF: `is_valid_url()` now rejects private/loopback/link-local/reserved hosts
|
|
60
|
+
(localhost, 127.0.0.1, 10/8, 192.168/16, 169.254.169.254, IPv6 equivalents).
|
|
61
|
+
- Rich markup injection: user- and metadata-controlled strings are escaped.
|
|
62
|
+
|
|
63
|
+
### Tests and CI
|
|
64
|
+
|
|
65
|
+
- Test suite grew from 15 to 69 tests (muxer, progress, extractors, core/handlers,
|
|
66
|
+
quality-prompt behaviour, SSRF, muxing regressions).
|
|
67
|
+
|
|
68
|
+
## [1.3.3] - 2026-09-06
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
|
|
72
|
+
- Validate ranged HTTP responses and received byte counts to prevent corrupted downloads.
|
|
73
|
+
- Prevent existing files from being treated as complete when the server cannot be checked.
|
|
74
|
+
- Avoid buffering an entire file during range capability detection.
|
|
75
|
+
- Validate resume metadata and make state updates safe across processes.
|
|
76
|
+
- Prevent direct-file audio-only downloads from reporting a false success.
|
|
77
|
+
- Handle small-file chunk partitioning and non-TTY input safely.
|
|
78
|
+
- Prevent temporary-file collisions and accidental output overwrites.
|
|
79
|
+
- Make FFmpeg post-processing output atomic.
|
|
80
|
+
- Harden filenames and escape user-controlled terminal output.
|
|
81
|
+
- Stop implicit browser-cookie access during yt-dlp fallback.
|
|
82
|
+
|
|
83
|
+
### Security
|
|
84
|
+
|
|
85
|
+
- Verify downloaded FFmpeg archives against the SHA-256 digest published by GitHub Releases.
|
|
86
|
+
- Added a security reporting policy in `SECURITY.md`.
|
|
87
|
+
|
|
88
|
+
### Tests and CI
|
|
89
|
+
|
|
90
|
+
- Added regression tests for configuration validation, filename safety, and direct extractors.
|
|
91
|
+
- Added coverage reporting to GitHub Actions.
|
|
92
|
+
|
|
93
|
+
## [1.3.0]
|
|
94
|
+
|
|
95
|
+
### Added
|
|
96
|
+
|
|
97
|
+
- URL validation for HTTP/HTTPS sources.
|
|
98
|
+
- Atomic download state persistence.
|
|
99
|
+
- Queue locking and safer Winget command execution.
|
|
100
|
+
- Improved retry handling and resume support.
|
|
101
|
+
|
|
102
|
+
### Security
|
|
103
|
+
|
|
104
|
+
- Removed unsafe command execution paths and machine-specific configuration from the repository.
|
|
105
|
+
|
|
106
|
+
## [1.2.2]
|
|
107
|
+
|
|
108
|
+
### Fixed
|
|
109
|
+
|
|
110
|
+
- Improved resume reliability after interrupted downloads.
|
|
111
|
+
- Improved recovery from throttling and silent network disconnects.
|
|
112
|
+
- Added faster automatic FFmpeg download support.
|
|
113
|
+
- Added Winget-based FFmpeg installation on Windows.
|
|
@@ -1,170 +1,211 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: idm-cli
|
|
3
|
-
Version: 1.3.
|
|
4
|
-
Summary: A lightning-fast, universal command-line download manager
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Project-URL:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Classifier:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist: psutil
|
|
25
|
-
Requires-Dist: platformdirs
|
|
26
|
-
Provides-Extra: dev
|
|
27
|
-
Requires-Dist: pytest; extra == "dev"
|
|
28
|
-
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Dynamic:
|
|
33
|
-
|
|
34
|
-
<div align="center">
|
|
35
|
-
|
|
36
|
-
<h1>IDM-CLI</h1>
|
|
37
|
-
|
|
38
|
-
**A lightning-fast,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
[](https://pypi.org/project/idm-cli/)
|
|
41
|
+
[](https://pepy.tech/project/idm-cli)
|
|
42
|
+
[](https://github.com/rj41-w2/idm-cli/blob/main/LICENSE)
|
|
43
|
+

|
|
44
|
+
[](https://pypi.org/project/idm-cli/)
|
|
45
|
+
|
|
46
|
+
[Download via PyPI](https://pypi.org/project/idm-cli/) · [Report a Bug](https://github.com/rj41-w2/idm-cli/issues)
|
|
47
|
+
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
IDM-CLI splits files into multiple parallel chunks (default 8, up to 32) to maximize your internet speed. It supports downloading from **YouTube**, **Facebook**, **Instagram**, and any **Direct File URL** (`.exe`, `.zip`, `.pdf`, etc.).
|
|
51
|
+
|
|
52
|
+
## Features
|
|
53
|
+
|
|
54
|
+
- **Parallel Chunk Engine** — Splits downloads into multiple concurrent chunks using `curl-cffi` async sessions to fully saturate your bandwidth.
|
|
55
|
+
- **Universal Downloader** — Paste any URL. yt-dlp handles 1000+ sites (YouTube, Facebook, Instagram, etc.), with automatic fallback to direct HTTP download for unsupported URLs.
|
|
56
|
+
- **Audio Only / MP3 Conversion** — Download videos as audio. IDM-CLI automatically grabs the best audio stream and uses FFmpeg to convert it to `.mp3`.
|
|
57
|
+
- **Smart Auto-Resume** — Internet dropped? Pressed `Ctrl+C`? No problem. IDM-CLI remembers the exact byte positions of all incomplete chunks. Paste the same link again to resume instantly.
|
|
58
|
+
- **Persistent Queue System** — Add multiple files to a queue with `-Q` and type `start queue` to download them all sequentially.
|
|
59
|
+
- **Interactive UI** — Modern terminal interface powered by `rich` and `questionary` with real-time speed, ETA, and progress bars. Press `p` to pause, `r` to resume.
|
|
60
|
+
- **Cross-Platform** — Works on Windows, macOS, and Linux with platform-specific FFmpeg handling.
|
|
61
|
+
- **Auto-Update Check** — Checks PyPI once a day and notifies you when a new version is available.
|
|
62
|
+
|
|
63
|
+
## Security
|
|
64
|
+
|
|
65
|
+
**IDM-CLI is a download manager, not an antivirus.** It does not scan files for
|
|
66
|
+
malware — no signature database, no heuristic engine. Downloading a file that
|
|
67
|
+
contains malware will not trigger any warning from IDM-CLI itself.
|
|
68
|
+
|
|
69
|
+
What IDM-CLI does give you:
|
|
70
|
+
|
|
71
|
+
- **SSRF protection** — URLs pointing at private/loopback/link-local hosts
|
|
72
|
+
(`localhost`, `127.0.0.1`, `10.x`, `192.168.x`, `169.254.169.254`, …) are
|
|
73
|
+
rejected, so a crafted link cannot make IDM-CLI probe your internal network.
|
|
74
|
+
- **No shell execution** — all `subprocess` calls use `shell=False` with
|
|
75
|
+
argument lists; no URL or title ever reaches a shell.
|
|
76
|
+
- **Verified FFmpeg download** — when IDM-CLI auto-installs FFmpeg, the archive
|
|
77
|
+
is checked against the SHA-256 digest published by GitHub Releases.
|
|
78
|
+
|
|
79
|
+
**How to stay safe:** rely on your operating system's antivirus, which scans
|
|
80
|
+
files as they land on disk.
|
|
81
|
+
|
|
82
|
+
- **Windows:** Windows Defender real-time protection scans WSL paths
|
|
83
|
+
(`\\wsl.localhost\...`) automatically — nothing to configure.
|
|
84
|
+
- **Linux:** install ClamAV (`sudo apt install clamav`), keep the signature
|
|
85
|
+
database current (`sudo freshclam`), and scan a download with
|
|
86
|
+
`clamscan ~/Downloads/file`. Add a cron job or an inotify watcher to scan
|
|
87
|
+
automatically.
|
|
88
|
+
|
|
89
|
+
This mirrors how the official Internet Download Manager behaves: IDM does not
|
|
90
|
+
detect malware either — it can be configured (Options → Downloads → Virus
|
|
91
|
+
checking) to call an installed antivirus after a download finishes, and
|
|
92
|
+
otherwise relies on the antivirus's real-time protection.
|
|
93
|
+
|
|
94
|
+
## Prerequisites
|
|
95
|
+
|
|
96
|
+
- **Python 3.8+**
|
|
97
|
+
- **FFmpeg** — Required for muxing video and audio streams, and converting to `.mp3`. IDM-CLI can auto-download it for you, or you can install it manually:
|
|
98
|
+
- Windows: `winget install ffmpeg`
|
|
99
|
+
- macOS: `brew install ffmpeg`
|
|
100
|
+
- Linux: `sudo apt install ffmpeg`
|
|
101
|
+
|
|
102
|
+
## Installation
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# From PyPI
|
|
106
|
+
pip install idm-cli
|
|
107
|
+
|
|
108
|
+
# From source
|
|
109
|
+
git clone https://github.com/rj41-w2/idm-cli.git
|
|
110
|
+
cd idm-cli
|
|
111
|
+
pip install -e ".[dev]"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Usage
|
|
115
|
+
|
|
116
|
+
Run the app interactively:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
idm
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
This opens a prompt where you can paste your link, select video quality, or queue the download.
|
|
123
|
+
|
|
124
|
+
### CLI Flags (Fast Mode)
|
|
125
|
+
|
|
126
|
+
Skip the interactive menus by passing arguments directly:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Download a video at 1080p
|
|
130
|
+
idm "https://youtube.com/watch?v=..." -q 1080p -v
|
|
131
|
+
|
|
132
|
+
# Audio only (converts to MP3)
|
|
133
|
+
idm "https://youtube.com/watch?v=..." -a
|
|
134
|
+
|
|
135
|
+
# 16 parallel chunks for maximum speed
|
|
136
|
+
idm "https://example.com/largefile.zip" -c 16
|
|
137
|
+
|
|
138
|
+
# Add to queue
|
|
139
|
+
idm "https://facebook.com/..." -Q
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
| Flag | Description |
|
|
143
|
+
|------|-------------|
|
|
144
|
+
| `-q <resolution>` | Set video quality (e.g., `1080p`, `720p`) |
|
|
145
|
+
| `-a` | Audio only — download and convert to MP3 |
|
|
146
|
+
| `-v` | Download video + audio (bypasses quality prompt) |
|
|
147
|
+
| `-Q` | Add to queue instead of downloading immediately |
|
|
148
|
+
| `-c <num>` | Number of parallel chunks (default: 8) |
|
|
149
|
+
| `-f <filename>` | Force a custom output filename |
|
|
150
|
+
|
|
151
|
+
### Interactive Commands
|
|
152
|
+
|
|
153
|
+
| Command | Description |
|
|
154
|
+
|---------|-------------|
|
|
155
|
+
| `<URL>` | Download a video or file |
|
|
156
|
+
| `resume` | Resume or delete incomplete downloads |
|
|
157
|
+
| `start queue` | Process all queued downloads |
|
|
158
|
+
| `help` | Show available commands and flags |
|
|
159
|
+
| `exit` | Exit the application |
|
|
160
|
+
|
|
161
|
+
### Troubleshooting: Windows Device Guard
|
|
162
|
+
|
|
163
|
+
If you get `"idm.exe was blocked by your organization's Device Guard policy"`, run the Python module directly:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
python -m idm_cli
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Architecture
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
idm_cli/
|
|
173
|
+
├── __init__.py # Package version
|
|
174
|
+
├── __main__.py # python -m idm_cli entry point
|
|
175
|
+
├── config.py # Platform-aware config, logging, and paths
|
|
176
|
+
├── update_checker.py # PyPI version check
|
|
177
|
+
├── ui/
|
|
178
|
+
│ ├── cli.py # Typer entry point and interactive command loop
|
|
179
|
+
│ ├── prompts.py # Questionary prompts and user-facing messages
|
|
180
|
+
│ ├── progress.py # Rich progress display and pause/resume controls
|
|
181
|
+
│ └── utils.py # URL validation, filename safety, and terminal helpers
|
|
182
|
+
├── downloader/
|
|
183
|
+
│ ├── core.py # Download orchestration and destination management
|
|
184
|
+
│ ├── downloader.py # Async ranged downloads, retries, and resume validation
|
|
185
|
+
│ ├── handlers.py # Queue & resume handlers
|
|
186
|
+
│ ├── muxer.py # FFmpeg verification, muxing, and conversion
|
|
187
|
+
│ └── state.py # Locked, atomic JSON state persistence
|
|
188
|
+
└── extractors/
|
|
189
|
+
├── __init__.py # Direct HTTP probe and extractor selection
|
|
190
|
+
├── ytdlp.py # YouTube/social media extractor
|
|
191
|
+
├── direct.py # Direct HTTP file metadata and URL extraction
|
|
192
|
+
└── winget.py # Windows Package Manager metadata extraction
|
|
193
|
+
|
|
194
|
+
tests/ # pytest suite (runs fully offline)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The download flow is: `core.py` selects the extractor and prepares the
|
|
198
|
+
destination and media pipeline, `downloader.py` downloads validated byte ranges,
|
|
199
|
+
`progress.py` renders live progress, and `muxer.py` creates the final media file.
|
|
200
|
+
Interrupted downloads are tracked under the platform-specific application data
|
|
201
|
+
directory, not inside the repository.
|
|
202
|
+
|
|
203
|
+
## Contributing
|
|
204
|
+
|
|
205
|
+
Contributions are welcome. Fork the repo, make your changes on a feature branch, and open a PR against `main`. Keep changes focused and follow the existing code style.
|
|
206
|
+
|
|
207
|
+
For bug reports and feature requests, [open an issue](https://github.com/rj41-w2/idm-cli/issues).
|
|
208
|
+
|
|
209
|
+
## License
|
|
210
|
+
|
|
211
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<h1>IDM-CLI</h1>
|
|
4
4
|
|
|
5
|
-
**A lightning-fast,
|
|
6
|
-
|
|
7
|
-
*The official IDM asks you to pay after 30 days — IDM-CLI is 100% free, open-source, and yours to modify!*
|
|
5
|
+
**A lightning-fast, universal command-line download manager written in Python.**
|
|
8
6
|
|
|
9
7
|
[](https://pypi.org/project/idm-cli/)
|
|
10
8
|
[](https://pepy.tech/project/idm-cli)
|
|
@@ -20,7 +18,7 @@ IDM-CLI splits files into multiple parallel chunks (default 8, up to 32) to maxi
|
|
|
20
18
|
|
|
21
19
|
## Features
|
|
22
20
|
|
|
23
|
-
- **Parallel Chunk Engine** — Splits downloads into multiple concurrent chunks using `
|
|
21
|
+
- **Parallel Chunk Engine** — Splits downloads into multiple concurrent chunks using `curl-cffi` async sessions to fully saturate your bandwidth.
|
|
24
22
|
- **Universal Downloader** — Paste any URL. yt-dlp handles 1000+ sites (YouTube, Facebook, Instagram, etc.), with automatic fallback to direct HTTP download for unsupported URLs.
|
|
25
23
|
- **Audio Only / MP3 Conversion** — Download videos as audio. IDM-CLI automatically grabs the best audio stream and uses FFmpeg to convert it to `.mp3`.
|
|
26
24
|
- **Smart Auto-Resume** — Internet dropped? Pressed `Ctrl+C`? No problem. IDM-CLI remembers the exact byte positions of all incomplete chunks. Paste the same link again to resume instantly.
|
|
@@ -29,6 +27,37 @@ IDM-CLI splits files into multiple parallel chunks (default 8, up to 32) to maxi
|
|
|
29
27
|
- **Cross-Platform** — Works on Windows, macOS, and Linux with platform-specific FFmpeg handling.
|
|
30
28
|
- **Auto-Update Check** — Checks PyPI once a day and notifies you when a new version is available.
|
|
31
29
|
|
|
30
|
+
## Security
|
|
31
|
+
|
|
32
|
+
**IDM-CLI is a download manager, not an antivirus.** It does not scan files for
|
|
33
|
+
malware — no signature database, no heuristic engine. Downloading a file that
|
|
34
|
+
contains malware will not trigger any warning from IDM-CLI itself.
|
|
35
|
+
|
|
36
|
+
What IDM-CLI does give you:
|
|
37
|
+
|
|
38
|
+
- **SSRF protection** — URLs pointing at private/loopback/link-local hosts
|
|
39
|
+
(`localhost`, `127.0.0.1`, `10.x`, `192.168.x`, `169.254.169.254`, …) are
|
|
40
|
+
rejected, so a crafted link cannot make IDM-CLI probe your internal network.
|
|
41
|
+
- **No shell execution** — all `subprocess` calls use `shell=False` with
|
|
42
|
+
argument lists; no URL or title ever reaches a shell.
|
|
43
|
+
- **Verified FFmpeg download** — when IDM-CLI auto-installs FFmpeg, the archive
|
|
44
|
+
is checked against the SHA-256 digest published by GitHub Releases.
|
|
45
|
+
|
|
46
|
+
**How to stay safe:** rely on your operating system's antivirus, which scans
|
|
47
|
+
files as they land on disk.
|
|
48
|
+
|
|
49
|
+
- **Windows:** Windows Defender real-time protection scans WSL paths
|
|
50
|
+
(`\\wsl.localhost\...`) automatically — nothing to configure.
|
|
51
|
+
- **Linux:** install ClamAV (`sudo apt install clamav`), keep the signature
|
|
52
|
+
database current (`sudo freshclam`), and scan a download with
|
|
53
|
+
`clamscan ~/Downloads/file`. Add a cron job or an inotify watcher to scan
|
|
54
|
+
automatically.
|
|
55
|
+
|
|
56
|
+
This mirrors how the official Internet Download Manager behaves: IDM does not
|
|
57
|
+
detect malware either — it can be configured (Options → Downloads → Virus
|
|
58
|
+
checking) to call an installed antivirus after a download finishes, and
|
|
59
|
+
otherwise relies on the antivirus's real-time protection.
|
|
60
|
+
|
|
32
61
|
## Prerequisites
|
|
33
62
|
|
|
34
63
|
- **Python 3.8+**
|
|
@@ -45,9 +74,8 @@ pip install idm-cli
|
|
|
45
74
|
|
|
46
75
|
# From source
|
|
47
76
|
git clone https://github.com/rj41-w2/idm-cli.git
|
|
48
|
-
cd
|
|
49
|
-
pip install -
|
|
50
|
-
pip install -e .
|
|
77
|
+
cd idm-cli
|
|
78
|
+
pip install -e ".[dev]"
|
|
51
79
|
```
|
|
52
80
|
|
|
53
81
|
## Usage
|
|
@@ -109,23 +137,36 @@ python -m idm_cli
|
|
|
109
137
|
|
|
110
138
|
```
|
|
111
139
|
idm_cli/
|
|
112
|
-
├──
|
|
140
|
+
├── __init__.py # Package version
|
|
141
|
+
├── __main__.py # python -m idm_cli entry point
|
|
142
|
+
├── config.py # Platform-aware config, logging, and paths
|
|
113
143
|
├── update_checker.py # PyPI version check
|
|
114
144
|
├── ui/
|
|
115
|
-
│ ├── cli.py #
|
|
116
|
-
│
|
|
145
|
+
│ ├── cli.py # Typer entry point and interactive command loop
|
|
146
|
+
│ ├── prompts.py # Questionary prompts and user-facing messages
|
|
147
|
+
│ ├── progress.py # Rich progress display and pause/resume controls
|
|
148
|
+
│ └── utils.py # URL validation, filename safety, and terminal helpers
|
|
117
149
|
├── downloader/
|
|
118
|
-
│ ├── core.py # Download orchestration
|
|
119
|
-
│ ├── downloader.py # Async
|
|
150
|
+
│ ├── core.py # Download orchestration and destination management
|
|
151
|
+
│ ├── downloader.py # Async ranged downloads, retries, and resume validation
|
|
120
152
|
│ ├── handlers.py # Queue & resume handlers
|
|
121
|
-
│ ├── muxer.py # FFmpeg
|
|
122
|
-
│ └── state.py #
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
153
|
+
│ ├── muxer.py # FFmpeg verification, muxing, and conversion
|
|
154
|
+
│ └── state.py # Locked, atomic JSON state persistence
|
|
155
|
+
└── extractors/
|
|
156
|
+
├── __init__.py # Direct HTTP probe and extractor selection
|
|
157
|
+
├── ytdlp.py # YouTube/social media extractor
|
|
158
|
+
├── direct.py # Direct HTTP file metadata and URL extraction
|
|
159
|
+
└── winget.py # Windows Package Manager metadata extraction
|
|
160
|
+
|
|
161
|
+
tests/ # pytest suite (runs fully offline)
|
|
127
162
|
```
|
|
128
163
|
|
|
164
|
+
The download flow is: `core.py` selects the extractor and prepares the
|
|
165
|
+
destination and media pipeline, `downloader.py` downloads validated byte ranges,
|
|
166
|
+
`progress.py` renders live progress, and `muxer.py` creates the final media file.
|
|
167
|
+
Interrupted downloads are tracked under the platform-specific application data
|
|
168
|
+
directory, not inside the repository.
|
|
169
|
+
|
|
129
170
|
## Contributing
|
|
130
171
|
|
|
131
172
|
Contributions are welcome. Fork the repo, make your changes on a feature branch, and open a PR against `main`. Keep changes focused and follow the existing code style.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from idm_cli.ui.cli import app
|
|
2
|
-
|
|
3
|
-
if __name__ == "__main__":
|
|
4
|
-
app()
|
|
1
|
+
from idm_cli.ui.cli import app
|
|
2
|
+
|
|
3
|
+
if __name__ == "__main__":
|
|
4
|
+
app()
|