ilovecli 0.1.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.
ilovecli-0.1.1/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Deep Dhabal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ <<<<<<< HEAD
22
+ SOFTWARE.
23
+ =======
24
+ SOFTWARE.
25
+ >>>>>>> 6722e1a0eb82323533fdaea2a1a3dedded46d53e
@@ -0,0 +1,254 @@
1
+ Metadata-Version: 2.4
2
+ Name: ilovecli
3
+ Version: 0.1.1
4
+ Summary: CLI tool to compress images, PDFs, and videos
5
+ Author: Deep Dhabal
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: typer[all]
11
+ Requires-Dist: rich
12
+ Requires-Dist: pillow
13
+ Requires-Dist: tqdm
14
+ Dynamic: license-file
15
+
16
+
17
+
18
+
19
+ # 🚀 ilovecli
20
+
21
+ > Compress smarter. From your terminal.
22
+
23
+
24
+ `ilovecli` is a fast, cross-platform command-line tool to compress **Images, PDFs, and Videos** directly from your terminal.
25
+
26
+ It supports smart auto-detection, target-size optimization, parallel processing, and Docker deployment.
27
+
28
+ ---
29
+
30
+ ## ✨ Features
31
+
32
+
33
+ - 🖼 Compress images (JPG, PNG, WEBP)
34
+ - 📄 Compress PDFs (Ghostscript powered)
35
+ - 🎬 Compress videos (FFmpeg powered)
36
+ - 🎯 Target-size compression (Images & PDFs)
37
+ - ⚡ Parallel folder image compression
38
+ - 📊 Original vs compressed size reporting
39
+ - 🐳 Docker support
40
+ - 📦 PyPI-ready package
41
+ - 🧠 Automatic file-type detection
42
+
43
+ ---
44
+
45
+ ## 📦 Installation
46
+
47
+ ### Install from PyPI
48
+
49
+ ```bash
50
+ pip install ilovecli
51
+ ````
52
+
53
+ ---
54
+
55
+ ### Install from Source
56
+
57
+ ```bash
58
+ git clone https://github.com/Dhabaldeep/ilovecli.git
59
+ cd ilovecli
60
+ pip install .
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 🔧 System Requirements
66
+
67
+ Make sure the following are installed:
68
+
69
+ * Python 3.8+
70
+ * FFmpeg (for video compression)
71
+ * Ghostscript (for PDF compression)
72
+
73
+ Verify installation:
74
+
75
+ ```bash
76
+ ffmpeg -version
77
+ gs --version
78
+ ```
79
+
80
+ ---
81
+
82
+ ## 🚀 Usage
83
+
84
+ ### 🔹 Compress Any Supported File
85
+
86
+ ```bash
87
+ ilovecli compress file.jpg
88
+ ilovecli compress document.pdf
89
+ ilovecli compress video.mp4
90
+ ```
91
+
92
+ Automatic file-type detection included.
93
+
94
+ ---
95
+
96
+ ### 🎯 Compress to Target Size
97
+
98
+ #### Image
99
+
100
+ ```bash
101
+ ilovecli target image.jpg 300
102
+ ```
103
+
104
+ Compresses image to approximately **300 KB** while maintaining best possible quality.
105
+
106
+ #### PDF
107
+
108
+ ```bash
109
+ ilovecli target document.pdf 500
110
+ ```
111
+
112
+ Optimizes DPI dynamically to keep the file under **500 KB**.
113
+
114
+ ---
115
+
116
+ ### 📄 Control PDF Compression Level
117
+
118
+ Available levels:
119
+
120
+ * `screen` (maximum compression)
121
+ * `ebook` (default)
122
+ * `printer`
123
+ * `prepress` (highest quality)
124
+
125
+ Example:
126
+
127
+ ```bash
128
+ ilovecli compress file.pdf --pdf-quality screen
129
+ ```
130
+
131
+ ---
132
+
133
+ ### 🎬 Control Video Compression (CRF)
134
+
135
+ Lower CRF → Better quality
136
+ Higher CRF → Smaller file
137
+
138
+ ```bash
139
+ ilovecli compress video.mp4 --crf 32
140
+ ```
141
+
142
+ Recommended range: **18–35**
143
+
144
+ ---
145
+
146
+ ### 📁 Compress All Images in Folder
147
+
148
+ ```bash
149
+ ilovecli folder ./images
150
+ ```
151
+
152
+ Uses parallel processing for faster execution.
153
+
154
+ ---
155
+
156
+ ### 🔎 Show Version
157
+
158
+ ```bash
159
+ ilovecli version
160
+ ```
161
+
162
+ ---
163
+
164
+ ## 🐳 Docker Support
165
+
166
+ ### Build Docker Image
167
+
168
+ ```bash
169
+ docker build -t ilovecli .
170
+ ```
171
+
172
+ ---
173
+
174
+ ### Run Inside Container
175
+
176
+ ```bash
177
+ docker run --rm -v $(pwd):/data ilovecli compress /data/file.pdf --pdf-quality screen
178
+ ```
179
+
180
+ No need to manually install Python, FFmpeg, or Ghostscript.
181
+
182
+ ---
183
+
184
+ ## 🏗 Project Structure
185
+
186
+ ```
187
+ ilovecli/
188
+
189
+ ├── cli.py
190
+ ├── image_tools.py
191
+ ├── pdf_tools.py
192
+ ├── video_tools.py
193
+ ├── utils.py
194
+ ├── logger.py
195
+ └── __init__.py
196
+ ```
197
+
198
+ ---
199
+
200
+ ## 🛠 Tech Stack
201
+
202
+ * Python
203
+ * Typer (CLI framework)
204
+ * Pillow (Image processing)
205
+ * FFmpeg (Video compression)
206
+ * Ghostscript (PDF compression)
207
+ * Rich (Styled console output)
208
+ * TQDM (Progress bars)
209
+ * Multiprocessing
210
+
211
+ ---
212
+
213
+ ## 📊 Example Output
214
+
215
+ ```
216
+ Original: 10.4 MB
217
+ Compressed: 2.3 MB
218
+ Reduced: 77.8%
219
+ ```
220
+
221
+ ---
222
+
223
+ ## 💼 Resume Description
224
+
225
+ > Developed a cross-platform CLI-based media compression toolkit using Python, Typer, multiprocessing, FFmpeg, and Ghostscript. Implemented dynamic target-size optimization via binary search, parallel processing, structured logging, and Docker containerization. Packaged for PyPI and Docker deployment.
226
+
227
+ ---
228
+
229
+ ## 📄 License
230
+
231
+ MIT License
232
+
233
+ ---
234
+
235
+ ## 🤝 Contributing
236
+
237
+ Contributions are welcome!
238
+
239
+ 1. Fork the repository
240
+ 2. Create your feature branch
241
+ 3. Commit changes
242
+ 4. Open a pull request
243
+
244
+ ---
245
+
246
+ ## ⭐ Support
247
+
248
+ If you find this project useful:
249
+
250
+ * ⭐ Star the repository
251
+ * 🐛 Report issues
252
+ * 🚀 Share with others
253
+
254
+ ```
@@ -0,0 +1,239 @@
1
+
2
+
3
+
4
+ # 🚀 ilovecli
5
+
6
+ > Compress smarter. From your terminal.
7
+
8
+
9
+ `ilovecli` is a fast, cross-platform command-line tool to compress **Images, PDFs, and Videos** directly from your terminal.
10
+
11
+ It supports smart auto-detection, target-size optimization, parallel processing, and Docker deployment.
12
+
13
+ ---
14
+
15
+ ## ✨ Features
16
+
17
+
18
+ - 🖼 Compress images (JPG, PNG, WEBP)
19
+ - 📄 Compress PDFs (Ghostscript powered)
20
+ - 🎬 Compress videos (FFmpeg powered)
21
+ - 🎯 Target-size compression (Images & PDFs)
22
+ - ⚡ Parallel folder image compression
23
+ - 📊 Original vs compressed size reporting
24
+ - 🐳 Docker support
25
+ - 📦 PyPI-ready package
26
+ - 🧠 Automatic file-type detection
27
+
28
+ ---
29
+
30
+ ## 📦 Installation
31
+
32
+ ### Install from PyPI
33
+
34
+ ```bash
35
+ pip install ilovecli
36
+ ````
37
+
38
+ ---
39
+
40
+ ### Install from Source
41
+
42
+ ```bash
43
+ git clone https://github.com/Dhabaldeep/ilovecli.git
44
+ cd ilovecli
45
+ pip install .
46
+ ```
47
+
48
+ ---
49
+
50
+ ## 🔧 System Requirements
51
+
52
+ Make sure the following are installed:
53
+
54
+ * Python 3.8+
55
+ * FFmpeg (for video compression)
56
+ * Ghostscript (for PDF compression)
57
+
58
+ Verify installation:
59
+
60
+ ```bash
61
+ ffmpeg -version
62
+ gs --version
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 🚀 Usage
68
+
69
+ ### 🔹 Compress Any Supported File
70
+
71
+ ```bash
72
+ ilovecli compress file.jpg
73
+ ilovecli compress document.pdf
74
+ ilovecli compress video.mp4
75
+ ```
76
+
77
+ Automatic file-type detection included.
78
+
79
+ ---
80
+
81
+ ### 🎯 Compress to Target Size
82
+
83
+ #### Image
84
+
85
+ ```bash
86
+ ilovecli target image.jpg 300
87
+ ```
88
+
89
+ Compresses image to approximately **300 KB** while maintaining best possible quality.
90
+
91
+ #### PDF
92
+
93
+ ```bash
94
+ ilovecli target document.pdf 500
95
+ ```
96
+
97
+ Optimizes DPI dynamically to keep the file under **500 KB**.
98
+
99
+ ---
100
+
101
+ ### 📄 Control PDF Compression Level
102
+
103
+ Available levels:
104
+
105
+ * `screen` (maximum compression)
106
+ * `ebook` (default)
107
+ * `printer`
108
+ * `prepress` (highest quality)
109
+
110
+ Example:
111
+
112
+ ```bash
113
+ ilovecli compress file.pdf --pdf-quality screen
114
+ ```
115
+
116
+ ---
117
+
118
+ ### 🎬 Control Video Compression (CRF)
119
+
120
+ Lower CRF → Better quality
121
+ Higher CRF → Smaller file
122
+
123
+ ```bash
124
+ ilovecli compress video.mp4 --crf 32
125
+ ```
126
+
127
+ Recommended range: **18–35**
128
+
129
+ ---
130
+
131
+ ### 📁 Compress All Images in Folder
132
+
133
+ ```bash
134
+ ilovecli folder ./images
135
+ ```
136
+
137
+ Uses parallel processing for faster execution.
138
+
139
+ ---
140
+
141
+ ### 🔎 Show Version
142
+
143
+ ```bash
144
+ ilovecli version
145
+ ```
146
+
147
+ ---
148
+
149
+ ## 🐳 Docker Support
150
+
151
+ ### Build Docker Image
152
+
153
+ ```bash
154
+ docker build -t ilovecli .
155
+ ```
156
+
157
+ ---
158
+
159
+ ### Run Inside Container
160
+
161
+ ```bash
162
+ docker run --rm -v $(pwd):/data ilovecli compress /data/file.pdf --pdf-quality screen
163
+ ```
164
+
165
+ No need to manually install Python, FFmpeg, or Ghostscript.
166
+
167
+ ---
168
+
169
+ ## 🏗 Project Structure
170
+
171
+ ```
172
+ ilovecli/
173
+
174
+ ├── cli.py
175
+ ├── image_tools.py
176
+ ├── pdf_tools.py
177
+ ├── video_tools.py
178
+ ├── utils.py
179
+ ├── logger.py
180
+ └── __init__.py
181
+ ```
182
+
183
+ ---
184
+
185
+ ## 🛠 Tech Stack
186
+
187
+ * Python
188
+ * Typer (CLI framework)
189
+ * Pillow (Image processing)
190
+ * FFmpeg (Video compression)
191
+ * Ghostscript (PDF compression)
192
+ * Rich (Styled console output)
193
+ * TQDM (Progress bars)
194
+ * Multiprocessing
195
+
196
+ ---
197
+
198
+ ## 📊 Example Output
199
+
200
+ ```
201
+ Original: 10.4 MB
202
+ Compressed: 2.3 MB
203
+ Reduced: 77.8%
204
+ ```
205
+
206
+ ---
207
+
208
+ ## 💼 Resume Description
209
+
210
+ > Developed a cross-platform CLI-based media compression toolkit using Python, Typer, multiprocessing, FFmpeg, and Ghostscript. Implemented dynamic target-size optimization via binary search, parallel processing, structured logging, and Docker containerization. Packaged for PyPI and Docker deployment.
211
+
212
+ ---
213
+
214
+ ## 📄 License
215
+
216
+ MIT License
217
+
218
+ ---
219
+
220
+ ## 🤝 Contributing
221
+
222
+ Contributions are welcome!
223
+
224
+ 1. Fork the repository
225
+ 2. Create your feature branch
226
+ 3. Commit changes
227
+ 4. Open a pull request
228
+
229
+ ---
230
+
231
+ ## ⭐ Support
232
+
233
+ If you find this project useful:
234
+
235
+ * ⭐ Star the repository
236
+ * 🐛 Report issues
237
+ * 🚀 Share with others
238
+
239
+ ```
@@ -0,0 +1,25 @@
1
+ from .image_tools import (
2
+ compress_image,
3
+ compress_folder_parallel,
4
+ convert_image,
5
+ compress_to_target_size,
6
+ )
7
+
8
+ from .pdf_tools import (
9
+ compress_pdf,
10
+ compress_pdf_to_target_size,
11
+ )
12
+
13
+ from .video_tools import compress_video
14
+
15
+ __all__ = [
16
+ "compress_image",
17
+ "compress_folder_parallel",
18
+ "convert_image",
19
+ "compress_to_target_size",
20
+ "compress_pdf",
21
+ "compress_pdf_to_target_size",
22
+ "compress_video",
23
+ ]
24
+
25
+ __version__ = "0.3.0"
@@ -0,0 +1,141 @@
1
+ import typer
2
+ from ilovecli import compress_pdf_to_target_size
3
+ from pathlib import Path
4
+ from rich.console import Console
5
+ from ilovecli import (
6
+ compress_image,
7
+ compress_folder_parallel,
8
+ compress_pdf,
9
+ compress_video,
10
+ convert_image,
11
+ compress_to_target_size,
12
+ __version__,
13
+ )
14
+ from ilovecli.logger import logger
15
+
16
+ app = typer.Typer(help="🚀 ilovecli - Image, PDF & Video Compressor")
17
+ console = Console()
18
+
19
+
20
+ @app.command()
21
+ def compress(
22
+ file: Path,
23
+ quality: int = typer.Option(60, help="Image quality (10-95)"),
24
+ pdf_quality: str = typer.Option(
25
+ "ebook",
26
+ help="PDF quality: screen, ebook, printer, prepress",
27
+ case_sensitive=False,
28
+ show_choices=True,
29
+ ),
30
+ crf: int = typer.Option(28, help="Video CRF (18-35)")
31
+ ):
32
+ """
33
+ Auto-detect and compress file
34
+ """
35
+ if not file.exists():
36
+ logger.error("File not found")
37
+ console.print("❌ File not found", style="red")
38
+ raise typer.Exit()
39
+
40
+ ext = file.suffix.lower()
41
+
42
+ try:
43
+ logger.info(f"Starting compression for {file.name}")
44
+
45
+ if ext in [".jpg", ".jpeg", ".png", ".webp"]:
46
+ compress_image(str(file), quality)
47
+
48
+ elif ext == ".pdf":
49
+ compress_pdf(str(file), pdf_quality)
50
+
51
+ elif ext in [".mp4", ".mkv", ".mov"]:
52
+ compress_video(str(file),crf)
53
+
54
+ else:
55
+ logger.warning("Unsupported file type")
56
+ console.print("❌ Unsupported file type", style="red")
57
+ raise typer.Exit()
58
+
59
+ logger.info("Compression completed successfully")
60
+
61
+ except Exception as e:
62
+ logger.exception("Unexpected error during compression")
63
+ console.print(f"❌ Error: {e}", style="red")
64
+
65
+
66
+ @app.command()
67
+ def folder(
68
+ path: Path,
69
+ quality: int = typer.Option(60, help="Image quality (10-95)")
70
+ ):
71
+ """
72
+ Compress all images inside folder using parallel processing
73
+ """
74
+ if not path.exists():
75
+ logger.error("Folder not found")
76
+ console.print("❌ Folder not found", style="red")
77
+ raise typer.Exit()
78
+
79
+ logger.info(f"Starting folder compression: {path}")
80
+ compress_folder_parallel(str(path), quality)
81
+ logger.info("Folder compression complete")
82
+
83
+
84
+ @app.command()
85
+ def convert(input: Path, output: Path):
86
+ """
87
+ Convert image format
88
+ """
89
+ logger.info(f"Converting {input.name} to {output.name}")
90
+ convert_image(str(input), str(output))
91
+ logger.info("Conversion complete")
92
+
93
+
94
+ @app.command()
95
+ def target(
96
+ file: Path,
97
+ size_kb: int = typer.Argument(..., help="Target size in KB"),
98
+ ):
99
+ """
100
+ Compress file to target size in KB
101
+ Works for images and PDFs
102
+ Example:
103
+ ilovecli target image.jpg 300
104
+ ilovecli target file.pdf 500
105
+ """
106
+ if not file.exists():
107
+ logger.error("File not found for target compression")
108
+ console.print("❌ File not found", style="red")
109
+ raise typer.Exit()
110
+
111
+ ext = file.suffix.lower()
112
+
113
+ logger.info(f"Starting target compression for {file.name} to {size_kb} KB")
114
+
115
+ try:
116
+ if ext in [".jpg", ".jpeg", ".png", ".webp"]:
117
+ compress_to_target_size(str(file), size_kb)
118
+
119
+ elif ext == ".pdf":
120
+ from ilovecli import compress_pdf_to_target_size
121
+ compress_pdf_to_target_size(str(file), size_kb)
122
+
123
+ else:
124
+ logger.warning("Target compression not supported for this file type")
125
+ console.print("❌ Target compression only supported for images and PDFs", style="red")
126
+ raise typer.Exit()
127
+
128
+ logger.info("Target compression completed successfully")
129
+
130
+ except Exception:
131
+ logger.exception("Error during target compression")
132
+ console.print("❌ Target compression failed", style="red")
133
+
134
+ @app.command()
135
+ def version():
136
+ logger.info("Version command called")
137
+ console.print(f"ilovecli version {__version__}")
138
+
139
+
140
+ if __name__ == "__main__":
141
+ app()
@@ -0,0 +1,123 @@
1
+ from PIL import Image
2
+ from multiprocessing import Pool, cpu_count
3
+ from pathlib import Path
4
+ import os
5
+
6
+ from .logger import logger
7
+
8
+
9
+ def compress_image(input_path: str, quality: int = 60):
10
+ try:
11
+ input_path = Path(input_path)
12
+ output = input_path.parent / f"compressed_{input_path.name}"
13
+
14
+ original_size = input_path.stat().st_size
15
+
16
+ img = Image.open(input_path)
17
+
18
+ if img.format in ["JPEG", "JPG"]:
19
+ img.save(output, quality=quality, optimize=True)
20
+ elif img.format == "PNG":
21
+ img.save(output, optimize=True)
22
+ else:
23
+ img.save(output)
24
+
25
+ new_size = output.stat().st_size
26
+ reduction = ((original_size - new_size) / original_size) * 100
27
+
28
+ logger.info(
29
+ f"Image compressed: {output.name} | "
30
+ f"Reduced {reduction:.2f}%"
31
+ )
32
+
33
+ except Exception:
34
+ logger.exception("Image compression failed")
35
+
36
+
37
+ def convert_image(input_path: str, output_path: str):
38
+ try:
39
+ img = Image.open(input_path)
40
+ img.save(output_path)
41
+ logger.info(f"Image converted: {output_path}")
42
+ except Exception:
43
+ logger.exception("Image conversion failed")
44
+
45
+
46
+ def _compress_single(args):
47
+ input_path, quality, output_folder = args
48
+ input_path = Path(input_path)
49
+ output_path = Path(output_folder) / f"compressed_{input_path.name}"
50
+
51
+ try:
52
+ img = Image.open(input_path)
53
+ img.save(output_path, quality=quality, optimize=True)
54
+ return input_path.name
55
+ except Exception:
56
+ logger.exception(f"Failed compressing {input_path.name}")
57
+ return None
58
+
59
+
60
+ def compress_folder_parallel(folder_path: str, quality: int = 60):
61
+ folder = Path(folder_path)
62
+
63
+ files = list(folder.glob("*.[jJ][pP][gG]")) + \
64
+ list(folder.glob("*.[jJ][pP][eE][gG]")) + \
65
+ list(folder.glob("*.[pP][nN][gG]")) + \
66
+ list(folder.glob("*.[wW][eE][bB][pP]"))
67
+
68
+ if not files:
69
+ logger.warning("No supported images found in folder")
70
+ return
71
+
72
+ output_folder = folder / "compressed_output"
73
+ output_folder.mkdir(exist_ok=True)
74
+
75
+ tasks = [(str(file), quality, str(output_folder)) for file in files]
76
+
77
+ workers = min(cpu_count(), len(tasks))
78
+ logger.info(f"Using {workers} CPU cores for parallel compression")
79
+
80
+ with Pool(workers) as pool:
81
+ for _ in pool.imap_unordered(_compress_single, tasks):
82
+ pass
83
+
84
+ logger.info("Parallel folder compression completed")
85
+
86
+
87
+ def compress_to_target_size(input_path: str, target_kb: int):
88
+ try:
89
+ input_path = Path(input_path)
90
+ output = input_path.parent / f"target_{input_path.name}"
91
+
92
+ target_bytes = target_kb * 1024
93
+ img = Image.open(input_path).convert("RGB")
94
+
95
+ low, high = 5, 95
96
+ best_quality = None
97
+
98
+ while low <= high:
99
+ mid = (low + high) // 2
100
+ img.save(output, format="JPEG", quality=mid, optimize=True)
101
+ size = output.stat().st_size
102
+
103
+ if size > target_bytes:
104
+ high = mid - 1
105
+ else:
106
+ best_quality = mid
107
+ low = mid + 1
108
+
109
+ if best_quality is None:
110
+ logger.error("Could not compress to desired size")
111
+ return
112
+
113
+ img.save(output, format="JPEG", quality=best_quality, optimize=True)
114
+
115
+ final_size_kb = output.stat().st_size / 1024
116
+ logger.info(
117
+ f"Target compression complete: {output.name} | "
118
+ f"Final size: {final_size_kb:.2f} KB | "
119
+ f"Quality used: {best_quality}"
120
+ )
121
+
122
+ except Exception:
123
+ logger.exception("Target size compression failed")
@@ -0,0 +1,8 @@
1
+ import logging
2
+
3
+ logging.basicConfig(
4
+ level=logging.INFO,
5
+ format="%(asctime)s - %(levelname)s - %(message)s"
6
+ )
7
+
8
+ logger = logging.getLogger("ilovecli")
@@ -0,0 +1,105 @@
1
+ #pdf_tools.py
2
+ import subprocess
3
+ from rich.console import Console
4
+ from tqdm import tqdm
5
+ import os
6
+ from .utils import print_size_report
7
+
8
+ console = Console()
9
+
10
+ def compress_pdf(input_path: str, quality: str = "ebook"):
11
+ import os
12
+ import subprocess
13
+
14
+ output = "compressed_" + os.path.basename(input_path)
15
+
16
+ original_size = os.path.getsize(input_path)
17
+
18
+ result = subprocess.run([
19
+ "gs",
20
+ "-sDEVICE=pdfwrite",
21
+ "-dCompatibilityLevel=1.4",
22
+ f"-dPDFSETTINGS=/{quality}",
23
+ "-dNOPAUSE",
24
+ "-dQUIET",
25
+ "-dBATCH",
26
+ f"-sOutputFile={output}",
27
+ input_path
28
+ ])
29
+
30
+ if result.returncode != 0:
31
+ print("❌ Ghostscript failed")
32
+ return
33
+
34
+ new_size = os.path.getsize(output)
35
+
36
+ print_size_report(original_size, new_size)
37
+
38
+ def compress_pdf_to_target_size(input_path: str, target_kb: int):
39
+ import os
40
+ import subprocess
41
+
42
+ target_bytes = target_kb * 1024
43
+ output = "target_" + os.path.basename(input_path)
44
+
45
+ original_size = os.path.getsize(input_path)
46
+
47
+ low = 50 # minimum DPI
48
+ high = 300 # maximum DPI
49
+ best_dpi = None
50
+
51
+ while low <= high:
52
+ mid = (low + high) // 2
53
+
54
+ subprocess.run([
55
+ "gs",
56
+ "-sDEVICE=pdfwrite",
57
+ "-dCompatibilityLevel=1.4",
58
+ "-dDownsampleColorImages=true",
59
+ "-dColorImageResolution=" + str(mid),
60
+ "-dDownsampleGrayImages=true",
61
+ "-dGrayImageResolution=" + str(mid),
62
+ "-dDownsampleMonoImages=true",
63
+ "-dMonoImageResolution=" + str(mid),
64
+ "-dNOPAUSE",
65
+ "-dQUIET",
66
+ "-dBATCH",
67
+ "-sOutputFile=" + output,
68
+ input_path
69
+ ], check=True)
70
+
71
+ new_size = os.path.getsize(output)
72
+
73
+ if new_size > target_bytes:
74
+ high = mid - 1
75
+ else:
76
+ best_dpi = mid
77
+ low = mid + 1
78
+
79
+ if best_dpi is None:
80
+ print("❌ Could not reach target size")
81
+ return
82
+
83
+ # Final save using best DPI
84
+ subprocess.run([
85
+ "gs",
86
+ "-sDEVICE=pdfwrite",
87
+ "-dCompatibilityLevel=1.4",
88
+ "-dDownsampleColorImages=true",
89
+ "-dColorImageResolution=" + str(best_dpi),
90
+ "-dDownsampleGrayImages=true",
91
+ "-dGrayImageResolution=" + str(best_dpi),
92
+ "-dDownsampleMonoImages=true",
93
+ "-dMonoImageResolution=" + str(best_dpi),
94
+ "-dNOPAUSE",
95
+ "-dQUIET",
96
+ "-dBATCH",
97
+ "-sOutputFile=" + output,
98
+ input_path
99
+ ], check=True)
100
+
101
+ final_size_kb = round(os.path.getsize(output) / 1024, 2)
102
+
103
+ print(f"✅ Saved as {output}")
104
+ print(f"📦 Final Size: {final_size_kb} KB")
105
+ print(f"🎯 DPI Used: {best_dpi}")
@@ -0,0 +1,10 @@
1
+ # utils.py
2
+ def print_size_report(original, new):
3
+ original_mb = original / (1024 * 1024)
4
+ new_mb = new / (1024 * 1024)
5
+
6
+ reduction = ((original - new) / original) * 100
7
+
8
+ print(f"Original: {round(original_mb,2)} MB")
9
+ print(f"Compressed: {round(new_mb,2)} MB")
10
+ print(f"Reduced: {round(reduction,2)}%")
@@ -0,0 +1,27 @@
1
+ # video_tools.py
2
+ import subprocess
3
+ from rich.console import Console
4
+ from tqdm import tqdm
5
+ import os
6
+
7
+ console = Console()
8
+
9
+ def compress_video(input_path: str, crf: int = 28):
10
+ output = "compressed_" + os.path.basename(input_path)
11
+
12
+ try:
13
+ subprocess.run([
14
+ "ffmpeg",
15
+ "-i", input_path,
16
+ "-vcodec", "libx264",
17
+ "-crf", str(crf),
18
+ "-preset", "slow", # better compression
19
+ "-movflags", "+faststart", # better for web streaming
20
+ "-y",
21
+ output
22
+ ], check=True)
23
+
24
+ console.print(f"✅ Saved as {output}", style="green")
25
+
26
+ except subprocess.CalledProcessError:
27
+ console.print("❌ FFmpeg failed", style="red")
@@ -0,0 +1,254 @@
1
+ Metadata-Version: 2.4
2
+ Name: ilovecli
3
+ Version: 0.1.1
4
+ Summary: CLI tool to compress images, PDFs, and videos
5
+ Author: Deep Dhabal
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: typer[all]
11
+ Requires-Dist: rich
12
+ Requires-Dist: pillow
13
+ Requires-Dist: tqdm
14
+ Dynamic: license-file
15
+
16
+
17
+
18
+
19
+ # 🚀 ilovecli
20
+
21
+ > Compress smarter. From your terminal.
22
+
23
+
24
+ `ilovecli` is a fast, cross-platform command-line tool to compress **Images, PDFs, and Videos** directly from your terminal.
25
+
26
+ It supports smart auto-detection, target-size optimization, parallel processing, and Docker deployment.
27
+
28
+ ---
29
+
30
+ ## ✨ Features
31
+
32
+
33
+ - 🖼 Compress images (JPG, PNG, WEBP)
34
+ - 📄 Compress PDFs (Ghostscript powered)
35
+ - 🎬 Compress videos (FFmpeg powered)
36
+ - 🎯 Target-size compression (Images & PDFs)
37
+ - ⚡ Parallel folder image compression
38
+ - 📊 Original vs compressed size reporting
39
+ - 🐳 Docker support
40
+ - 📦 PyPI-ready package
41
+ - 🧠 Automatic file-type detection
42
+
43
+ ---
44
+
45
+ ## 📦 Installation
46
+
47
+ ### Install from PyPI
48
+
49
+ ```bash
50
+ pip install ilovecli
51
+ ````
52
+
53
+ ---
54
+
55
+ ### Install from Source
56
+
57
+ ```bash
58
+ git clone https://github.com/Dhabaldeep/ilovecli.git
59
+ cd ilovecli
60
+ pip install .
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 🔧 System Requirements
66
+
67
+ Make sure the following are installed:
68
+
69
+ * Python 3.8+
70
+ * FFmpeg (for video compression)
71
+ * Ghostscript (for PDF compression)
72
+
73
+ Verify installation:
74
+
75
+ ```bash
76
+ ffmpeg -version
77
+ gs --version
78
+ ```
79
+
80
+ ---
81
+
82
+ ## 🚀 Usage
83
+
84
+ ### 🔹 Compress Any Supported File
85
+
86
+ ```bash
87
+ ilovecli compress file.jpg
88
+ ilovecli compress document.pdf
89
+ ilovecli compress video.mp4
90
+ ```
91
+
92
+ Automatic file-type detection included.
93
+
94
+ ---
95
+
96
+ ### 🎯 Compress to Target Size
97
+
98
+ #### Image
99
+
100
+ ```bash
101
+ ilovecli target image.jpg 300
102
+ ```
103
+
104
+ Compresses image to approximately **300 KB** while maintaining best possible quality.
105
+
106
+ #### PDF
107
+
108
+ ```bash
109
+ ilovecli target document.pdf 500
110
+ ```
111
+
112
+ Optimizes DPI dynamically to keep the file under **500 KB**.
113
+
114
+ ---
115
+
116
+ ### 📄 Control PDF Compression Level
117
+
118
+ Available levels:
119
+
120
+ * `screen` (maximum compression)
121
+ * `ebook` (default)
122
+ * `printer`
123
+ * `prepress` (highest quality)
124
+
125
+ Example:
126
+
127
+ ```bash
128
+ ilovecli compress file.pdf --pdf-quality screen
129
+ ```
130
+
131
+ ---
132
+
133
+ ### 🎬 Control Video Compression (CRF)
134
+
135
+ Lower CRF → Better quality
136
+ Higher CRF → Smaller file
137
+
138
+ ```bash
139
+ ilovecli compress video.mp4 --crf 32
140
+ ```
141
+
142
+ Recommended range: **18–35**
143
+
144
+ ---
145
+
146
+ ### 📁 Compress All Images in Folder
147
+
148
+ ```bash
149
+ ilovecli folder ./images
150
+ ```
151
+
152
+ Uses parallel processing for faster execution.
153
+
154
+ ---
155
+
156
+ ### 🔎 Show Version
157
+
158
+ ```bash
159
+ ilovecli version
160
+ ```
161
+
162
+ ---
163
+
164
+ ## 🐳 Docker Support
165
+
166
+ ### Build Docker Image
167
+
168
+ ```bash
169
+ docker build -t ilovecli .
170
+ ```
171
+
172
+ ---
173
+
174
+ ### Run Inside Container
175
+
176
+ ```bash
177
+ docker run --rm -v $(pwd):/data ilovecli compress /data/file.pdf --pdf-quality screen
178
+ ```
179
+
180
+ No need to manually install Python, FFmpeg, or Ghostscript.
181
+
182
+ ---
183
+
184
+ ## 🏗 Project Structure
185
+
186
+ ```
187
+ ilovecli/
188
+
189
+ ├── cli.py
190
+ ├── image_tools.py
191
+ ├── pdf_tools.py
192
+ ├── video_tools.py
193
+ ├── utils.py
194
+ ├── logger.py
195
+ └── __init__.py
196
+ ```
197
+
198
+ ---
199
+
200
+ ## 🛠 Tech Stack
201
+
202
+ * Python
203
+ * Typer (CLI framework)
204
+ * Pillow (Image processing)
205
+ * FFmpeg (Video compression)
206
+ * Ghostscript (PDF compression)
207
+ * Rich (Styled console output)
208
+ * TQDM (Progress bars)
209
+ * Multiprocessing
210
+
211
+ ---
212
+
213
+ ## 📊 Example Output
214
+
215
+ ```
216
+ Original: 10.4 MB
217
+ Compressed: 2.3 MB
218
+ Reduced: 77.8%
219
+ ```
220
+
221
+ ---
222
+
223
+ ## 💼 Resume Description
224
+
225
+ > Developed a cross-platform CLI-based media compression toolkit using Python, Typer, multiprocessing, FFmpeg, and Ghostscript. Implemented dynamic target-size optimization via binary search, parallel processing, structured logging, and Docker containerization. Packaged for PyPI and Docker deployment.
226
+
227
+ ---
228
+
229
+ ## 📄 License
230
+
231
+ MIT License
232
+
233
+ ---
234
+
235
+ ## 🤝 Contributing
236
+
237
+ Contributions are welcome!
238
+
239
+ 1. Fork the repository
240
+ 2. Create your feature branch
241
+ 3. Commit changes
242
+ 4. Open a pull request
243
+
244
+ ---
245
+
246
+ ## ⭐ Support
247
+
248
+ If you find this project useful:
249
+
250
+ * ⭐ Star the repository
251
+ * 🐛 Report issues
252
+ * 🚀 Share with others
253
+
254
+ ```
@@ -0,0 +1,16 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ ilovecli/__init__.py
5
+ ilovecli/cli.py
6
+ ilovecli/image_tools.py
7
+ ilovecli/logger.py
8
+ ilovecli/pdf_tools.py
9
+ ilovecli/utils.py
10
+ ilovecli/video_tools.py
11
+ ilovecli.egg-info/PKG-INFO
12
+ ilovecli.egg-info/SOURCES.txt
13
+ ilovecli.egg-info/dependency_links.txt
14
+ ilovecli.egg-info/entry_points.txt
15
+ ilovecli.egg-info/requires.txt
16
+ ilovecli.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ilovecli = ilovecli.cli:app
@@ -0,0 +1,4 @@
1
+ typer[all]
2
+ rich
3
+ pillow
4
+ tqdm
@@ -0,0 +1 @@
1
+ ilovecli
@@ -0,0 +1,24 @@
1
+ [project]
2
+ name = "ilovecli"
3
+ version = "0.1.1"
4
+ description = "CLI tool to compress images, PDFs, and videos"
5
+ authors = [
6
+ { name = "Deep Dhabal" }
7
+ ]
8
+ readme = "README.md"
9
+ license = "MIT"
10
+ requires-python = ">=3.8"
11
+
12
+ dependencies = [
13
+ "typer[all]",
14
+ "rich",
15
+ "pillow",
16
+ "tqdm"
17
+ ]
18
+
19
+ [project.scripts]
20
+ ilovecli = "ilovecli.cli:app"
21
+
22
+ [build-system]
23
+ requires = ["setuptools>=61.0"]
24
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+