From 0d09caa49abbce06bcf24634df00eda7f21d93af Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:15:51 +0330 Subject: [PATCH] Import documentation: CLAUDE.md Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- CLAUDE.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c801e3b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,88 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What this is + +A single-file Telegram bot (`bot.py`) that receives files (and URLs) and uploads them to Google Drive. Uses **Pyrogram** (MTProto, v2+) for direct Telegram communication and **rclone** (with `gdrive:` remote) for Drive uploads. All async, all in one file. + +## Environment setup + +```bash +source venv/bin/activate +pip install -r requirements.txt +``` + +Required `.env` variables: `BOT_TOKEN`, `API_ID`, `API_HASH`. The rclone remote (`gdrive:`) must be authenticated separately via `rclone config`. + +## Running the bot + +```bash +source venv/bin/activate +python bot.py +``` + +No real tests exist beyond the stub `test_local_api.py`. + +## Bot commands + +| Command | Auth required | Description | +|---------|---------------|-------------| +| `/start` | No | Upload instructions + system info | +| `/help` | No | Full command reference | +| `/list` | Yes | Last 10 files in Drive | +| `/listall` | Yes | All files (paginated) | +| `/search ` | Yes | Search files by name | +| `/share ` | Yes | Make file public + share link | +| `/status` | Yes | Uptime, RAM, CPU, disk | +| `/logs` | Yes | Last 50 log lines | +| `/adduser @user` | Yes | Grant full access | +| `/removeuser @user` | Yes | Revoke full access | +| `/setquota @user ` | Yes | Set daily upload quota | +| `/clearquota @user` | Yes | Remove quota | +| `/quotas` | Yes | Overview all quotas | +| `/myquota` | No | Check own quota | +| `/restart` | Yes | Graceful restart via `os.execv` | + +## Architecture + +All logic in `bot.py` (~1368 lines). Key components: + +- **`handle_file`** (`@app.on_message(filters.media)`) — receives any media type (document, photo, video, audio, voice, sticker, video_note, animation). Routes to one of two upload strategies based on file size: + - **`_download_then_upload`** (< 2 GB) — downloads to temp dir via `client.download_media` with retry logic (3 attempts, 5/15/30s backoff) and live progress updates, then `rclone copy` to Drive. Cleans up temp files on success. + - **`_stream_to_drive`** (≥ 2 GB) — streams directly through RAM via `client.stream_media` → `rclone rcat` stdin, with retry logic and speed tracking. Zero disk usage. +- **`handle_url`** (`@app.on_message(filters.text)`) — detects URLs in text messages, downloads via `rclone copyurl` (RAM-only, no disk), saves to Drive. Pulse animation during transfer. +- **`classify_to_folder`** — routes files into Drive subfolders by extension/MIME (Videos, Music, Photos, Software, Archives, Models, Docs, etc.). +- **`resolve_filename`** — uses caption as filename override if provided; falls back to `file_name` attribute or generates one with appropriate extension. +- **`send_links`** — after upload, queries Drive via `rclone lsjson` for the file ID, then sends direct-download + wget links. + +### Auth system + +- **`AUTHORIZED_USERS`** set persisted in `authorized_users.json`. Anyone in this set has unlimited upload access. +- **Quota system** in `quotas.json` schema: `{"quotas": {"username": bytes}, "usage": {"username": {"YYYY-MM-DD": bytes}}}`. Non-auth users can upload if they have a quota with remaining bytes today. Quotas auto-reset at midnight UTC. + +### Upload methods + +| Size | Method | Disk usage | CLI tool | +|------|--------|------------|----------| +| < 2 GB | Download then upload | Temp file on disk | `rclone copy` | +| ≥ 2 GB | RAM stream | None | `rclone rcat` | +| URLs (any size) | RAM stream | None | `rclone copyurl` | + +The 2 GB threshold is `STREAM_THRESHOLD` at line 53. + +### Key tech stack + +- **Pyrogram** v2+ — async MTProto client (`Client`), `filters.media` / `filters.command()` handlers +- **rclone** — Drive operations: `copy`, `rcat`, `copyurl`, `lsjson`, `link` +- **`asyncio.create_subprocess_exec`** — all rclone calls are non-blocking subprocesses +- **`psutil`** — RAM/CPU/disk stats for `/status` +- **`python-dotenv`** — loads `.env` + +### Key constraints + +- All handlers are `async def` — Pyrogram is fully async. +- rclone subprocesses use `asyncio.create_subprocess_exec` — do not replace with `subprocess.run`. +- Temp files only deleted on successful upload (manual retry on failure). +- Filenames cleaned via `sanitize_filename` (NFKC normalization, emoji removal, illegal char stripping). +- The bot can also handle files sent by non-auth users if they have a daily quota assigned. \ No newline at end of file