From af530372f3b0dad36b64c21e70198c7a8cf64bc0 Mon Sep 17 00:00:00 2001 From: Steve Dudenhoeffer Date: Fri, 23 Jan 2026 00:53:46 -0500 Subject: [PATCH] initial commit --- CLAUDE.md | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..fe06962 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,322 @@ +\# CLAUDE.md - Project Pravda + + + +\## Overview + + + +\*\*Pravda\*\* is a Python-based Dockerized service that monitors Donald Trump's Truth Social feed using the `truthbrush` library. It relays posts to Discord via Webhooks with intelligent media handling (transcoding/splitting) and supports interactive message components. + + + +\## Tech Stack + + + +\* \*\*Language:\*\* Python 3.12+ + +\* \*\*Core Libs:\*\* `truthbrush`, `requests`, `fastapi`, `uvicorn`, `ffmpeg-python` + +\* \*\*System Tools:\*\* `ffmpeg` (installed in container) + +\* \*\*Deployment:\*\* Docker, Gitea Actions + + + +\## Architecture + + + +The application runs two concurrent processes: + + + +1\. \*\*The Poller:\*\* Loops infinitely, checking `truthbrush` for new posts. Processed posts are cached (SQLite/File) to prevent duplicates. + +2\. \*\*The Server:\*\* A FastAPI instance listening on port \*\*8080\*\* to handle Discord Interaction Webhooks (button clicks). + + + +\## Commands + + + +\### Local Development + + + +```bash + +\# Install dependencies + +pip install -r requirements.txt + + + +\# Run locally (requires ENV vars set) + +python main.py + + + +\# Run unit tests + +pytest + + + +``` + + + +\### Docker Operations + + + +```bash + +\# Build image + +docker build -t pravda . + + + +\# Run in background (Poller + Server) + +docker run -d \\ + +  -e DISCORD\_WEBHOOK="your\_webhook\_url" \\ + +  -e DISCORD\_PUBLIC\_KEY="your\_app\_public\_key" \\ + +  -v $(pwd)/data:/data \\ + +  -p 8080:8080 \\ + +  pravda + + + +\# Manual Invocation (One-off relay of specific post) + +\# Overrides normal execution loop + +docker run --rm \\ + +  -e DISCORD\_WEBHOOK="your\_webhook\_url" \\ + +  pravda https://truthsocial.com/@realDonaldTrump/posts/123456789 + + + +``` + + + +\## Environment Variables + + + +| Variable | Description | Required | + +| --- | --- | --- | + +| `DISCORD\_WEBHOOK` | The Discord Webhook URL for posting messages. | Yes | + +| `DISCORD\_APPLICATION\_ID` | App ID (for component construction). | Yes | + +| `DISCORD\_PUBLIC\_KEY` | Public Key for verifying interaction signatures. | Yes (if Server enabled) | + +| `POLL\_INTERVAL` | Seconds between checks (default: `300`). | No | + +| `TRUTH\_USER` | Target username (default: `realDonaldTrump`). | No | + +| `DB\_PATH` | Path to SQLite DB for tracking seen IDs (default: `/data/seen.db`). | No | + + + +\## Application Logic Requirements + + + +\### 1. Media Handling (The "Smart" Relay) + + + +\* \*\*Images:\*\* Download and attach directly. + +\* \*\*Videos:\*\* + +\* \*\*Must\*\* use `ffmpeg` to re-encode to `H.264/AAC` (MP4 container) for maximum Discord compatibility. + +\* \*\*Constraint:\*\* Output file must be `< 50MB` (Discord Nitro limit safeguard). + +\* \*\*Logic:\*\* If > 50MB, attempt to downscale resolution or lower bitrate. + + + + + +\* \*\*Limits:\*\* + +\* Discord allows max 10 attachments per message. + +\* Discord allows max 2000 chars per message. + +\* \*\*Splitting:\*\* If a post exceeds these limits, split the content into a thread or sequential messages. "Part 1/X" style. + + + + + + + +\### 2. Interaction Handler (FastAPI) + + + +\* Expose `POST /interactions`. + +\* Verify Ed25519 signature using `DISCORD\_PUBLIC\_KEY`. + +\* \*\*Component 1 (Delete):\*\* Check if user has `MANAGE\_MESSAGES` permission (or allow-list). Delete the webhook message. + +\* \*\*Component 2 (Raw):\*\* Reply with `flags: 64` (Ephemeral) containing the raw JSON snippet of the post. + + + +\### 3. Gitea Action Workflow + + + +Create `.gitea/workflows/build-push.yaml`: + + + +\* \*\*Trigger:\*\* On `push` to any branch. + +\* \*\*Steps:\*\* + +1\. Checkout code. + +2\. Login to Gitea Registry using `${{ secrets.REGISTRY\_USERNAME }}` and `${{ secrets.REGISTRY\_PASSWORD }}`. + +3\. Build Docker image. + +4\. Tag: `gitea.stevedudenhoeffer.com/steve/pravda:${{ gitea.ref\_name }}`. + +5\. If branch is `main`, also tag `:latest`. + +6\. Push all tags. + + + + + + + +\## Dockerfile Specification + + + +\* \*\*Base:\*\* `python:3.12-slim` + +\* \*\*System Deps:\*\* `ffmpeg`, `git` (needed for truthbrush?) + +\* \*\*Entrypoint:\*\* A script `entrypoint.sh` that detects arguments. + +\* If args provided (URL), run "One-off Mode". + +\* If no args, run "Daemon Mode" (Poller + Uvicorn). + + + + + + + +\## Code Style + + + +\* \*\*Formatter:\*\* `black` + +\* \*\*Linter:\*\* `ruff` + +\* \*\*Typing:\*\* Strong typing enforced (`mypy`). + +\* \*\*Error Handling:\*\* Never crash the poller loop on a network error. Log to `stderr` and retry. + + + +\## Example Interaction Payload (JSON) + + + +When sending the webhook, include components: + + + +```json + +{ + +  "content": "Post text here...", + +  "components": \[ + +  { + +  "type": 1, + +  "components": \[ + +  { + +  "type": 2, + +  "style": 4, + +  "label": "Delete", + +  "custom\_id": "delete\_msg" + +  }, + +  { + +  "type": 2, + +  "style": 2, + +  "label": "View Raw", + +  "custom\_id": "view\_raw" + +  }, + +  { + +  "type": 2, + +  "style": 5, + +  "label": "Original Post", + +  "url": "https://truthsocial.com/..." + +  } + +  ] + +  } + +  ] + +} + + + +``` +