Homepage (site/index.html): integration-v14 promoted, Writings section integrated with 33 pieces clustered by type (stories/essays/miscellany), Writings welcome lightbox, content frame at 98% opacity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
289 lines
11 KiB
Markdown
289 lines
11 KiB
Markdown
# Meshagora — Deployment & Troubleshooting
|
|
|
|
---
|
|
|
|
## Version History
|
|
|
|
### v0.2 — IP Detection & Startup Transparency
|
|
- Replaced UDP routing trick with `ifconfig` parsing for hotspot IP detection. The UDP trick failed on the Samsung A25 (and likely other Android builds) because the hotspot interface routing entry may not exist at startup. `ifconfig` reads interface addresses directly via socket ioctls — no netlink, no root, no routing assumptions.
|
|
- Startup banner now lists all detected non-loopback IPs with interface names, so if the primary guess is wrong the alternatives are immediately visible.
|
|
- Added `install_termux.sh` — one-shot setup script for Termux.
|
|
- Added `net-tools` as an explicit dependency (`ifconfig` provider).
|
|
|
|
### v0.1 — Initial prototype
|
|
- Single-file Flask app, in-memory SQLite, runs on Android/Termux hotspot.
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
### Termux (Android) — required packages
|
|
|
|
| Package | Source | Purpose |
|
|
|---------|--------|---------|
|
|
| `python` | `pkg` | Runtime |
|
|
| `net-tools` | `pkg` | `ifconfig` — hotspot IP detection |
|
|
| `libjpeg-turbo` | `pkg` | JPEG support for Pillow (required by `qrcode[pil]`) |
|
|
| `libpng` | `pkg` | PNG support for Pillow (required by `qrcode[pil]`) |
|
|
| `flask` | `pip` | Web framework |
|
|
| `qrcode[pil]` | `pip` | QR code generation at `/qr` |
|
|
|
|
### Desktop (testing only)
|
|
|
|
| Package | Source | Purpose |
|
|
|---------|--------|---------|
|
|
| `flask` | `pip` | Web framework |
|
|
| `qrcode[pil]` | `pip` | QR code generation |
|
|
|
|
`ifconfig` is standard on desktop Linux/macOS — no extra install needed.
|
|
|
|
---
|
|
|
|
## Quick Start (Termux)
|
|
|
|
**First time only — install dependencies:**
|
|
```
|
|
bash install_termux.sh
|
|
```
|
|
Or manually:
|
|
```
|
|
pkg install python net-tools libjpeg-turbo libpng
|
|
pip install flask "qrcode[pil]"
|
|
```
|
|
|
|
**Every session:**
|
|
1. Enable Android mobile hotspot.
|
|
2. Open Termux and run:
|
|
```
|
|
python3 meshagora.py
|
|
```
|
|
3. Read the startup banner — note all three keys and the Join URL.
|
|
4. Open `http://[IP]:5000/qr` on the server device and display it for participants to scan.
|
|
5. Once everyone has joined, go to `/admin` → HIDE QR.
|
|
|
|
---
|
|
|
|
## Starting the Server
|
|
|
|
1. **Enable the Android mobile hotspot before running the script.**
|
|
IP detection reads active interfaces at startup — if the hotspot is off, the banner URL will be wrong.
|
|
|
|
2. Run:
|
|
```
|
|
python3 meshagora.py
|
|
```
|
|
|
|
3. The startup banner prints:
|
|
```
|
|
==================================================
|
|
MESHAGORA v2.3 — SOCIAL SANDBOX
|
|
Admin Post Key : [4 emoji]
|
|
Trusted Post Key : [2 emoji]
|
|
Default Post Key : [2 emoji]
|
|
--------------------------------------------------
|
|
Join URL : http://192.168.43.1:5000/join (wlan0)
|
|
Also try : http://10.0.2.5:5000/join (rmnet0)
|
|
QR code : http://192.168.43.1:5000/qr
|
|
If no URL works, run: ifconfig | grep inet
|
|
==================================================
|
|
```
|
|
Write down or photograph all three keys. They cannot be recovered without restarting the server (which destroys the session).
|
|
|
|
**Reading the banner:**
|
|
- "Join URL" is the best-guess hotspot address (`192.168.x.x` preferred).
|
|
- "Also try" lines show other detected interfaces. The `rmnet` / `10.x.x.x` entries are mobile data — participants on the hotspot WiFi cannot reach those.
|
|
- Samsung A25 hotspot is typically `192.168.43.1` on `wlan0`.
|
|
|
|
4. Navigate to `http://[IP]:5000/qr` on the server device and display the QR code for participants to scan.
|
|
|
|
5. Once all participants have joined, hide the QR code from the Admin Panel (`/admin` → HIDE QR).
|
|
|
|
---
|
|
|
|
## Connecting Participants
|
|
|
|
Participants need to:
|
|
1. Join the hotspot WiFi (name set by the server device's hotspot settings).
|
|
2. Open a browser and scan the QR code, or type the Join URL from the banner.
|
|
3. Go to `/join` — choose a username, Profile Key (2 emoji), and Friend Key (2 emoji).
|
|
|
|
No app install required. Works on any browser from Android 7.0+, iOS Safari, desktop Chrome/Firefox.
|
|
|
|
---
|
|
|
|
## Admin Panel
|
|
|
|
Navigate to `/admin` from any browser connected to the hotspot.
|
|
Enter the 4-emoji Admin Post Key when prompted. Authentication persists for that browser session.
|
|
|
|
**Actions available:**
|
|
- Restrict / Unrestrict / Promote / Demote individual users
|
|
- View the current Default Post Key (large, readable — copy to board or announce verbally)
|
|
- Rotate Default Key manually
|
|
- Trigger Flood Attack (creates 5 bot accounts with posts)
|
|
- Show / Hide the join QR code
|
|
- View raw database tables (users, posts, votes, reports, keys)
|
|
- **WHAT THE PLATFORM SEES** — surveillance dashboard (scroll to bottom of admin panel):
|
|
- *Deanonymization table*: maps every session label (Anon #N) to real username, tier, post count, and net score
|
|
- *Social graph*: all handshake pairs with CONFIRMED / PENDING status
|
|
- *Behavioral correlations*: who voted for whom and who reported whom, cross-referenced with confirmed friendships — project mid-session for maximum pedagogical impact
|
|
|
|
---
|
|
|
|
## Stopping the Server
|
|
|
|
`Ctrl+C` in the Termux terminal. The in-memory database is destroyed immediately.
|
|
There is no persistent storage — every session starts clean.
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Server prints `127.0.0.1` instead of the hotspot IP
|
|
|
|
**Important:** `127.0.0.1` is the loopback address — it only works in the browser on the server device itself. Participants on other devices will get "connection refused". Flask is still listening on all interfaces (`0.0.0.0`), so the server is reachable — you just need the correct IP.
|
|
|
|
**Step 1:** Enable the mobile hotspot *before* running `python3 meshagora.py`, then restart. The hotspot interface only appears after the hotspot is on.
|
|
|
|
**Step 2:** If still wrong, check all interfaces manually:
|
|
```
|
|
ifconfig | grep inet
|
|
```
|
|
Look for an address like `192.168.43.1` under `wlan0` — that's the hotspot gateway. Ignore `127.0.0.1` (loopback) and `10.x.x.x` under `rmnet` (mobile data).
|
|
|
|
Note: `ip addr` fails in Termux with "cannot bind netlink socket: permission denied" — always use `ifconfig` instead.
|
|
|
|
**Step 3:** Navigate to `http://[correct-ip]:5000/join` directly and distribute that URL to participants.
|
|
|
|
**Samsung A-series:** The A25 hotspot is typically `192.168.43.1` on `wlan0`. If the banner's "Join URL" shows a different address, check the "Also try" lines for the `192.168.43.1` entry.
|
|
|
|
---
|
|
|
|
### `ModuleNotFoundError: No module named 'qrcode'`
|
|
|
|
```
|
|
pip install "qrcode[pil]"
|
|
```
|
|
|
|
If it installs but the error persists:
|
|
```
|
|
python3 -m pip install "qrcode[pil]"
|
|
```
|
|
|
|
The server runs without qrcode — `/qr` returns a 404. Participants can type the join URL directly.
|
|
|
|
---
|
|
|
|
### `ModuleNotFoundError: No module named 'flask'`
|
|
|
|
```
|
|
pip install flask
|
|
```
|
|
|
|
---
|
|
|
|
### `ifconfig` command not found
|
|
|
|
```
|
|
pkg install net-tools
|
|
```
|
|
|
|
This is required for hotspot IP detection in Termux. Without it, the banner will fall back to `127.0.0.1`.
|
|
|
|
---
|
|
|
|
### Port 5000 already in use
|
|
|
|
Common on macOS (AirPlay Receiver uses 5000).
|
|
|
|
**Option A:** Kill the other process:
|
|
```
|
|
lsof -i :5000
|
|
kill [PID]
|
|
```
|
|
|
|
**Option B:** Change the port at the bottom of `meshagora.py`:
|
|
```python
|
|
app.run(host='0.0.0.0', port=5001, debug=False, threaded=False)
|
|
```
|
|
Update the join URL accordingly.
|
|
|
|
---
|
|
|
|
### Participants can't reach the server
|
|
|
|
1. Confirm participants are connected to the *hotspot WiFi*, not their mobile data or a different network.
|
|
2. Confirm the IP in the banner matches `ifconfig | grep inet` output for the `wlan0` interface.
|
|
3. Confirm port 5000 is not blocked by a firewall. On Termux this is rarely an issue on a local hotspot.
|
|
4. Try navigating to the URL from the server device's own browser first to confirm the server is responding.
|
|
|
|
---
|
|
|
|
### Android kills the server mid-session (Termux background kill)
|
|
|
|
Android aggressively kills background processes to save battery.
|
|
|
|
**Prevention:**
|
|
- In Android Settings → Apps → Termux → Battery → set to "Unrestricted" (wording varies by device).
|
|
- Keep Termux in the foreground with the screen on, or acquire a wakelock:
|
|
```
|
|
termux-wake-lock
|
|
```
|
|
(Requires the Termux:API app from F-Droid.)
|
|
- Keep the server device plugged in to power.
|
|
|
|
If the server is killed, all session data is lost. Restart with `python3 meshagora.py` — all keys rotate, all users must rejoin.
|
|
|
|
---
|
|
|
|
### Default Post Key stopped working for everyone
|
|
|
|
A user was restricted (by admin action or by 51% community reports). The Default Post Key rotates silently on every restriction. Check the Admin Panel for the new key and distribute it.
|
|
|
|
---
|
|
|
|
### Emoji picker doesn't appear / looks broken
|
|
|
|
The emoji picker is rendered as inline HTML buttons with basic CSS. No JavaScript framework required.
|
|
|
|
- If buttons appear but emoji don't render: the device font doesn't support those codepoints. This is rare on Android 7.0+ but possible on stripped-down browsers. Participants can type emoji directly into the visible input field.
|
|
- If the grid looks misaligned: the scroll container (`max-height: 160px; overflow-y: auto`) is intentional. Scroll within the picker to see all emoji.
|
|
|
|
---
|
|
|
|
### Post fails with "Post key incorrect." for a RESTRICTED user
|
|
|
|
RESTRICTED users require an admin co-sign. The admin must communicate the Admin Post Key directly to the restricted user for them to post. This is by design — it represents supervised posting access.
|
|
|
|
---
|
|
|
|
### Handshake says "One or both keys are incorrect."
|
|
|
|
- Both participants must submit from their own accounts (you cannot complete both sides from one account).
|
|
- Emoji must match exactly — the picker submits codepoints, not descriptions.
|
|
- Try clearing both fields and reselecting. The CLEAR button resets the hidden input.
|
|
- Verify both participants have submitted independently.
|
|
|
|
---
|
|
|
|
## Testing Checklist (Pre-Session)
|
|
|
|
- [ ] Hotspot enabled before starting server — correct IP appears in banner
|
|
- [ ] `/qr` loads a scannable QR code from the server device
|
|
- [ ] Join as User 1 from a phone — "Anon #1" assigned, Default Post Key shown on join confirmation
|
|
- [ ] Join as User 2 from a second device or incognito tab — "Anon #2" assigned
|
|
- [ ] Post from User 1 with correct Default Post Key — appears in feed
|
|
- [ ] Post from User 1 with wrong key — "Post key incorrect." error
|
|
- [ ] Vote from User 2 — score updates
|
|
- [ ] Report from User 2 — spoiler overlay appears, User 1 sees notification banner
|
|
- [ ] Admin panel accessible at `/admin` with 4-emoji Admin Post Key
|
|
- [ ] Admin restricts User 1 — Default Post Key rotates (new key visible in admin panel)
|
|
- [ ] User 1 post fails with old key, succeeds with new key (or admin co-sign)
|
|
- [ ] Handshake between User 1 and User 2 — confirmed, username appears on posts for the friend
|
|
- [ ] Friends-only toggle shows only friend posts
|
|
- [ ] Profile notes edit blocked without Profile Key, succeeds with correct key
|
|
- [ ] Hide QR via admin → `/qr` returns 404
|
|
- [ ] Flood Attack → 5 bot posts appear in feed
|
|
- [ ] Scroll to "WHAT THE PLATFORM SEES" in admin panel — all three panels render (deanonymization, social graph, behavioral correlations)
|
|
- [ ] Confirm panels are empty (no crash) on a fresh session with no posts/votes/reports
|