Metadata-Version: 2.4
Name: todus-bot
Version: 1.0.0
Summary: Bot de Telegram modular para subir archivos al bucket ToDus S3
Author-email: nyxthor-dev <vm1008079@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/nyxthor-dev/todus-bot
Project-URL: Repository, https://github.com/nyxthor-dev/todus-bot
Project-URL: Issues, https://github.com/nyxthor-dev/todus-bot/issues
Keywords: telegram,bot,s3,todus,youtube-downloader,cuba
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Multimedia :: Video
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: python-telegram-bot>=20.0
Requires-Dist: todus-client>=3.0.0
Requires-Dist: requests>=2.25
Requires-Dist: pyyaml>=5.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.20; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Dynamic: license-file

# ToDus Bot

Bot de Telegram modular para subir archivos al bucket público de ToDus
(`s3.todus.cu/stream`) usando el cliente [`todus-client`](https://pypi.org/project/todus-client/).

## Características

- **Whitelist por user_id**: solo usuarios autorizados pueden usarlo
- **Namespaces aislados**: cada usuario tiene su propio espacio `tg_<user_id>/` en el bucket
- **Plugins modulares**:
  - `curl`: descarga URLs HTTP/HTTPS directas
  - `youtube`: videos de YouTube vía [delirius API](https://api.delirius.online)
  - `telegram`: archivos enviados directamente al bot
- **Cuotas diarias** por usuario para evitar abuso
- **Nombres preservados**: usa `Content-Disposition` para que el browser descargue con el nombre original (incluye tildes y espacios)
- **Stats y tracking** de subidas por usuario/plugin
- **Docker ready** con docker-compose

## Instalación

### Opción 1: pip install (recomendado)

```bash
pip install todus-bot
```

### Opción 2: desde el código

```bash
git clone https://github.com/nyxthor-dev/todus-bot.git
cd todus-bot
pip install -r requirements.txt
pip install -e .
```

## Configuración

1. **Crear el bot en Telegram**:
   - Habla con [@BotFather](https://t.me/BotFather)
   - Crea un nuevo bot con `/newbot`
   - Copia el token

2. **Obtener tu user_id**:
   - Habla con [@userinfobot](https://t.me/userinfobot)
   - Te devuelve tu ID numérico

3. **Crear config.yaml**:
```bash
cp config.yaml.example config.yaml
# Edita config.yaml con tu token y user_id
```

O usa variables de entorno:
```bash
cp .env.example .env
# Edita .env
```

## Uso

### Local

```bash
python -m todus_bot
# o
todus-bot
```

### Docker

```bash
docker-compose up -d
```

Ver logs:
```bash
docker-compose logs -f
```

## Comandos del bot

### Gestión de archivos
| Comando | Descripción |
|---------|-------------|
| `/list [path]` | Listar tus archivos |
| `/share <key>` | Generar enlace de descarga |
| `/info <key>` | Info detallada de un archivo |
| `/delete <key>` | Eliminar archivo del bucket |
| `/stats` | Tus estadísticas |
| `/quota` | Cuota diaria restante |

### Descarga desde internet
| Comando | Descripción |
|---------|-------------|
| `/curl <url> [--as name]` | Descargar URL directa |
| `/yt <youtube_url> [calidad]` | Descargar video de YouTube |
| `/ytaudio <youtube_url>` | Descargar solo audio MP3 |

**Calidades YouTube**: `144p`, `240p`, `360p`, `480p`, `720p`, `1080p` (default: `360p`)

### Atajos
- **Enviar URL HTTP/HTTPS** → la descarga y sube
- **Enviar URL de YouTube** → la procesa con el plugin YouTube
- **Enviar archivo** (documento, foto, video, audio) → lo sube al bucket

### Admin
| Comando | Descripción |
|---------|-------------|
| `/users` | Listar usuarios registrados (admin only) |
| `/broadcast <msg>` | Enviar mensaje a todos los usuarios (admin only) |

## Ejemplos de uso

### Subir un archivo de internet

```
/curl https://example.com/documento.pdf
```

Respuesta del bot:
```
✅ ¡Listo!

📦 Archivo: documento.pdf
📏 Tamaño: 234.5 KB
🔑 Key: curl/documento.pdf
🔗 Descarga: https://s3.todus.cu/stream/users/tg_123456789/curl/documento.pdf
```

### Descargar un video de YouTube

```
/yt https://www.youtube.com/watch?v=5M_n2UCe7DQ 720p
```

### Renombrar archivo al subir

```
/curl https://example.com/foto.jpg --as "foto vacaciones.jpg"
```

El archivo se guarda con `Content-Disposition: attachment; filename*=UTF-8''foto%20vacaciones.jpg`
para que al descargar el browser use "foto vacaciones.jpg" como nombre.

## Arquitectura

```
todus_bot/
├── __init__.py
├── __main__.py          # python -m todus_bot
├── bot.py               # Bot principal + handlers de comandos
├── config.py            # Carga config YAML + env vars
├── auth.py              # Whitelist + cuotas + SQLite
├── todus_helper.py      # Wrapper sobre todus-client
└── plugins/
    ├── __init__.py
    ├── base.py          # BasePlugin abstracta
    ├── curl.py          # Plugin: URLs HTTP/HTTPS
    ├── youtube.py       # Plugin: YouTube vía delirius API
    └── telegram.py      # Plugin: archivos directos
```

### Mapeo usuario → namespace

Cada usuario de Telegram se mapea a un namespace en el bucket:

```
Telegram user 123456789 → namespace "tg_123456789"
                       → prefix S3 "users/tg_123456789/"
```

Estructura típica del bucket:
```
users/tg_123456789/
├── curl/
│   ├── documento.pdf
│   └── foto.jpg
├── youtube/
│   └── video_abc123_720p.mp4
└── telegram/
    └── archivo_recibido.docx
```

### Cómo crear un plugin nuevo

1. Crear `todus_bot/plugins/mi_plugin.py`:

```python
from .base import BasePlugin, DownloadResult
from telegram import Update
from telegram.ext import ContextTypes

class MiPlugin(BasePlugin):
    name = "mi_plugin"
    description = "Mi plugin personalizado"

    def can_handle(self, update: Update) -> bool:
        return update.message and update.message.text == "/mi_comando"

    async def handle(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        # Tu lógica aquí
        result = self.todus.upload_to_user(
            user_id=update.effective_user.id,
            username=update.effective_user.username,
            local_path="/tmp/archivo.txt",
            path="mi_plugin",
            original_name="archivo.txt",
            plugin=self.name,
        )
        return DownloadResult(
            success=result.success,
            plugin=self.name,
            remote_key=result.key,
        )
```

2. Registrarlo en `bot.py`:
```python
self.plugins.append(MiPlugin(config, self.auth, self.todus))
```

## License

MIT © [nyxthor-dev](https://github.com/nyxthor-dev)
