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.
Files changed (28) hide show
  1. {devbits-1.2.0 → devbits-1.3.2}/PKG-INFO +92 -1
  2. devbits-1.3.2/README.md +220 -0
  3. {devbits-1.2.0 → devbits-1.3.2}/devbits/__init__.py +1 -1
  4. {devbits-1.2.0 → devbits-1.3.2}/devbits/cli.py +359 -0
  5. {devbits-1.2.0 → devbits-1.3.2}/devbits/scripts.py +4 -0
  6. devbits-1.3.2/devbits/tui.py +323 -0
  7. devbits-1.3.2/devbits/wifi.py +712 -0
  8. {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/PKG-INFO +92 -1
  9. {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/SOURCES.txt +5 -1
  10. {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/entry_points.txt +1 -0
  11. {devbits-1.2.0 → devbits-1.3.2}/pyproject.toml +2 -1
  12. devbits-1.3.2/tests/test_tui.py +236 -0
  13. devbits-1.3.2/tests/test_wifi.py +679 -0
  14. devbits-1.2.0/README.md +0 -129
  15. {devbits-1.2.0 → devbits-1.3.2}/LICENSE +0 -0
  16. {devbits-1.2.0 → devbits-1.3.2}/devbits/cache.py +0 -0
  17. {devbits-1.2.0 → devbits-1.3.2}/devbits/gui.py +0 -0
  18. {devbits-1.2.0 → devbits-1.3.2}/devbits/image.py +0 -0
  19. {devbits-1.2.0 → devbits-1.3.2}/devbits/media.py +0 -0
  20. {devbits-1.2.0 → devbits-1.3.2}/devbits/network.py +0 -0
  21. {devbits-1.2.0 → devbits-1.3.2}/devbits/project.py +0 -0
  22. {devbits-1.2.0 → devbits-1.3.2}/devbits/utils.py +0 -0
  23. {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/dependency_links.txt +0 -0
  24. {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/requires.txt +0 -0
  25. {devbits-1.2.0 → devbits-1.3.2}/devbits.egg-info/top_level.txt +0 -0
  26. {devbits-1.2.0 → devbits-1.3.2}/setup.cfg +0 -0
  27. {devbits-1.2.0 → devbits-1.3.2}/tests/test_cli.py +0 -0
  28. {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.0
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:
@@ -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
@@ -1,3 +1,3 @@
1
1
  """devbits: A lightweight CLI toolkit for daily development utilities."""
2
2
 
3
- __version__ = "1.2.0"
3
+ __version__ = "1.3.2"