idm-cli 1.2.0__tar.gz → 1.3.1__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.
Files changed (53) hide show
  1. idm_cli-1.3.1/MANIFEST.in +1 -0
  2. idm_cli-1.3.1/PKG-INFO +170 -0
  3. idm_cli-1.3.1/README.md +137 -0
  4. idm_cli-1.3.1/idm_cli/__init__.py +3 -0
  5. idm_cli-1.3.1/idm_cli/__main__.py +4 -0
  6. idm_cli-1.3.1/idm_cli/config.py +85 -0
  7. idm_cli-1.3.1/idm_cli/downloader/__init__.py +0 -0
  8. idm_cli-1.3.1/idm_cli/downloader/core.py +317 -0
  9. idm_cli-1.3.1/idm_cli/downloader/downloader.py +293 -0
  10. idm_cli-1.3.1/idm_cli/downloader/handlers.py +195 -0
  11. idm_cli-1.3.1/idm_cli/downloader/muxer.py +174 -0
  12. {idm_cli-1.2.0/idm_cli → idm_cli-1.3.1/idm_cli/downloader}/state.py +62 -59
  13. {idm_cli-1.2.0 → idm_cli-1.3.1}/idm_cli/extractors/__init__.py +5 -9
  14. {idm_cli-1.2.0 → idm_cli-1.3.1}/idm_cli/extractors/direct.py +19 -19
  15. {idm_cli-1.2.0 → idm_cli-1.3.1}/idm_cli/extractors/winget.py +76 -65
  16. idm_cli-1.2.0/idm_cli/extractors/youtube.py → idm_cli-1.3.1/idm_cli/extractors/ytdlp.py +139 -112
  17. idm_cli-1.3.1/idm_cli/ui/__init__.py +0 -0
  18. idm_cli-1.3.1/idm_cli/ui/cli.py +206 -0
  19. idm_cli-1.3.1/idm_cli/ui/utils.py +153 -0
  20. {idm_cli-1.2.0 → idm_cli-1.3.1}/idm_cli/update_checker.py +74 -67
  21. idm_cli-1.3.1/idm_cli.egg-info/PKG-INFO +170 -0
  22. idm_cli-1.3.1/idm_cli.egg-info/SOURCES.txt +31 -0
  23. idm_cli-1.3.1/idm_cli.egg-info/entry_points.txt +2 -0
  24. {idm_cli-1.2.0 → idm_cli-1.3.1}/idm_cli.egg-info/requires.txt +6 -0
  25. {idm_cli-1.2.0 → idm_cli-1.3.1}/idm_cli.egg-info/top_level.txt +1 -0
  26. idm_cli-1.3.1/pyproject.toml +45 -0
  27. {idm_cli-1.2.0 → idm_cli-1.3.1}/requirements.txt +11 -10
  28. {idm_cli-1.2.0 → idm_cli-1.3.1}/setup.py +44 -46
  29. idm_cli-1.3.1/tests/__init__.py +0 -0
  30. idm_cli-1.3.1/tests/test_core.py +76 -0
  31. idm_cli-1.2.0/MANIFEST.in +0 -1
  32. idm_cli-1.2.0/PKG-INFO +0 -124
  33. idm_cli-1.2.0/README.md +0 -91
  34. idm_cli-1.2.0/idm_cli/__init__.py +0 -3
  35. idm_cli-1.2.0/idm_cli/browser_extension/background.js +0 -41
  36. idm_cli-1.2.0/idm_cli/browser_extension/icon128.png +0 -0
  37. idm_cli-1.2.0/idm_cli/browser_extension/icon16.png +0 -0
  38. idm_cli-1.2.0/idm_cli/browser_extension/icon32.png +0 -0
  39. idm_cli-1.2.0/idm_cli/browser_extension/icon48.png +0 -0
  40. idm_cli-1.2.0/idm_cli/browser_extension/manifest.json +0 -17
  41. idm_cli-1.2.0/idm_cli/cli.py +0 -785
  42. idm_cli-1.2.0/idm_cli/daemon.py +0 -35
  43. idm_cli-1.2.0/idm_cli/downloader.py +0 -158
  44. idm_cli-1.2.0/idm_cli/extractors/facebook.py +0 -112
  45. idm_cli-1.2.0/idm_cli/extractors/instagram.py +0 -116
  46. idm_cli-1.2.0/idm_cli/muxer.py +0 -75
  47. idm_cli-1.2.0/idm_cli/native_host.py +0 -78
  48. idm_cli-1.2.0/idm_cli.egg-info/PKG-INFO +0 -124
  49. idm_cli-1.2.0/idm_cli.egg-info/SOURCES.txt +0 -31
  50. idm_cli-1.2.0/idm_cli.egg-info/entry_points.txt +0 -2
  51. {idm_cli-1.2.0 → idm_cli-1.3.1}/LICENSE +0 -0
  52. {idm_cli-1.2.0 → idm_cli-1.3.1}/idm_cli.egg-info/dependency_links.txt +0 -0
  53. {idm_cli-1.2.0 → idm_cli-1.3.1}/setup.cfg +0 -0
