devbits 1.2.0__tar.gz → 1.3.2__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.
- {devbits-1.2.0 → devbits-1.3.2}/PKG-INFO +92 -1
- devbits-1.3.2/README.md +220 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits/__init__.py +1 -1
- {devbits-1.2.0 → devbits-1.3.2}/devbits/cli.py +359 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits/scripts.py +4 -0
- devbits-1.3.2/devbits/tui.py +323 -0
- devbits-1.3.2/devbits/wifi.py +712 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/PKG-INFO +92 -1
- {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/SOURCES.txt +5 -1
- {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/entry_points.txt +1 -0
- {devbits-1.2.0 → devbits-1.3.2}/pyproject.toml +2 -1
- devbits-1.3.2/tests/test_tui.py +236 -0
- devbits-1.3.2/tests/test_wifi.py +679 -0
- devbits-1.2.0/README.md +0 -129
- {devbits-1.2.0 → devbits-1.3.2}/LICENSE +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits/cache.py +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits/gui.py +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits/image.py +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits/media.py +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits/network.py +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits/project.py +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits/utils.py +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/dependency_links.txt +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/requires.txt +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/top_level.txt +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/setup.cfg +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/tests/test_cli.py +0 -0
- {devbits-1.2.0 → devbits-1.3.2}/tests/test_gui_cli.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devbits
|
|
3
|
-
Version: 1.2
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: A lightweight CLI toolkit for daily development utilities.
|
|
5
5
|
Author: Bruce Chuang
|
|
6
6
|
License-Expression: MIT
|
|
@@ -85,6 +85,7 @@ clipvideo --help
|
|
|
85
85
|
| Command | Description |
|
|
86
86
|
|---------|-------------|
|
|
87
87
|
| `netscan` | List devices connected to your local network (Wi-Fi / router) with their IP, MAC, and hostname. `--lookup` adds the manufacturer. |
|
|
88
|
+
| `wifi` | Manage Wi-Fi: `list`, `connect` (arrow-key picker + hidden password prompt), `on`, `off`, `forget`. Linux and Windows fully; macOS without `list`. |
|
|
88
89
|
|
|
89
90
|
## Examples
|
|
90
91
|
|
|
@@ -122,6 +123,22 @@ netscan --lookup
|
|
|
122
123
|
|
|
123
124
|
# Scan a specific subnet, faster, without hostname lookups
|
|
124
125
|
netscan --network 192.168.1.0/24 --timeout 0.5 --no-resolve
|
|
126
|
+
|
|
127
|
+
# Show the Wi-Fi networks in range (Linux / Windows)
|
|
128
|
+
wifi list
|
|
129
|
+
|
|
130
|
+
# Pick a Wi-Fi network with the arrow keys, then type the password
|
|
131
|
+
wifi connect
|
|
132
|
+
|
|
133
|
+
# Join a specific network without the picker
|
|
134
|
+
wifi connect MyHome-5G
|
|
135
|
+
|
|
136
|
+
# Turn the Wi-Fi radio on / off
|
|
137
|
+
wifi on
|
|
138
|
+
wifi off
|
|
139
|
+
|
|
140
|
+
# Stop a network from auto-connecting
|
|
141
|
+
wifi forget OldCafe
|
|
125
142
|
```
|
|
126
143
|
|
|
127
144
|
> `netscan` reports IP, MAC, hostname and (with `--lookup`) the hardware
|
|
@@ -129,6 +146,80 @@ netscan --network 192.168.1.0/24 --timeout 0.5 --no-resolve
|
|
|
129
146
|
> laptops that use a randomized/private MAC show up as `(private)` and can't be
|
|
130
147
|
> attributed to a vendor.
|
|
131
148
|
|
|
149
|
+
### Wi-Fi
|
|
150
|
+
|
|
151
|
+
`wifi connect` lists everything in range — move with ↑/↓, press Enter to join,
|
|
152
|
+
Esc to cancel. The password prompt is hidden, skipped for open networks, and
|
|
153
|
+
skipped again for networks your system already remembers. When stdout isn't a
|
|
154
|
+
terminal the picker degrades to a numbered prompt, so the command still works
|
|
155
|
+
over pipes and in scripts.
|
|
156
|
+
|
|
157
|
+
Each subcommand drives the platform's own tooling, so no extra dependency or
|
|
158
|
+
driver access is needed:
|
|
159
|
+
|
|
160
|
+
| OS | Tooling used | Notes |
|
|
161
|
+
|----|--------------|-------|
|
|
162
|
+
| Linux | `nmcli` (NetworkManager) | The Ubuntu default. Systems without NetworkManager aren't supported. See the sudo note below. |
|
|
163
|
+
| Windows | `netsh` | `wifi on` / `wifi off` enable and disable the adapter, which needs an Administrator terminal. |
|
|
164
|
+
| macOS | `networksetup` | **No scanning** — see below. `connect`, `on`, `off` and `forget` all work; `wifi forget` edits the preferred-networks list and may need `sudo`. |
|
|
165
|
+
|
|
166
|
+
### Scanning support
|
|
167
|
+
|
|
168
|
+
| | `list` | `connect <ssid>` | `connect` (picker) | `on` / `off` | `forget` |
|
|
169
|
+
|---|---|---|---|---|---|
|
|
170
|
+
| Linux | ✅ | ✅ | networks in range | ✅ | ✅ |
|
|
171
|
+
| Windows | ✅ | ✅ | networks in range | ✅ | ✅ |
|
|
172
|
+
| macOS | ❌ | ✅ | saved networks | ✅ | ✅ |
|
|
173
|
+
|
|
174
|
+
> `--password` exists for automation but lands in your shell history — prefer the
|
|
175
|
+
> interactive prompt. On Linux, NetworkManager itself takes the passphrase as a
|
|
176
|
+
> command-line argument, so it is briefly visible in the process list.
|
|
177
|
+
|
|
178
|
+
#### Linux: polkit and sudo
|
|
179
|
+
|
|
180
|
+
NetworkManager's polkit rules usually let a local desktop session toggle Wi-Fi
|
|
181
|
+
without a password, but deny the same thing over SSH. When an operation is
|
|
182
|
+
refused, `wifi` says so and re-runs **just that `nmcli` command** under `sudo`,
|
|
183
|
+
which prompts for your password on the terminal:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
Error: Failed to set radio: Not authorized to enable/disable WiFi.
|
|
187
|
+
Retrying with sudo (you may be asked for your password) ...
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The escalation only happens on an interactive terminal. In a script or pipeline
|
|
191
|
+
the command fails with the permission error instead of hanging on a prompt.
|
|
192
|
+
|
|
193
|
+
> If you have a shell function or alias named `wifi` (a common `nmcli` wrapper),
|
|
194
|
+
> it takes precedence over this command — shell functions win over `PATH`. Use
|
|
195
|
+
> `devbits wifi ...`, or remove the function.
|
|
196
|
+
|
|
197
|
+
#### macOS: no scanning
|
|
198
|
+
|
|
199
|
+
`wifi list` is unsupported on macOS, and `wifi connect` without an SSID picks
|
|
200
|
+
from the networks this Mac already **remembers** rather than what's in range:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
$ devbits wifi connect
|
|
204
|
+
Listing nearby Wi-Fi networks is not supported on macOS. ...
|
|
205
|
+
|
|
206
|
+
Falling back to your saved networks.
|
|
207
|
+
Select a network to join:
|
|
208
|
+
❯ MyHome-5G (saved)
|
|
209
|
+
CoffeeShop (saved)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Joining by name — `wifi connect MyHome-5G` — always works, as do `on`, `off`
|
|
213
|
+
and `forget`.
|
|
214
|
+
|
|
215
|
+
The reason is that the last remaining macOS API that enumerates networks,
|
|
216
|
+
`system_profiler SPAirPortDataType`, replaces every SSID with the literal string
|
|
217
|
+
`<redacted>` unless the calling process holds Location Services authorization.
|
|
218
|
+
That is a TCC privacy permission, not a file permission: `sudo` does not bypass
|
|
219
|
+
it, the authorization database is SIP-protected, and a CLI cannot request it —
|
|
220
|
+
only a bundled app linking CoreLocation can. Rather than ship a pyobjc
|
|
221
|
+
dependency for one platform, devbits doesn't scan on macOS at all.
|
|
222
|
+
|
|
132
223
|
## Output Defaults
|
|
133
224
|
|
|
134
225
|
When `-o` / `--output` is omitted, the output filename is derived from the input:
|
devbits-1.3.2/README.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# devbits
|
|
2
|
+
|
|
3
|
+
A lightweight CLI toolkit for daily development utilities — video/image processing, project file management, and more.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install devbits
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Python ≥ 3.9.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
All commands are available in two ways:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# As subcommands of devbits
|
|
19
|
+
devbits <command> [options]
|
|
20
|
+
|
|
21
|
+
# As standalone commands
|
|
22
|
+
<command> [options]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Use `--help` on any command for detailed usage and parameter descriptions:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
devbits clipvideo --help
|
|
29
|
+
clipvideo --help
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Commands
|
|
33
|
+
|
|
34
|
+
### Video
|
|
35
|
+
|
|
36
|
+
| Command | Description |
|
|
37
|
+
|---------|-------------|
|
|
38
|
+
| `clipvideo` | Trim a video by time (seconds) or frame range. Includes `--gui` for browser-based editing. |
|
|
39
|
+
| `video2images` | Extract frames from a video. |
|
|
40
|
+
| `video2gif` | Convert a video (or a portion) to animated GIF. |
|
|
41
|
+
| `images2video` | Assemble an image sequence into an MP4 video. |
|
|
42
|
+
| `images2gif` | Assemble an image sequence into an animated GIF. |
|
|
43
|
+
| `resizevideo` | Re-encode a video at a different resolution. |
|
|
44
|
+
|
|
45
|
+
### Image
|
|
46
|
+
|
|
47
|
+
| Command | Description |
|
|
48
|
+
|---------|-------------|
|
|
49
|
+
| `resizeimage` | Resize a single image (preserves aspect ratio by default). |
|
|
50
|
+
| `recolor` | Recolor a logo/icon foreground, leaving the background intact. |
|
|
51
|
+
| `image2ico` | Convert an image to a multi-size ICO file. |
|
|
52
|
+
| `batchimages` | Batch resize or convert all images in a folder. |
|
|
53
|
+
| `checkimages` | Scan for broken / corrupt image files. |
|
|
54
|
+
| `contactsheet` | Generate a thumbnail grid (contact sheet) from a folder of images. |
|
|
55
|
+
|
|
56
|
+
### Project / Files
|
|
57
|
+
|
|
58
|
+
| Command | Description |
|
|
59
|
+
|---------|-------------|
|
|
60
|
+
| `clearcache` | Remove `__pycache__` and other Python cache directories. |
|
|
61
|
+
| `tree` | Print a directory tree. |
|
|
62
|
+
| `size` | List the largest files / folders, sorted by size. |
|
|
63
|
+
| `renamefiles` | Batch rename files sequentially. |
|
|
64
|
+
| `samplefiles` | Copy or move the first N files to another folder. |
|
|
65
|
+
|
|
66
|
+
### Network
|
|
67
|
+
|
|
68
|
+
| Command | Description |
|
|
69
|
+
|---------|-------------|
|
|
70
|
+
| `netscan` | List devices connected to your local network (Wi-Fi / router) with their IP, MAC, and hostname. `--lookup` adds the manufacturer. |
|
|
71
|
+
| `wifi` | Manage Wi-Fi: `list`, `connect` (arrow-key picker + hidden password prompt), `on`, `off`, `forget`. Linux and Windows fully; macOS without `list`. |
|
|
72
|
+
|
|
73
|
+
## Examples
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Trim video from 5s to 20s
|
|
77
|
+
clipvideo movie.mp4 --start 5.0 --end 20.0
|
|
78
|
+
|
|
79
|
+
# Open interactive clip editor in the browser
|
|
80
|
+
clipvideo movie.mp4 --gui
|
|
81
|
+
|
|
82
|
+
# Convert video to GIF (3.5s–10s at 15 fps)
|
|
83
|
+
video2gif movie.mp4 --start 3.5 --end 10.0 --fps 15
|
|
84
|
+
|
|
85
|
+
# Extract every 5th frame as PNG
|
|
86
|
+
video2images movie.mp4 --every 5 --format png
|
|
87
|
+
|
|
88
|
+
# Recolor a logo's foreground to black (keeps the background)
|
|
89
|
+
recolor logo.png
|
|
90
|
+
|
|
91
|
+
# Recolor a logo's foreground to a custom color (hex or R,G,B)
|
|
92
|
+
recolor logo.png --color '#1a73e8'
|
|
93
|
+
recolor logo.png --color 0,178,179
|
|
94
|
+
|
|
95
|
+
# Batch resize images to 800×600
|
|
96
|
+
batchimages ./photos -o ./resized --size 800,600
|
|
97
|
+
|
|
98
|
+
# Clean Python caches
|
|
99
|
+
clearcache . --all
|
|
100
|
+
|
|
101
|
+
# List every device on your local network
|
|
102
|
+
netscan
|
|
103
|
+
|
|
104
|
+
# Also identify each device's manufacturer (online OUI lookup)
|
|
105
|
+
netscan --lookup
|
|
106
|
+
|
|
107
|
+
# Scan a specific subnet, faster, without hostname lookups
|
|
108
|
+
netscan --network 192.168.1.0/24 --timeout 0.5 --no-resolve
|
|
109
|
+
|
|
110
|
+
# Show the Wi-Fi networks in range (Linux / Windows)
|
|
111
|
+
wifi list
|
|
112
|
+
|
|
113
|
+
# Pick a Wi-Fi network with the arrow keys, then type the password
|
|
114
|
+
wifi connect
|
|
115
|
+
|
|
116
|
+
# Join a specific network without the picker
|
|
117
|
+
wifi connect MyHome-5G
|
|
118
|
+
|
|
119
|
+
# Turn the Wi-Fi radio on / off
|
|
120
|
+
wifi on
|
|
121
|
+
wifi off
|
|
122
|
+
|
|
123
|
+
# Stop a network from auto-connecting
|
|
124
|
+
wifi forget OldCafe
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
> `netscan` reports IP, MAC, hostname and (with `--lookup`) the hardware
|
|
128
|
+
> **manufacturer** — a network scan can't read a device's CPU/RAM/OS. Phones and
|
|
129
|
+
> laptops that use a randomized/private MAC show up as `(private)` and can't be
|
|
130
|
+
> attributed to a vendor.
|
|
131
|
+
|
|
132
|
+
### Wi-Fi
|
|
133
|
+
|
|
134
|
+
`wifi connect` lists everything in range — move with ↑/↓, press Enter to join,
|
|
135
|
+
Esc to cancel. The password prompt is hidden, skipped for open networks, and
|
|
136
|
+
skipped again for networks your system already remembers. When stdout isn't a
|
|
137
|
+
terminal the picker degrades to a numbered prompt, so the command still works
|
|
138
|
+
over pipes and in scripts.
|
|
139
|
+
|
|
140
|
+
Each subcommand drives the platform's own tooling, so no extra dependency or
|
|
141
|
+
driver access is needed:
|
|
142
|
+
|
|
143
|
+
| OS | Tooling used | Notes |
|
|
144
|
+
|----|--------------|-------|
|
|
145
|
+
| Linux | `nmcli` (NetworkManager) | The Ubuntu default. Systems without NetworkManager aren't supported. See the sudo note below. |
|
|
146
|
+
| Windows | `netsh` | `wifi on` / `wifi off` enable and disable the adapter, which needs an Administrator terminal. |
|
|
147
|
+
| macOS | `networksetup` | **No scanning** — see below. `connect`, `on`, `off` and `forget` all work; `wifi forget` edits the preferred-networks list and may need `sudo`. |
|
|
148
|
+
|
|
149
|
+
### Scanning support
|
|
150
|
+
|
|
151
|
+
| | `list` | `connect <ssid>` | `connect` (picker) | `on` / `off` | `forget` |
|
|
152
|
+
|---|---|---|---|---|---|
|
|
153
|
+
| Linux | ✅ | ✅ | networks in range | ✅ | ✅ |
|
|
154
|
+
| Windows | ✅ | ✅ | networks in range | ✅ | ✅ |
|
|
155
|
+
| macOS | ❌ | ✅ | saved networks | ✅ | ✅ |
|
|
156
|
+
|
|
157
|
+
> `--password` exists for automation but lands in your shell history — prefer the
|
|
158
|
+
> interactive prompt. On Linux, NetworkManager itself takes the passphrase as a
|
|
159
|
+
> command-line argument, so it is briefly visible in the process list.
|
|
160
|
+
|
|
161
|
+
#### Linux: polkit and sudo
|
|
162
|
+
|
|
163
|
+
NetworkManager's polkit rules usually let a local desktop session toggle Wi-Fi
|
|
164
|
+
without a password, but deny the same thing over SSH. When an operation is
|
|
165
|
+
refused, `wifi` says so and re-runs **just that `nmcli` command** under `sudo`,
|
|
166
|
+
which prompts for your password on the terminal:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
Error: Failed to set radio: Not authorized to enable/disable WiFi.
|
|
170
|
+
Retrying with sudo (you may be asked for your password) ...
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The escalation only happens on an interactive terminal. In a script or pipeline
|
|
174
|
+
the command fails with the permission error instead of hanging on a prompt.
|
|
175
|
+
|
|
176
|
+
> If you have a shell function or alias named `wifi` (a common `nmcli` wrapper),
|
|
177
|
+
> it takes precedence over this command — shell functions win over `PATH`. Use
|
|
178
|
+
> `devbits wifi ...`, or remove the function.
|
|
179
|
+
|
|
180
|
+
#### macOS: no scanning
|
|
181
|
+
|
|
182
|
+
`wifi list` is unsupported on macOS, and `wifi connect` without an SSID picks
|
|
183
|
+
from the networks this Mac already **remembers** rather than what's in range:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
$ devbits wifi connect
|
|
187
|
+
Listing nearby Wi-Fi networks is not supported on macOS. ...
|
|
188
|
+
|
|
189
|
+
Falling back to your saved networks.
|
|
190
|
+
Select a network to join:
|
|
191
|
+
❯ MyHome-5G (saved)
|
|
192
|
+
CoffeeShop (saved)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Joining by name — `wifi connect MyHome-5G` — always works, as do `on`, `off`
|
|
196
|
+
and `forget`.
|
|
197
|
+
|
|
198
|
+
The reason is that the last remaining macOS API that enumerates networks,
|
|
199
|
+
`system_profiler SPAirPortDataType`, replaces every SSID with the literal string
|
|
200
|
+
`<redacted>` unless the calling process holds Location Services authorization.
|
|
201
|
+
That is a TCC privacy permission, not a file permission: `sudo` does not bypass
|
|
202
|
+
it, the authorization database is SIP-protected, and a CLI cannot request it —
|
|
203
|
+
only a bundled app linking CoreLocation can. Rather than ship a pyobjc
|
|
204
|
+
dependency for one platform, devbits doesn't scan on macOS at all.
|
|
205
|
+
|
|
206
|
+
## Output Defaults
|
|
207
|
+
|
|
208
|
+
When `-o` / `--output` is omitted, the output filename is derived from the input:
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
clipvideo movie.mp4 → movie_clip.mp4
|
|
212
|
+
video2gif movie.mp4 → movie.gif
|
|
213
|
+
resizeimage photo.jpg → photo_resized.jpg
|
|
214
|
+
recolor logo.png → logo_revised.png
|
|
215
|
+
contactsheet ./photos → photos_sheet.jpg
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|