polytool 0.1.0__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.
- polytool-0.1.0/.gitignore +63 -0
- polytool-0.1.0/LICENSE +21 -0
- polytool-0.1.0/PKG-INFO +258 -0
- polytool-0.1.0/README.md +159 -0
- polytool-0.1.0/docs/README.md +80 -0
- polytool-0.1.0/pyproject.toml +147 -0
- polytool-0.1.0/src/polytool/__init__.py +4 -0
- polytool-0.1.0/src/polytool/__main__.py +6 -0
- polytool-0.1.0/src/polytool/cli/__init__.py +82 -0
- polytool-0.1.0/src/polytool/cli/clip.py +71 -0
- polytool-0.1.0/src/polytool/cli/color.py +125 -0
- polytool-0.1.0/src/polytool/cli/convert.py +151 -0
- polytool-0.1.0/src/polytool/cli/cron.py +60 -0
- polytool-0.1.0/src/polytool/cli/data.py +188 -0
- polytool-0.1.0/src/polytool/cli/dl.py +102 -0
- polytool-0.1.0/src/polytool/cli/enc.py +216 -0
- polytool-0.1.0/src/polytool/cli/file.py +275 -0
- polytool-0.1.0/src/polytool/cli/gen.py +163 -0
- polytool-0.1.0/src/polytool/cli/img.py +439 -0
- polytool-0.1.0/src/polytool/cli/net.py +147 -0
- polytool-0.1.0/src/polytool/cli/pdf.py +306 -0
- polytool-0.1.0/src/polytool/cli/qr.py +122 -0
- polytool-0.1.0/src/polytool/cli/shot.py +128 -0
- polytool-0.1.0/src/polytool/cli/text.py +176 -0
- polytool-0.1.0/src/polytool/cli/vid.py +159 -0
- polytool-0.1.0/src/polytool/core/__init__.py +1 -0
- polytool-0.1.0/src/polytool/core/console.py +8 -0
- polytool-0.1.0/src/polytool/core/errors.py +56 -0
- polytool-0.1.0/src/polytool/core/ffmpeg.py +35 -0
- polytool-0.1.0/src/polytool/core/io.py +71 -0
- polytool-0.1.0/src/polytool/core/lazy.py +35 -0
- polytool-0.1.0/src/polytool/core/progress.py +47 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
*.egg-info/
|
|
8
|
+
*.egg
|
|
9
|
+
build/
|
|
10
|
+
dist/
|
|
11
|
+
wheels/
|
|
12
|
+
.eggs/
|
|
13
|
+
pip-wheel-metadata/
|
|
14
|
+
share/python-wheels/
|
|
15
|
+
|
|
16
|
+
# Virtual envs
|
|
17
|
+
.venv/
|
|
18
|
+
venv/
|
|
19
|
+
env/
|
|
20
|
+
ENV/
|
|
21
|
+
|
|
22
|
+
# uv
|
|
23
|
+
.uv-cache/
|
|
24
|
+
|
|
25
|
+
# Tests / coverage
|
|
26
|
+
.pytest_cache/
|
|
27
|
+
.coverage
|
|
28
|
+
.coverage.*
|
|
29
|
+
htmlcov/
|
|
30
|
+
coverage.xml
|
|
31
|
+
.tox/
|
|
32
|
+
.nox/
|
|
33
|
+
|
|
34
|
+
# Type checkers
|
|
35
|
+
.mypy_cache/
|
|
36
|
+
.pyright/
|
|
37
|
+
.basedpyright/
|
|
38
|
+
.ruff_cache/
|
|
39
|
+
|
|
40
|
+
# Editors
|
|
41
|
+
.idea/
|
|
42
|
+
.vscode/
|
|
43
|
+
*.swp
|
|
44
|
+
*.swo
|
|
45
|
+
|
|
46
|
+
# OS
|
|
47
|
+
.DS_Store
|
|
48
|
+
Thumbs.db
|
|
49
|
+
|
|
50
|
+
# Local outputs from manual smoke tests
|
|
51
|
+
out.*
|
|
52
|
+
cutout.*
|
|
53
|
+
merged.pdf
|
|
54
|
+
pages/
|
|
55
|
+
qr.png
|
|
56
|
+
screen.png
|
|
57
|
+
page.png
|
|
58
|
+
*.gif
|
|
59
|
+
!tests/fixtures/*.gif
|
|
60
|
+
|
|
61
|
+
# Cache from heavy deps
|
|
62
|
+
.rembg/
|
|
63
|
+
.cache/
|
polytool-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 polytool contributors
|
|
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
|
+
SOFTWARE.
|
polytool-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: polytool
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: One-binary CLI bundling 26 everyday utilities — image/video/PDF conversion, background removal, OCR, QR codes, hashing, downloads, and more
|
|
5
|
+
Project-URL: Homepage, https://github.com/k6w/polytool
|
|
6
|
+
Project-URL: Repository, https://github.com/k6w/polytool
|
|
7
|
+
Project-URL: Issues, https://github.com/k6w/polytool/issues
|
|
8
|
+
Author: polytool contributors
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: background-removal,cli,convert,ffmpeg,image,ocr,pdf,qr,swiss-army-knife,utility,video,yt-dlp
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Requires-Python: >=3.13
|
|
23
|
+
Requires-Dist: cron-descriptor>=1.4
|
|
24
|
+
Requires-Dist: croniter>=2
|
|
25
|
+
Requires-Dist: faker>=25
|
|
26
|
+
Requires-Dist: httpx>=0.27
|
|
27
|
+
Requires-Dist: markdown-it-py>=3
|
|
28
|
+
Requires-Dist: pint>=0.24
|
|
29
|
+
Requires-Dist: pyjwt>=2.8
|
|
30
|
+
Requires-Dist: pyperclip>=1.8
|
|
31
|
+
Requires-Dist: python-dateutil>=2.9
|
|
32
|
+
Requires-Dist: python-slugify>=8
|
|
33
|
+
Requires-Dist: rich>=13
|
|
34
|
+
Requires-Dist: ruamel-yaml>=0.18
|
|
35
|
+
Requires-Dist: segno>=1.6
|
|
36
|
+
Requires-Dist: tomli-w>=1.0
|
|
37
|
+
Requires-Dist: typer>=0.12
|
|
38
|
+
Requires-Dist: xmltodict>=0.13
|
|
39
|
+
Requires-Dist: xxhash>=3.4
|
|
40
|
+
Provides-Extra: ai
|
|
41
|
+
Requires-Dist: rembg[cpu]>=2.0; extra == 'ai'
|
|
42
|
+
Provides-Extra: archive
|
|
43
|
+
Requires-Dist: py7zr>=0.21; extra == 'archive'
|
|
44
|
+
Provides-Extra: dev
|
|
45
|
+
Requires-Dist: basedpyright>=1.13; extra == 'dev'
|
|
46
|
+
Requires-Dist: pre-commit>=3.7; extra == 'dev'
|
|
47
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
48
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
49
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
50
|
+
Provides-Extra: dl
|
|
51
|
+
Requires-Dist: yt-dlp>=2024.5; extra == 'dl'
|
|
52
|
+
Provides-Extra: full
|
|
53
|
+
Requires-Dist: ascii-magic>=2; extra == 'full'
|
|
54
|
+
Requires-Dist: colorthief>=0.2; extra == 'full'
|
|
55
|
+
Requires-Dist: easyocr>=1.7; extra == 'full'
|
|
56
|
+
Requires-Dist: ffmpeg-python>=0.2; extra == 'full'
|
|
57
|
+
Requires-Dist: imageio-ffmpeg>=0.5; extra == 'full'
|
|
58
|
+
Requires-Dist: mss>=9; extra == 'full'
|
|
59
|
+
Requires-Dist: pdfplumber>=0.11; extra == 'full'
|
|
60
|
+
Requires-Dist: piexif>=1.1; extra == 'full'
|
|
61
|
+
Requires-Dist: pikepdf>=8; extra == 'full'
|
|
62
|
+
Requires-Dist: pillow-avif-plugin>=1.4; extra == 'full'
|
|
63
|
+
Requires-Dist: pillow-heif>=0.18; extra == 'full'
|
|
64
|
+
Requires-Dist: pillow>=10; extra == 'full'
|
|
65
|
+
Requires-Dist: playwright>=1.44; extra == 'full'
|
|
66
|
+
Requires-Dist: py7zr>=0.21; extra == 'full'
|
|
67
|
+
Requires-Dist: pymupdf>=1.24; extra == 'full'
|
|
68
|
+
Requires-Dist: pypdf>=4; extra == 'full'
|
|
69
|
+
Requires-Dist: pytesseract>=0.3; extra == 'full'
|
|
70
|
+
Requires-Dist: pyzbar>=0.1; extra == 'full'
|
|
71
|
+
Requires-Dist: rembg[cpu]>=2.0; extra == 'full'
|
|
72
|
+
Requires-Dist: resvg-py>=0.1; extra == 'full'
|
|
73
|
+
Requires-Dist: yt-dlp>=2024.5; extra == 'full'
|
|
74
|
+
Provides-Extra: img
|
|
75
|
+
Requires-Dist: ascii-magic>=2; extra == 'img'
|
|
76
|
+
Requires-Dist: colorthief>=0.2; extra == 'img'
|
|
77
|
+
Requires-Dist: piexif>=1.1; extra == 'img'
|
|
78
|
+
Requires-Dist: pillow-avif-plugin>=1.4; extra == 'img'
|
|
79
|
+
Requires-Dist: pillow-heif>=0.18; extra == 'img'
|
|
80
|
+
Requires-Dist: pillow>=10; extra == 'img'
|
|
81
|
+
Requires-Dist: resvg-py>=0.1; extra == 'img'
|
|
82
|
+
Provides-Extra: ocr
|
|
83
|
+
Requires-Dist: easyocr>=1.7; extra == 'ocr'
|
|
84
|
+
Requires-Dist: pytesseract>=0.3; extra == 'ocr'
|
|
85
|
+
Provides-Extra: pdf
|
|
86
|
+
Requires-Dist: pdfplumber>=0.11; extra == 'pdf'
|
|
87
|
+
Requires-Dist: pikepdf>=8; extra == 'pdf'
|
|
88
|
+
Requires-Dist: pymupdf>=1.24; extra == 'pdf'
|
|
89
|
+
Requires-Dist: pypdf>=4; extra == 'pdf'
|
|
90
|
+
Provides-Extra: qr-decode
|
|
91
|
+
Requires-Dist: pyzbar>=0.1; extra == 'qr-decode'
|
|
92
|
+
Provides-Extra: shot
|
|
93
|
+
Requires-Dist: mss>=9; extra == 'shot'
|
|
94
|
+
Requires-Dist: playwright>=1.44; extra == 'shot'
|
|
95
|
+
Provides-Extra: vid
|
|
96
|
+
Requires-Dist: ffmpeg-python>=0.2; extra == 'vid'
|
|
97
|
+
Requires-Dist: imageio-ffmpeg>=0.5; extra == 'vid'
|
|
98
|
+
Description-Content-Type: text/markdown
|
|
99
|
+
|
|
100
|
+
# polytool
|
|
101
|
+
|
|
102
|
+
> One CLI, 26 everyday utilities. Image format conversion, background removal, video/audio conversion, PDF tooling, OCR, QR codes, hashing, downloads, and more — all behind one binary called `pt`.
|
|
103
|
+
|
|
104
|
+
[](https://github.com/k6w/polytool/actions/workflows/ci.yml)
|
|
105
|
+
|
|
106
|
+
## Install
|
|
107
|
+
|
|
108
|
+
The fastest way (no Python prerequisite — `uv` brings its own):
|
|
109
|
+
|
|
110
|
+
```powershell
|
|
111
|
+
# 1. install uv (Windows PowerShell)
|
|
112
|
+
irm https://astral.sh/uv/install.ps1 | iex
|
|
113
|
+
|
|
114
|
+
# 2. install polytool (slim — fast, ~80 MB)
|
|
115
|
+
uv tool install polytool
|
|
116
|
+
|
|
117
|
+
# or, install everything (image/video/PDF/yt-dlp/screenshots/AI background removal)
|
|
118
|
+
uv tool install 'polytool[full]'
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# macOS / Linux
|
|
123
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
124
|
+
uv tool install 'polytool[full]'
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
> **Note for PowerShell users:** quote `'polytool[full]'` — the brackets are shell glob characters.
|
|
128
|
+
|
|
129
|
+
After install, both `polytool` and the short alias `pt` are on your PATH.
|
|
130
|
+
|
|
131
|
+
## Quick start
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
pt qr gen "https://github.com/k6w/polytool" -o qr.png
|
|
135
|
+
pt img convert photo.heic -o photo.jpg
|
|
136
|
+
pt img bg-remove portrait.jpg # transparent PNG
|
|
137
|
+
pt vid gif clip.mp4 # animated gif
|
|
138
|
+
pt vid extract-audio movie.mp4 # mp3
|
|
139
|
+
pt pdf merge a.pdf b.pdf -o merged.pdf
|
|
140
|
+
pt pdf to-images doc.pdf --dpi 200
|
|
141
|
+
pt dl get 'https://www.youtube.com/watch?v=...'
|
|
142
|
+
pt enc hash sha256 release.zip
|
|
143
|
+
pt enc base64 encode README.md
|
|
144
|
+
pt data convert config.yaml --to json
|
|
145
|
+
pt gen password --length 32
|
|
146
|
+
pt gen uuid v7
|
|
147
|
+
pt color convert "#3366ff"
|
|
148
|
+
pt convert unit "100 km" --to mi
|
|
149
|
+
pt convert timestamp 1715200000
|
|
150
|
+
pt text slugify "Hello, World!"
|
|
151
|
+
pt cron explain "0 9 * * MON"
|
|
152
|
+
pt net http GET https://api.github.com
|
|
153
|
+
pt file dedupe ./Downloads
|
|
154
|
+
pt file archive ./project -o project.7z
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Run `pt --help` to see all groups, or `pt <group> --help` for any group's verbs (each verb's help has runnable Examples).
|
|
158
|
+
|
|
159
|
+
## Documentation
|
|
160
|
+
|
|
161
|
+
Full reference for every verb, argument, and option lives in **[docs/](docs/README.md)**:
|
|
162
|
+
|
|
163
|
+
- **[Install guide](docs/install.md)** — slim vs full, all extras, Windows quoting
|
|
164
|
+
- **Per-group reference** — [img](docs/img.md) · [vid](docs/vid.md) · [pdf](docs/pdf.md) · [dl](docs/dl.md) · [shot](docs/shot.md) · [qr](docs/qr.md) · [data](docs/data.md) · [enc](docs/enc.md) · [text](docs/text.md) · [convert](docs/convert.md) · [color](docs/color.md) · [cron](docs/cron.md) · [file](docs/file.md) · [gen](docs/gen.md) · [net](docs/net.md) · [clip](docs/clip.md)
|
|
165
|
+
- **[Architecture](docs/architecture.md)** — package layout, lazy imports, error model, how to add a verb
|
|
166
|
+
- **[Troubleshooting](docs/troubleshooting.md)** — every common error with a fix
|
|
167
|
+
|
|
168
|
+
## Feature reference (all 26 verbs)
|
|
169
|
+
|
|
170
|
+
| Group | Verbs |
|
|
171
|
+
|---|---|
|
|
172
|
+
| `pt img` | `convert` (png/jpg/webp/avif/heic/svg/bmp/tiff), `resize`, `compress`, `bg-remove`, `watermark`, `ascii`, `exif`, `palette`, `ocr` |
|
|
173
|
+
| `pt vid` | `convert`, `trim`, `extract-audio`, `gif` |
|
|
174
|
+
| `pt pdf` | `merge`, `split`, `compress`, `extract-text`, `to-images`, `from-images`, `ocr` |
|
|
175
|
+
| `pt dl` | `get` (yt-dlp wrapper, audio-only mode), `info` |
|
|
176
|
+
| `pt data` | `convert` (json↔yaml↔toml↔csv↔xml), `pretty`, `validate` |
|
|
177
|
+
| `pt enc` | `hash` (md5/sha1/sha256/sha512/blake2b/xxhash), `base64`, `url`, `html`, `jwt-decode`, `jwt-verify` |
|
|
178
|
+
| `pt qr` | `gen` (png/svg/pdf/eps/terminal), `wifi` (Wi-Fi join code), `decode` |
|
|
179
|
+
| `pt gen` | `password`, `uuid` (v1/v3/v4/v5/v7), `lorem` |
|
|
180
|
+
| `pt file` | `rename`, `dedupe`, `bigfiles`, `organize`, `archive` (zip/tar/tar.gz/7z) |
|
|
181
|
+
| `pt net` | `port-check`, `ip-info`, `http` |
|
|
182
|
+
| `pt clip` | `copy`, `paste` |
|
|
183
|
+
| `pt shot` | `screen`, `web` (Playwright), `install` |
|
|
184
|
+
| `pt color` | `convert` (hex/rgb/hsl/hsv/cmyk) |
|
|
185
|
+
| `pt convert` | `unit`, `timestamp`, `base` |
|
|
186
|
+
| `pt text` | `diff`, `wc`, `case` (snake/kebab/camel/pascal/...), `slugify`, `md-to-html`, `md-preview` |
|
|
187
|
+
| `pt cron` | `explain`, `next` |
|
|
188
|
+
|
|
189
|
+
## Slim vs full install
|
|
190
|
+
|
|
191
|
+
The default install ships only lightweight utilities (data, enc, gen, color, convert, text, qr-gen, cron, net, clip, file). Heavy/optional features are grouped behind extras so you only pull what you need:
|
|
192
|
+
|
|
193
|
+
| Extra | Adds | Approx. size |
|
|
194
|
+
|---|---|---|
|
|
195
|
+
| `[img]` | Pillow + HEIC/AVIF/SVG plugins, EXIF, palette, ASCII, watermark | ~50 MB |
|
|
196
|
+
| `[vid]` | `ffmpeg-python` + bundled `ffmpeg` (auto-downloaded) | ~70 MB on first use |
|
|
197
|
+
| `[pdf]` | pypdf, pikepdf, pdfplumber, PyMuPDF | ~80 MB |
|
|
198
|
+
| `[dl]` | yt-dlp | ~10 MB |
|
|
199
|
+
| `[shot]` | mss, Playwright (Chromium installed via `pt shot install`) | ~150 MB |
|
|
200
|
+
| `[ai]` | rembg + ONNX runtime (170 MB U2-Net model on first run) | ~250 MB |
|
|
201
|
+
| `[ocr]` | pytesseract / easyocr (PyTorch) | ~1 GB if easyocr |
|
|
202
|
+
| `[qr-decode]` | pyzbar (system `libzbar` on Linux) | ~5 MB |
|
|
203
|
+
| `[archive]` | py7zr | ~5 MB |
|
|
204
|
+
| `[full]` | all of the above | ~1.5 GB |
|
|
205
|
+
|
|
206
|
+
Verbs that need an extra you haven't installed print a friendly hint:
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
This command needs the 'ai' extra.
|
|
210
|
+
Install with: uv tool install 'polytool[ai]'
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Troubleshooting
|
|
214
|
+
|
|
215
|
+
### `pt img convert *.svg` fails on Windows
|
|
216
|
+
We use `resvg-py` (a pre-built Rust wheel) instead of `cairosvg` precisely to avoid the Cairo DLL pain. Reinstall the `[img]` extra to pull it in.
|
|
217
|
+
|
|
218
|
+
### `pt vid` wants ffmpeg
|
|
219
|
+
We prefer a system `ffmpeg` if it's on PATH, and fall back to `imageio-ffmpeg`'s bundled binary (auto-downloads ~70 MB on first call). Install ffmpeg system-wide with [`winget install ffmpeg`](https://learn.microsoft.com/windows/package-manager/) / `brew install ffmpeg` / `apt install ffmpeg` to skip the bundled download.
|
|
220
|
+
|
|
221
|
+
### `pt img bg-remove` is downloading something
|
|
222
|
+
First run pulls the U2-Net ONNX model (~170 MB) into `~/.u2net/`. Set `U2NET_HOME` to relocate.
|
|
223
|
+
|
|
224
|
+
### `pt qr decode` says pyzbar missing
|
|
225
|
+
On Linux, install the system library: `sudo apt-get install libzbar0` (Debian/Ubuntu) or `sudo dnf install zbar` (Fedora). Then reinstall `[qr-decode]`.
|
|
226
|
+
|
|
227
|
+
### `pt shot web` fails on first run
|
|
228
|
+
Chromium isn't installed yet. Run `pt shot install` (which is shorthand for `python -m playwright install chromium`).
|
|
229
|
+
|
|
230
|
+
### `pt img ocr` says Tesseract not found
|
|
231
|
+
The default `tesseract` engine needs the system Tesseract binary. Either install it (`winget install --id UB-Mannheim.TesseractOCR` on Windows, `brew install tesseract`, `apt install tesseract-ocr`) or pass `--engine easyocr` to use a self-contained PyTorch OCR.
|
|
232
|
+
|
|
233
|
+
### Brackets in `uv tool install 'polytool[full]'`
|
|
234
|
+
PowerShell parses unquoted brackets — always wrap the spec in single quotes.
|
|
235
|
+
|
|
236
|
+
## Contributing
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
git clone https://github.com/k6w/polytool
|
|
240
|
+
cd polytool
|
|
241
|
+
uv sync --extra dev --extra img --extra vid --extra pdf --extra dl --extra shot --extra archive --extra qr-decode
|
|
242
|
+
uv run pre-commit install
|
|
243
|
+
uv run pytest
|
|
244
|
+
uv run ruff check .
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Conventional Commits required (`feat:`, `fix:`, `chore:`, `docs:`, `test:`, `ci:`, `build:`).
|
|
248
|
+
|
|
249
|
+
Each user-facing verb must:
|
|
250
|
+
- Include a runnable `Examples:` block in its `--help`.
|
|
251
|
+
- Read from path or stdin (`-`) where it's semantic.
|
|
252
|
+
- Default `--output` to next-to-source for files, stdout for text.
|
|
253
|
+
- Raise `PolytoolError(msg, hint=...)` on user errors (rendered as a red panel).
|
|
254
|
+
- Ship at least one happy-path and one error-path test.
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
MIT — see [LICENSE](LICENSE).
|
polytool-0.1.0/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# polytool
|
|
2
|
+
|
|
3
|
+
> One CLI, 26 everyday utilities. Image format conversion, background removal, video/audio conversion, PDF tooling, OCR, QR codes, hashing, downloads, and more — all behind one binary called `pt`.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/k6w/polytool/actions/workflows/ci.yml)
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
The fastest way (no Python prerequisite — `uv` brings its own):
|
|
10
|
+
|
|
11
|
+
```powershell
|
|
12
|
+
# 1. install uv (Windows PowerShell)
|
|
13
|
+
irm https://astral.sh/uv/install.ps1 | iex
|
|
14
|
+
|
|
15
|
+
# 2. install polytool (slim — fast, ~80 MB)
|
|
16
|
+
uv tool install polytool
|
|
17
|
+
|
|
18
|
+
# or, install everything (image/video/PDF/yt-dlp/screenshots/AI background removal)
|
|
19
|
+
uv tool install 'polytool[full]'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# macOS / Linux
|
|
24
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
25
|
+
uv tool install 'polytool[full]'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
> **Note for PowerShell users:** quote `'polytool[full]'` — the brackets are shell glob characters.
|
|
29
|
+
|
|
30
|
+
After install, both `polytool` and the short alias `pt` are on your PATH.
|
|
31
|
+
|
|
32
|
+
## Quick start
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pt qr gen "https://github.com/k6w/polytool" -o qr.png
|
|
36
|
+
pt img convert photo.heic -o photo.jpg
|
|
37
|
+
pt img bg-remove portrait.jpg # transparent PNG
|
|
38
|
+
pt vid gif clip.mp4 # animated gif
|
|
39
|
+
pt vid extract-audio movie.mp4 # mp3
|
|
40
|
+
pt pdf merge a.pdf b.pdf -o merged.pdf
|
|
41
|
+
pt pdf to-images doc.pdf --dpi 200
|
|
42
|
+
pt dl get 'https://www.youtube.com/watch?v=...'
|
|
43
|
+
pt enc hash sha256 release.zip
|
|
44
|
+
pt enc base64 encode README.md
|
|
45
|
+
pt data convert config.yaml --to json
|
|
46
|
+
pt gen password --length 32
|
|
47
|
+
pt gen uuid v7
|
|
48
|
+
pt color convert "#3366ff"
|
|
49
|
+
pt convert unit "100 km" --to mi
|
|
50
|
+
pt convert timestamp 1715200000
|
|
51
|
+
pt text slugify "Hello, World!"
|
|
52
|
+
pt cron explain "0 9 * * MON"
|
|
53
|
+
pt net http GET https://api.github.com
|
|
54
|
+
pt file dedupe ./Downloads
|
|
55
|
+
pt file archive ./project -o project.7z
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Run `pt --help` to see all groups, or `pt <group> --help` for any group's verbs (each verb's help has runnable Examples).
|
|
59
|
+
|
|
60
|
+
## Documentation
|
|
61
|
+
|
|
62
|
+
Full reference for every verb, argument, and option lives in **[docs/](docs/README.md)**:
|
|
63
|
+
|
|
64
|
+
- **[Install guide](docs/install.md)** — slim vs full, all extras, Windows quoting
|
|
65
|
+
- **Per-group reference** — [img](docs/img.md) · [vid](docs/vid.md) · [pdf](docs/pdf.md) · [dl](docs/dl.md) · [shot](docs/shot.md) · [qr](docs/qr.md) · [data](docs/data.md) · [enc](docs/enc.md) · [text](docs/text.md) · [convert](docs/convert.md) · [color](docs/color.md) · [cron](docs/cron.md) · [file](docs/file.md) · [gen](docs/gen.md) · [net](docs/net.md) · [clip](docs/clip.md)
|
|
66
|
+
- **[Architecture](docs/architecture.md)** — package layout, lazy imports, error model, how to add a verb
|
|
67
|
+
- **[Troubleshooting](docs/troubleshooting.md)** — every common error with a fix
|
|
68
|
+
|
|
69
|
+
## Feature reference (all 26 verbs)
|
|
70
|
+
|
|
71
|
+
| Group | Verbs |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `pt img` | `convert` (png/jpg/webp/avif/heic/svg/bmp/tiff), `resize`, `compress`, `bg-remove`, `watermark`, `ascii`, `exif`, `palette`, `ocr` |
|
|
74
|
+
| `pt vid` | `convert`, `trim`, `extract-audio`, `gif` |
|
|
75
|
+
| `pt pdf` | `merge`, `split`, `compress`, `extract-text`, `to-images`, `from-images`, `ocr` |
|
|
76
|
+
| `pt dl` | `get` (yt-dlp wrapper, audio-only mode), `info` |
|
|
77
|
+
| `pt data` | `convert` (json↔yaml↔toml↔csv↔xml), `pretty`, `validate` |
|
|
78
|
+
| `pt enc` | `hash` (md5/sha1/sha256/sha512/blake2b/xxhash), `base64`, `url`, `html`, `jwt-decode`, `jwt-verify` |
|
|
79
|
+
| `pt qr` | `gen` (png/svg/pdf/eps/terminal), `wifi` (Wi-Fi join code), `decode` |
|
|
80
|
+
| `pt gen` | `password`, `uuid` (v1/v3/v4/v5/v7), `lorem` |
|
|
81
|
+
| `pt file` | `rename`, `dedupe`, `bigfiles`, `organize`, `archive` (zip/tar/tar.gz/7z) |
|
|
82
|
+
| `pt net` | `port-check`, `ip-info`, `http` |
|
|
83
|
+
| `pt clip` | `copy`, `paste` |
|
|
84
|
+
| `pt shot` | `screen`, `web` (Playwright), `install` |
|
|
85
|
+
| `pt color` | `convert` (hex/rgb/hsl/hsv/cmyk) |
|
|
86
|
+
| `pt convert` | `unit`, `timestamp`, `base` |
|
|
87
|
+
| `pt text` | `diff`, `wc`, `case` (snake/kebab/camel/pascal/...), `slugify`, `md-to-html`, `md-preview` |
|
|
88
|
+
| `pt cron` | `explain`, `next` |
|
|
89
|
+
|
|
90
|
+
## Slim vs full install
|
|
91
|
+
|
|
92
|
+
The default install ships only lightweight utilities (data, enc, gen, color, convert, text, qr-gen, cron, net, clip, file). Heavy/optional features are grouped behind extras so you only pull what you need:
|
|
93
|
+
|
|
94
|
+
| Extra | Adds | Approx. size |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `[img]` | Pillow + HEIC/AVIF/SVG plugins, EXIF, palette, ASCII, watermark | ~50 MB |
|
|
97
|
+
| `[vid]` | `ffmpeg-python` + bundled `ffmpeg` (auto-downloaded) | ~70 MB on first use |
|
|
98
|
+
| `[pdf]` | pypdf, pikepdf, pdfplumber, PyMuPDF | ~80 MB |
|
|
99
|
+
| `[dl]` | yt-dlp | ~10 MB |
|
|
100
|
+
| `[shot]` | mss, Playwright (Chromium installed via `pt shot install`) | ~150 MB |
|
|
101
|
+
| `[ai]` | rembg + ONNX runtime (170 MB U2-Net model on first run) | ~250 MB |
|
|
102
|
+
| `[ocr]` | pytesseract / easyocr (PyTorch) | ~1 GB if easyocr |
|
|
103
|
+
| `[qr-decode]` | pyzbar (system `libzbar` on Linux) | ~5 MB |
|
|
104
|
+
| `[archive]` | py7zr | ~5 MB |
|
|
105
|
+
| `[full]` | all of the above | ~1.5 GB |
|
|
106
|
+
|
|
107
|
+
Verbs that need an extra you haven't installed print a friendly hint:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
This command needs the 'ai' extra.
|
|
111
|
+
Install with: uv tool install 'polytool[ai]'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Troubleshooting
|
|
115
|
+
|
|
116
|
+
### `pt img convert *.svg` fails on Windows
|
|
117
|
+
We use `resvg-py` (a pre-built Rust wheel) instead of `cairosvg` precisely to avoid the Cairo DLL pain. Reinstall the `[img]` extra to pull it in.
|
|
118
|
+
|
|
119
|
+
### `pt vid` wants ffmpeg
|
|
120
|
+
We prefer a system `ffmpeg` if it's on PATH, and fall back to `imageio-ffmpeg`'s bundled binary (auto-downloads ~70 MB on first call). Install ffmpeg system-wide with [`winget install ffmpeg`](https://learn.microsoft.com/windows/package-manager/) / `brew install ffmpeg` / `apt install ffmpeg` to skip the bundled download.
|
|
121
|
+
|
|
122
|
+
### `pt img bg-remove` is downloading something
|
|
123
|
+
First run pulls the U2-Net ONNX model (~170 MB) into `~/.u2net/`. Set `U2NET_HOME` to relocate.
|
|
124
|
+
|
|
125
|
+
### `pt qr decode` says pyzbar missing
|
|
126
|
+
On Linux, install the system library: `sudo apt-get install libzbar0` (Debian/Ubuntu) or `sudo dnf install zbar` (Fedora). Then reinstall `[qr-decode]`.
|
|
127
|
+
|
|
128
|
+
### `pt shot web` fails on first run
|
|
129
|
+
Chromium isn't installed yet. Run `pt shot install` (which is shorthand for `python -m playwright install chromium`).
|
|
130
|
+
|
|
131
|
+
### `pt img ocr` says Tesseract not found
|
|
132
|
+
The default `tesseract` engine needs the system Tesseract binary. Either install it (`winget install --id UB-Mannheim.TesseractOCR` on Windows, `brew install tesseract`, `apt install tesseract-ocr`) or pass `--engine easyocr` to use a self-contained PyTorch OCR.
|
|
133
|
+
|
|
134
|
+
### Brackets in `uv tool install 'polytool[full]'`
|
|
135
|
+
PowerShell parses unquoted brackets — always wrap the spec in single quotes.
|
|
136
|
+
|
|
137
|
+
## Contributing
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
git clone https://github.com/k6w/polytool
|
|
141
|
+
cd polytool
|
|
142
|
+
uv sync --extra dev --extra img --extra vid --extra pdf --extra dl --extra shot --extra archive --extra qr-decode
|
|
143
|
+
uv run pre-commit install
|
|
144
|
+
uv run pytest
|
|
145
|
+
uv run ruff check .
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Conventional Commits required (`feat:`, `fix:`, `chore:`, `docs:`, `test:`, `ci:`, `build:`).
|
|
149
|
+
|
|
150
|
+
Each user-facing verb must:
|
|
151
|
+
- Include a runnable `Examples:` block in its `--help`.
|
|
152
|
+
- Read from path or stdin (`-`) where it's semantic.
|
|
153
|
+
- Default `--output` to next-to-source for files, stdout for text.
|
|
154
|
+
- Raise `PolytoolError(msg, hint=...)` on user errors (rendered as a red panel).
|
|
155
|
+
- Ship at least one happy-path and one error-path test.
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# polytool documentation
|
|
2
|
+
|
|
3
|
+
Detailed reference for every command in `polytool` (binary `pt`).
|
|
4
|
+
|
|
5
|
+
`pt` is built around 16 subcommand groups, each with one or more verbs (26 verbs in total). Every verb has its own page below — argument types, defaults, all flags, exit codes, and runnable examples.
|
|
6
|
+
|
|
7
|
+
## Quick links
|
|
8
|
+
|
|
9
|
+
- **[Install](install.md)** — `uv tool install`, slim vs full, extras, Windows quoting
|
|
10
|
+
- **[Troubleshooting](troubleshooting.md)** — every common gotcha with a fix
|
|
11
|
+
- **[Architecture](architecture.md)** — package layout, lazy imports, error model
|
|
12
|
+
|
|
13
|
+
## Subcommand groups
|
|
14
|
+
|
|
15
|
+
Tap a group to jump to its full reference.
|
|
16
|
+
|
|
17
|
+
### Media
|
|
18
|
+
|
|
19
|
+
| Group | What it does |
|
|
20
|
+
|---|---|
|
|
21
|
+
| **[`pt img`](img.md)** | Image format conversion (HEIC, AVIF, SVG, ...), resize, compress, EXIF, palette, watermark, ASCII art, **background removal**, OCR |
|
|
22
|
+
| **[`pt vid`](vid.md)** | Convert video/audio, trim, extract audio, animated GIF |
|
|
23
|
+
| **[`pt pdf`](pdf.md)** | Merge, split, compress, extract text, render to images, build from images, OCR |
|
|
24
|
+
| **[`pt dl`](dl.md)** | Download from YouTube and 1000+ sites (yt-dlp wrapper, audio-only mode) |
|
|
25
|
+
| **[`pt shot`](shot.md)** | Screen capture and full-page web screenshots |
|
|
26
|
+
| **[`pt qr`](qr.md)** | Generate QR codes (PNG/SVG/PDF/EPS/terminal), Wi-Fi join codes, decode |
|
|
27
|
+
|
|
28
|
+
### Text & data
|
|
29
|
+
|
|
30
|
+
| Group | What it does |
|
|
31
|
+
|---|---|
|
|
32
|
+
| **[`pt data`](data.md)** | Convert between JSON / YAML / TOML / CSV / XML; pretty-print; validate |
|
|
33
|
+
| **[`pt enc`](enc.md)** | Hash (sha*, xxhash, blake2b), base64, URL, HTML, JWT decode/verify |
|
|
34
|
+
| **[`pt text`](text.md)** | Diff, wc, case conversion, slugify, Markdown → HTML / preview |
|
|
35
|
+
| **[`pt convert`](convert.md)** | Unit conversion (pint), epoch ↔ ISO timestamp, number-base conversion |
|
|
36
|
+
| **[`pt color`](color.md)** | Color conversion (hex / rgb / hsl / hsv / cmyk) |
|
|
37
|
+
| **[`pt cron`](cron.md)** | Explain a cron expression in English; show next N firings |
|
|
38
|
+
|
|
39
|
+
### System
|
|
40
|
+
|
|
41
|
+
| Group | What it does |
|
|
42
|
+
|---|---|
|
|
43
|
+
| **[`pt file`](file.md)** | Batch rename, find duplicates, list big files, organize, archive (zip/tar/7z) |
|
|
44
|
+
| **[`pt gen`](gen.md)** | Strong passwords, UUIDs (v1/v3/v4/v5/v7), lorem ipsum |
|
|
45
|
+
| **[`pt net`](net.md)** | Port reachability, IP geolocation, HTTP request (httpie-like) |
|
|
46
|
+
| **[`pt clip`](clip.md)** | Read/write the system clipboard |
|
|
47
|
+
|
|
48
|
+
## Conventions used in these docs
|
|
49
|
+
|
|
50
|
+
- **`SOURCE`**, **`OUTPUT`** — uppercase = positional argument.
|
|
51
|
+
- **`--flag`**, **`-f`** — long and short option forms; both work.
|
|
52
|
+
- **`Default:`** — what happens when the option is omitted.
|
|
53
|
+
- **`Type:`** — `path`, `int`, `float`, `str`, `bool` (flag), or a closed `enum: a | b | c`.
|
|
54
|
+
- **`Required:`** — marked explicitly when not optional.
|
|
55
|
+
- **`Stdin:`** — every verb that accepts file input also accepts `-` (or omitting the path) to read stdin where it makes sense.
|
|
56
|
+
- **`Stdout:`** — verbs that produce text default to stdout when `--output` is omitted (you can pipe into other commands).
|
|
57
|
+
- **Exit codes** — `0` on success, `1` on user/data error (rendered as a red panel with a fix hint), `2` on argument parsing error (Typer default).
|
|
58
|
+
|
|
59
|
+
## Global options
|
|
60
|
+
|
|
61
|
+
These work for every subcommand:
|
|
62
|
+
|
|
63
|
+
| Flag | Type | Default | Purpose |
|
|
64
|
+
|---|---|---|---|
|
|
65
|
+
| `--version`, `-V` | flag | — | Print the polytool version and exit. |
|
|
66
|
+
| `--help` | flag | — | Show help for the current group/verb. Every leaf verb's help includes a runnable `Examples:` block. |
|
|
67
|
+
|
|
68
|
+
## How help is structured
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
pt --help # top-level: lists 16 groups
|
|
72
|
+
pt <group> --help # lists verbs in that group
|
|
73
|
+
pt <group> <verb> --help # full verb reference (matches the .md page)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Next steps
|
|
77
|
+
|
|
78
|
+
- Read **[install.md](install.md)** for the install paths and extras.
|
|
79
|
+
- Browse a group page above to see exact arguments and examples.
|
|
80
|
+
- Hit a problem? **[troubleshooting.md](troubleshooting.md)** has the answer for every common error.
|