for assorted things
1some python scripts that are sometimes helpful to me
2
3### run a script
4only general requirement is [`uv`](https://docs.astral.sh/uv/getting-started/installation/)
5
6```bash
7chmod +x <script-name>
8./<script-name> <...>
9```
10
11## scripts
12
13- [`analyze-github-followers`](#analyze-github-followers)
14- [`check-files-for-bad-links`](#check-files-for-bad-links)
15- [`dm-me-when-a-flight-passes-over`](#dm-me-when-a-flight-passes-over)
16- [`find-longest-bsky-thread`](#find-longest-bsky-thread)
17- [`find-stale-bsky-follows`](#find-stale-bsky-follows)
18- [`kill-processes`](#kill-processes)
19- [`predict-github-stars`](#predict-github-stars)
20- [`update-lights`](#update-lights)
21- [`update-readme`](#update-readme)
22
23---
24
25### `analyze-github-followers`
26
27analyze your github followers and following.
28
29usage:
30 ./analyze-github-followers
31 ./analyze-github-followers --summary-only # skip detailed analysis
32
33details:
34- uses github rest api to fetch followers/following
35- shows rich tables with follower stats
36- identifies mutual follows, notable followers, etc.
37- requires GITHUB_TOKEN in .env file
38
39---
40
41### `check-files-for-bad-links`
42
43Check files for bad links.
44
45Usage:
46
47```bash
48./check-files-for-bad-links *.md
49```
50
51Details:
52- uses [`httpx`](https://www.python-httpx.org/) to check links
53- uses [`anyio`](https://anyio.readthedocs.io/en/stable/) to run the checks concurrently
54- pass include globs to scan (e.g. `*.md`)
55- pass exclude globs to skip (e.g. `*.md`)
56- pass ignore-url prefixes to ignore (e.g. `http://localhost` or `https://localhost`)
57- pass concurrency to run the checks concurrently (default is 50)
58
59---
60
61### `dm-me-when-a-flight-passes-over`
62
63Monitor flights passing overhead and send BlueSky DMs.
64
65Usage:
66 # Single user mode (backward compatible)
67 ./dm-me-when-a-flight-passes-over
68
69 # Multi-subscriber mode with JSON file
70 ./dm-me-when-a-flight-passes-over --subscribers subscribers.json
71
72 # Multi-subscriber mode with stdin
73 echo '[{"handle": "user1.bsky.social", "latitude": 41.8781, "longitude": -87.6298, "radius_miles": 5}]' | ./dm-me-when-a-flight-passes-over --subscribers -
74
75This script monitors flights within a configurable radius and sends DMs on BlueSky
76when flights pass overhead. Supports multiple subscribers with different locations.
77
78## Future Architecture Ideas
79
80### Web App Deployment Options
81
821. **FastAPI + Fly.io/Railway/Render**
83 - REST API with endpoints:
84 - POST /subscribe - Register user with BlueSky handle
85 - DELETE /unsubscribe - Remove subscription
86 - POST /update-location - Update user's location
87 - GET /status - Check subscription status
88 - Background worker using Celery/RQ/APScheduler
89 - PostgreSQL/SQLite for subscriber persistence
90 - Redis for caching flight data & deduplication
91
922. **Vercel/Netlify Edge Functions**
93 - Serverless approach with scheduled cron jobs
94 - Use Vercel KV or Upstash Redis for state
95 - Challenge: Long-running monitoring needs workarounds
96 - Solution: Trigger checks via cron every minute
97
983. **Self-Hosted with ngrok/Cloudflare Tunnel**
99 - Quick prototype option
100 - Run this script as daemon
101 - Expose simple Flask/FastAPI wrapper
102 - Security concerns: rate limiting, auth required
103
104### Mobile/Browser Integration
105
1061. **Progressive Web App (PWA)**
107 - Service worker for background location updates
108 - Geolocation API for current position
109 - Push notifications instead of/alongside DMs
110 - IndexedDB for offline capability
111
1122. **iOS Shortcuts Integration**
113 - Create shortcut that gets location
114 - Calls webhook with location + BlueSky handle
115 - Could run automatically based on focus modes
116
1173. **Browser Extension**
118 - Background script polls location
119 - Lighter weight than full app
120 - Cross-platform solution
121
122### Architecture Components
123
1241. **Location Services Layer**
125 - Browser Geolocation API
126 - IP-based geolocation fallback
127 - Manual location picker UI
128 - Privacy: Only send location when checking flights
129
1302. **Notification Options**
131 - BlueSky DMs (current)
132 - Web Push Notifications
133 - Webhooks to other services
134 - Email/SMS via Twilio/SendGrid
135
1363. **Subscription Management**
137 - OAuth with BlueSky for auth
138 - User preferences: radius, notification types
139 - Quiet hours/Do Not Disturb
140 - Rate limiting per user
141
1424. **Data Optimization**
143 - Cache FlightRadar API responses
144 - Batch location updates
145 - Aggregate nearby users for efficiency
146 - WebSocket for real-time updates
147
148### Implementation Approach
149
150Phase 1: Web API Wrapper
151- FastAPI with /subscribe endpoint
152- SQLite for subscribers
153- Run monitoring in background thread
154- Deploy to Fly.io free tier
155
156Phase 2: Web UI
157- Simple React/Vue form
158- Geolocation permission request
159- Show nearby flights on map
160- Subscription management
161
162Phase 3: Mobile Experience
163- PWA with service workers
164- Background location updates
165- Local notifications
166- Offline support
167
168### Security Considerations
169- Rate limit FlightRadar API calls
170- Authenticate BlueSky handles
171- Validate location bounds
172- Prevent subscription spam
173- GDPR compliance for location data
174
175---
176
177### `find-longest-bsky-thread`
178
179Find the longest reply thread from a Bluesky post.
180
181Usage:
182
183```bash
184./find-longest-bsky-thread https://bsky.app/profile/nerditry.bsky.social/post/3lnofix5nlc23
185```
186
187Details:
188- uses [`atproto`](https://github.com/MarshalX/atproto) to fetch the thread
189- uses [`jinja2`](https://github.com/pallets/jinja) to render the thread
190
191---
192
193### `find-stale-bsky-follows`
194
195Find stale/inactive accounts among those you follow on Bluesky.
196
197Usage:
198
199```bash
200./find-stale-bsky-follows
201# or with custom inactivity threshold (days)
202./find-stale-bsky-follows --days 180
203```
204
205Details:
206- uses [`atproto`](https://github.com/MarshalX/atproto) to fetch following list
207- uses [`rich`](https://github.com/Textualize/rich) for pretty output
208- identifies accounts with no recent posts
209
210---
211
212### `kill-processes`
213
214AI-powered TUI for killing processes.
215
216Usage:
217
218```bash
219./kill-processes
220```
221
222Details:
223- uses [`textual`](https://textual.textualize.io/) for the TUI
224- uses [`marvin`](https://github.com/prefecthq/marvin) (built on [`pydantic-ai`](https://github.com/pydantic/pydantic-ai)) to annotate processes
225
226---
227
228### `predict-github-stars`
229
230Predict when a GitHub repository will reach a target number of stars.
231
232Usage:
233 ./predict-github-stars owner/repo 10000
234
235Details:
236- Uses GitHub REST API to fetch star history (with timestamps).
237- Fits polynomial regression (degree 1–3) to full history.
238- Falls back to recent‑trend linear extrapolation if the polynomial
239 cannot reach the target within ten years.
240- Shows recent growth rate and a caution for long‑range estimates.
241- Requires `GITHUB_TOKEN` in the environment for higher rate limits (optional).
242
243---
244
245### `update-lights`
246
247Make some change to my phillips hue network of lights via agent + MCP server.
248
249Usage:
250
251```bash
252./update-lights -m "turn on sahara in the living room and nightlight in the kitchen"
253```
254
255Details:
256- uses a [`marvin`](https://github.com/prefecthq/marvin) (built on [`pydantic-ai`](https://github.com/pydantic/pydantic-ai)) agent
257- the agent spins up a [`fastmcp`](https://github.com/jlowin/fastmcp) MCP server that talks to my [`phue`](https://github.com/studioimaginaire/phue) bridge
258- set `HUE_BRIDGE_IP` and `HUE_BRIDGE_USERNAME` in `.env` or otherwise in environment
259- uses `OPENAI_API_KEY` by default, but you can set `AI_MODEL` in `.env` or otherwise in environment to use a different model
260
261---
262
263### `update-readme`
264
265Update the README.md file with a list of all the scripts in the current directory.
266
267Usage:
268
269```bash
270./update-readme
271```
272