@@ -0,0 +1 @@
1
+ include requirements.txt
idm_cli-1.3.1/PKG-INFO ADDED
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.4
2
+ Name: idm-cli
3
+ Version: 1.3.1
4
+ Summary: A lightning-fast, universal command-line download manager
5
+ Home-page: https://github.com/rj41-w2/idm-cli
6
+ Author: Rehan
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/rj41-w2/idm-cli
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Environment :: Console
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: typer
16
+ Requires-Dist: rich
17
+ Requires-Dist: aiohttp
18
+ Requires-Dist: aiofiles
19
+ Requires-Dist: yt-dlp
20
+ Requires-Dist: pyfiglet
21
+ Requires-Dist: questionary
22
+ Requires-Dist: aiodns
23
+ Requires-Dist: Brotli
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: packaging; extra == "dev"
30
+ Dynamic: home-page
31
+ Dynamic: license-file
32
+ Dynamic: requires-python
33
+
34
+ <div align="center">
35
+
36
+ <h1>IDM-CLI</h1>
37
+
38
+ **A lightning-fast, cross-platform command-line download manager written in Python.**
39
+
40
+ *The official IDM asks you to pay after 30 days — IDM-CLI is 100% free, open-source, and yours to modify!*
41
+
42
+ [![PyPI version](https://img.shields.io/pypi/v/idm-cli?color=blue&label=pypi%20version)](https://pypi.org/project/idm-cli/)
43
+ [![Downloads](https://static.pepy.tech/badge/idm-cli)](https://pepy.tech/project/idm-cli)
44
+ [![License](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/rj41-w2/idm-cli/blob/main/LICENSE)
45
+ ![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey)
46
+ [![Install](https://img.shields.io/badge/install-pip%20install%20idm--cli-brightgreen)](https://pypi.org/project/idm-cli/)
47
+
48
+ [Download via PyPI](https://pypi.org/project/idm-cli/) · [Report a Bug](https://github.com/rj41-w2/idm-cli/issues)
49
+
50
+ </div>
51
+
52
+ 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.).
53
+
54
+ ## Features
55
+
56
+ - **Parallel Chunk Engine** — Splits downloads into multiple concurrent chunks using `aiohttp` async sessions to fully saturate your bandwidth.
57
+ - **Universal Downloader** — Paste any URL. yt-dlp handles 1000+ sites (YouTube, Facebook, Instagram, etc.), with automatic fallback to direct HTTP download for unsupported URLs.
58
+ - **Audio Only / MP3 Conversion** — Download videos as audio. IDM-CLI automatically grabs the best audio stream and uses FFmpeg to convert it to `.mp3`.
59
+ - **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.
60
+ - **Persistent Queue System** — Add multiple files to a queue with `-Q` and type `start queue` to download them all sequentially.
61
+ - **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.
62
+ - **Cross-Platform** — Works on Windows, macOS, and Linux with platform-specific FFmpeg handling.
63
+ - **Auto-Update Check** — Checks PyPI once a day and notifies you when a new version is available.
64
+
65
+ ## Prerequisites
66
+
67
+ - **Python 3.8+**
68
+ - **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:
69
+ - Windows: `winget install ffmpeg`
70
+ - macOS: `brew install ffmpeg`
71
+ - Linux: `sudo apt install ffmpeg`
72
+
73
+ ## Installation
74
+
75
+ ```bash
76
+ # From PyPI
77
+ pip install idm-cli
78
+
79
+ # From source
80
+ git clone https://github.com/rj41-w2/idm-cli.git
81
+ cd IDM-CLI
82
+ pip install -r requirements.txt
83
+ pip install -e .
84
+ ```
85
+
86
+ ## Usage
87
+
88
+ Run the app interactively:
89
+
90
+ ```bash
91
+ idm
92
+ ```
93
+
94
+ This opens a prompt where you can paste your link, select video quality, or queue the download.
95
+
96
+ ### CLI Flags (Fast Mode)
97
+
98
+ Skip the interactive menus by passing arguments directly:
99
+
100
+ ```bash
101
+ # Download a video at 1080p
102
+ idm "https://youtube.com/watch?v=..." -q 1080p -v
103
+
104
+ # Audio only (converts to MP3)
105
+ idm "https://youtube.com/watch?v=..." -a
106
+
107
+ # 16 parallel chunks for maximum speed
108
+ idm "https://example.com/largefile.zip" -c 16
109
+
110
+ # Add to queue
111
+ idm "https://facebook.com/..." -Q
112
+ ```
113
+
114
+ | Flag | Description |
115
+ |------|-------------|
116
+ | `-q <resolution>` | Set video quality (e.g., `1080p`, `720p`) |
117
+ | `-a` | Audio only — download and convert to MP3 |
118
+ | `-v` | Download video + audio (bypasses quality prompt) |
119
+ | `-Q` | Add to queue instead of downloading immediately |
120
+ | `-c <num>` | Number of parallel chunks (default: 8) |
121
+ | `-f <filename>` | Force a custom output filename |
122
+
123
+ ### Interactive Commands
124
+
125
+ | Command | Description |
126
+ |---------|-------------|
127
+ | `<URL>` | Download a video or file |
128
+ | `resume` | Resume or delete incomplete downloads |
129
+ | `start queue` | Process all queued downloads |
130
+ | `help` | Show available commands and flags |
131
+ | `exit` | Exit the application |
132
+
133
+ ### Troubleshooting: Windows Device Guard
134
+
135
+ If you get `"idm.exe was blocked by your organization's Device Guard policy"`, run the Python module directly:
136
+
137
+ ```bash
138
+ python -m idm_cli
139
+ ```
140
+
141
+ ## Architecture
142
+
143
+ ```
144
+ idm_cli/
145
+ ├── config.py # Platform-aware config, logging, paths
146
+ ├── update_checker.py # PyPI version check
147
+ ├── ui/
148
+ │ ├── cli.py # Main interactive CLI
149
+ │ └── utils.py # Console, progress listener, validators
150
+ ├── downloader/
151
+ │ ├── core.py # Download orchestration & FFmpeg setup
152
+ │ ├── downloader.py # Async chunk download engine
153
+ │ ├── handlers.py # Queue & resume handlers
154
+ │ ├── muxer.py # FFmpeg mux/conversion
155
+ │ └── state.py # Atomic JSON state persistence
156
+ ├── extractors/
157
+ │ ├── ytdlp.py # YouTube/social media extractor
158
+ │ ├── direct.py # Direct HTTP file downloader
159
+ │ └── winget.py # Windows Package Manager extractor
160
+ ```
161
+
162
+ ## Contributing
163
+
164
+ 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.
165
+
166
+ For bug reports and feature requests, [open an issue](https://github.com/rj41-w2/idm-cli/issues).
167
+
168
+ ## License
169
+
170
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,137 @@
1
+ <div align="center">
2
+
3
+ <h1>IDM-CLI</h1>
4
+
5
+ **A lightning-fast, cross-platform command-line download manager written in Python.**
6
+
7
+ *The official IDM asks you to pay after 30 days — IDM-CLI is 100% free, open-source, and yours to modify!*
8
+
9
+ [![PyPI version](https://img.shields.io/pypi/v/idm-cli?color=blue&label=pypi%20version)](https://pypi.org/project/idm-cli/)
10
+ [![Downloads](https://static.pepy.tech/badge/idm-cli)](https://pepy.tech/project/idm-cli)
11
+ [![License](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/rj41-w2/idm-cli/blob/main/LICENSE)
12
+ ![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey)
13
+ [![Install](https://img.shields.io/badge/install-pip%20install%20idm--cli-brightgreen)](https://pypi.org/project/idm-cli/)
14
+
15
+ [Download via PyPI](https://pypi.org/project/idm-cli/) · [Report a Bug](https://github.com/rj41-w2/idm-cli/issues)
16
+
17
+ </div>
18
+
19
+ 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.).
20
+
21
+ ## Features
22
+
23
+ - **Parallel Chunk Engine** — Splits downloads into multiple concurrent chunks using `aiohttp` async sessions to fully saturate your bandwidth.
24
+ - **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
+ - **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
+ - **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.
27
+ - **Persistent Queue System** — Add multiple files to a queue with `-Q` and type `start queue` to download them all sequentially.
28
+ - **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.
29
+ - **Cross-Platform** — Works on Windows, macOS, and Linux with platform-specific FFmpeg handling.
30
+ - **Auto-Update Check** — Checks PyPI once a day and notifies you when a new version is available.
31
+
32
+ ## Prerequisites
33
+
34
+ - **Python 3.8+**
35
+ - **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:
36
+ - Windows: `winget install ffmpeg`
37
+ - macOS: `brew install ffmpeg`
38
+ - Linux: `sudo apt install ffmpeg`
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ # From PyPI
44
+ pip install idm-cli
45
+
46
+ # From source
47
+ git clone https://github.com/rj41-w2/idm-cli.git
48
+ cd IDM-CLI
49
+ pip install -r requirements.txt
50
+ pip install -e .
51
+ ```
52
+
53
+ ## Usage
54
+
55
+ Run the app interactively:
56
+
57
+ ```bash
58
+ idm
59
+ ```
60
+
61
+ This opens a prompt where you can paste your link, select video quality, or queue the download.
62
+
63
+ ### CLI Flags (Fast Mode)
64
+
65
+ Skip the interactive menus by passing arguments directly:
66
+
67
+ ```bash
68
+ # Download a video at 1080p
69
+ idm "https://youtube.com/watch?v=..." -q 1080p -v
70
+
71
+ # Audio only (converts to MP3)
72
+ idm "https://youtube.com/watch?v=..." -a
73
+
74
+ # 16 parallel chunks for maximum speed
75
+ idm "https://example.com/largefile.zip" -c 16
76
+
77
+ # Add to queue
78
+ idm "https://facebook.com/..." -Q
79
+ ```
80
+
81
+ | Flag | Description |
82
+ |------|-------------|
83
+ | `-q <resolution>` | Set video quality (e.g., `1080p`, `720p`) |
84
+ | `-a` | Audio only — download and convert to MP3 |
85
+ | `-v` | Download video + audio (bypasses quality prompt) |
86
+ | `-Q` | Add to queue instead of downloading immediately |
87
+ | `-c <num>` | Number of parallel chunks (default: 8) |
88
+ | `-f <filename>` | Force a custom output filename |
89
+
90
+ ### Interactive Commands
91
+
92
+ | Command | Description |
93
+ |---------|-------------|
94
+ | `<URL>` | Download a video or file |
95
+ | `resume` | Resume or delete incomplete downloads |
96
+ | `start queue` | Process all queued downloads |
97
+ | `help` | Show available commands and flags |
98
+ | `exit` | Exit the application |
99
+
100
+ ### Troubleshooting: Windows Device Guard
101
+
102
+ If you get `"idm.exe was blocked by your organization's Device Guard policy"`, run the Python module directly:
103
+
104
+ ```bash
105
+ python -m idm_cli
106
+ ```
107
+
108
+ ## Architecture
109
+
110
+ ```
111
+ idm_cli/
112
+ ├── config.py # Platform-aware config, logging, paths
113
+ ├── update_checker.py # PyPI version check
114
+ ├── ui/
115
+ │ ├── cli.py # Main interactive CLI
116
+ │ └── utils.py # Console, progress listener, validators
117
+ ├── downloader/
118
+ │ ├── core.py # Download orchestration & FFmpeg setup
119
+ │ ├── downloader.py # Async chunk download engine
120
+ │ ├── handlers.py # Queue & resume handlers
121
+ │ ├── muxer.py # FFmpeg mux/conversion
122
+ │ └── state.py # Atomic JSON state persistence
123
+ ├── extractors/
124
+ │ ├── ytdlp.py # YouTube/social media extractor
125
+ │ ├── direct.py # Direct HTTP file downloader
126
+ │ └── winget.py # Windows Package Manager extractor
127
+ ```
128
+
129
+ ## Contributing
130
+
131
+ 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.
132
+
133
+ For bug reports and feature requests, [open an issue](https://github.com/rj41-w2/idm-cli/issues).
134
+
135
+ ## License
136
+
137
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,3 @@
1
+ # IDM-CLI Package
2
+
3
+ __version__ = "1.3.1"
@@ -0,0 +1,4 @@
1
+ from idm_cli.ui.cli import app
2
+
3
+ if __name__ == "__main__":
4
+ app()
@@ -0,0 +1,85 @@
1
+ import os
2
+ import json
3
+ import platform
4
+ import shutil
5
+ import logging
6
+ from logging.handlers import RotatingFileHandler
7
+ from platformdirs import user_data_dir, user_downloads_dir
8
+
9
+ __all__ = ["CONFIG_DIR", "CONFIG_FILE", "logger", "load_config", "save_config", "setup_logging"]
10
+
11
+ APP_NAME = "idm-cli"
12
+ APP_AUTHOR = "idm-cli"
13
+ CONFIG_DIR = user_data_dir(APP_NAME, APP_AUTHOR)
14
+ CONFIG_FILE = os.path.join(CONFIG_DIR, "config.json")
15
+ LOG_FILE = os.path.join(CONFIG_DIR, "idm.log")
16
+
17
+ def _migrate_old_config() -> None:
18
+ old_dir = os.path.expanduser("~/.idm_cli")
19
+ if old_dir == CONFIG_DIR:
20
+ return
21
+ if not os.path.isdir(old_dir):
22
+ return
23
+ os.makedirs(CONFIG_DIR, exist_ok=True)
24
+ for item in os.listdir(old_dir):
25
+ if item == "__pycache__":
26
+ continue
27
+ src = os.path.join(old_dir, item)
28
+ dst = os.path.join(CONFIG_DIR, item)
29
+ if not os.path.exists(dst):
30
+ try:
31
+ if os.path.isdir(src):
32
+ shutil.copytree(src, dst)
33
+ else:
34
+ shutil.copy2(src, dst)
35
+ except OSError:
36
+ pass
37
+
38
+ def _get_default_download_dir() -> str:
39
+ return user_downloads_dir()
40
+
41
+ def setup_logging() -> logging.Logger:
42
+ _migrate_old_config()
43
+ os.makedirs(CONFIG_DIR, exist_ok=True)
44
+ logger = logging.getLogger("idm_cli")
45
+ logger.setLevel(logging.DEBUG)
46
+ if not logger.handlers:
47
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
48
+
49
+ file_handler = RotatingFileHandler(LOG_FILE, maxBytes=5*1024*1024, backupCount=2, encoding="utf-8")
50
+ file_handler.setFormatter(formatter)
51
+ logger.addHandler(file_handler)
52
+
53
+ stream_handler = logging.StreamHandler()
54
+ stream_handler.setFormatter(formatter)
55
+ stream_handler.stream.reconfigure(errors="backslashreplace")
56
+ logger.addHandler(stream_handler)
57
+ return logger
58
+
59
+ logger = setup_logging()
60
+
61
+ DEFAULT_CONFIG = {
62
+ "default_chunks": 8,
63
+ "default_quality": "720p",
64
+ "download_dir": _get_default_download_dir(),
65
+ "last_version": "0.0.0"
66
+ }
67
+
68
+ def load_config() -> dict:
69
+ config = DEFAULT_CONFIG.copy()
70
+ if os.path.exists(CONFIG_FILE):
71
+ try:
72
+ with open(CONFIG_FILE, "r") as f:
73
+ user_config = json.load(f)
74
+ config.update(user_config)
75
+ except (OSError, json.JSONDecodeError) as e:
76
+ logger.warning(f"Failed to load config: {e}")
77
+ return config
78
+
79
+ def save_config(config_data: dict) -> None:
80
+ os.makedirs(CONFIG_DIR, exist_ok=True)
81
+ try:
82
+ with open(CONFIG_FILE, "w") as f:
83
+ json.dump(config_data, f, indent=4)
84
+ except OSError as e:
85
+ logger.error(f"Failed to save config: {e}")
File without changes