add initial config
Signed-off-by: Omar Sánchez Pizarro <omar.sanchez@pistacero.net>
This commit is contained in:
185
QUICKSTART.md
Normal file
185
QUICKSTART.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# Guía Rápida de Inicio - WallaMonitor 🚀
|
||||
|
||||
Esta guía te ayudará a configurar y ejecutar WallaMonitor en menos de 5 minutos.
|
||||
|
||||
## Requisitos Previos
|
||||
|
||||
- Python 3.x instalado
|
||||
- Un bot de Telegram creado (habla con [@BotFather](https://t.me/botfather))
|
||||
- Un canal o grupo de Telegram donde recibir notificaciones
|
||||
|
||||
## Instalación en 4 Pasos
|
||||
|
||||
### 1️⃣ Instalar Dependencias
|
||||
|
||||
```bash
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
### 2️⃣ Configurar Archivos
|
||||
|
||||
Ejecuta el script de configuración automática:
|
||||
|
||||
```bash
|
||||
python setup_config.py
|
||||
```
|
||||
|
||||
Este script creará automáticamente:
|
||||
- `config.yaml` desde `config.sample.yaml`
|
||||
- `workers.json` desde `workers.sample.json`
|
||||
|
||||
**Nota:** Si los archivos ya existen, no se sobrescribirán.
|
||||
|
||||
### 3️⃣ Editar config.yaml
|
||||
|
||||
Abre `config.yaml` y configura tus credenciales:
|
||||
|
||||
```yaml
|
||||
telegram_token: "TU_TOKEN_AQUI" # Token que te dio BotFather
|
||||
telegram_channel: "@tu_canal" # Tu canal o grupo de Telegram
|
||||
```
|
||||
|
||||
**¿Cómo obtener el token?**
|
||||
1. Habla con [@BotFather](https://t.me/botfather) en Telegram
|
||||
2. Envía el comando `/newbot`
|
||||
3. Sigue las instrucciones y guarda el token que te proporciona
|
||||
|
||||
**¿Cómo configurar el canal?**
|
||||
- Si es un canal público: `@nombre_canal`
|
||||
- Si es un grupo: usa el ID numérico (ej: `-1001234567890`)
|
||||
|
||||
### 4️⃣ Configurar Búsquedas (workers.json)
|
||||
|
||||
El archivo `workers.json` contiene ejemplos de búsquedas. Personalízalo según tus necesidades:
|
||||
|
||||
```json
|
||||
{
|
||||
"general": {
|
||||
"title_exclude": ["palabras", "a", "excluir"],
|
||||
"description_exclude": ["más", "palabras"]
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"name": "Mi Búsqueda",
|
||||
"search_query": "playstation 5",
|
||||
"platform": "wallapop",
|
||||
"thread_id": 8,
|
||||
"title_exclude": ["roto", "piezas"],
|
||||
"description_exclude": ["no funciona"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Parámetros importantes:**
|
||||
- `name`: Nombre descriptivo de la búsqueda
|
||||
- `search_query`: Término a buscar
|
||||
- `platform`: `wallapop` (por defecto) o `vinted`
|
||||
- `thread_id`: ID del hilo de Telegram (opcional)
|
||||
- `latitude`/`longitude`: Para búsquedas locales (opcional)
|
||||
- `max_distance`: Distancia máxima en km (opcional)
|
||||
|
||||
## Ejecutar WallaMonitor
|
||||
|
||||
Una vez configurado, simplemente ejecuta:
|
||||
|
||||
```bash
|
||||
python wallamonitor.py
|
||||
```
|
||||
|
||||
El monitor:
|
||||
- ✅ Verificará la configuración automáticamente
|
||||
- ✅ Creará archivos faltantes desde los .sample
|
||||
- ✅ Comenzará a monitorizar tus búsquedas
|
||||
- ✅ Enviará notificaciones a Telegram cuando encuentre artículos
|
||||
|
||||
## Verificación de Funcionamiento
|
||||
|
||||
Si todo está correcto, verás mensajes como:
|
||||
|
||||
```
|
||||
INFO [2025-10-13 10:30:00] Iniciando monitor para: Mi Búsqueda
|
||||
INFO [2025-10-13 10:30:01] Polling de Telegram iniciado
|
||||
```
|
||||
|
||||
Y comenzarás a recibir notificaciones en tu canal de Telegram!
|
||||
|
||||
## Solución de Problemas Comunes
|
||||
|
||||
### Error: "No se encontró config.yaml"
|
||||
- Ejecuta `python setup_config.py`
|
||||
- O copia manualmente: `cp config.sample.yaml config.yaml`
|
||||
|
||||
### Error: "Missing mandatory field: items"
|
||||
- Verifica que `workers.json` tenga la estructura correcta
|
||||
- Asegúrate de que el campo `items` exista y sea una lista
|
||||
|
||||
### No recibo notificaciones en Telegram
|
||||
- Verifica que el bot sea administrador del canal
|
||||
- Comprueba que el token y el canal sean correctos
|
||||
- Para grupos privados, asegúrate de usar el ID numérico correcto
|
||||
|
||||
### Error de autenticación de Telegram
|
||||
- Revisa que el token en `config.yaml` sea correcto
|
||||
- Regenera el token con [@BotFather](https://t.me/botfather) si es necesario
|
||||
|
||||
## Funcionalidades Avanzadas
|
||||
|
||||
### Búsquedas Locales
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Búsqueda Local",
|
||||
"search_query": "nintendo switch",
|
||||
"latitude": 40.4165,
|
||||
"longitude": -3.70256,
|
||||
"max_distance": "25"
|
||||
}
|
||||
```
|
||||
|
||||
### Múltiples Plataformas
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Búsqueda en Vinted",
|
||||
"platform": "vinted",
|
||||
"search_query": "zapatillas nike"
|
||||
}
|
||||
```
|
||||
|
||||
### Hilos de Telegram
|
||||
|
||||
Organiza tus notificaciones en diferentes hilos/temas:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Consolas Retro",
|
||||
"search_query": "gameboy",
|
||||
"thread_id": 10
|
||||
}
|
||||
```
|
||||
|
||||
## Comandos del Bot de Telegram
|
||||
|
||||
Una vez el bot esté funcionando, puedes usar:
|
||||
|
||||
- `/favs` - Ver tu lista de artículos favoritos
|
||||
- Botón "⭐ Añadir a favoritos" - Guardar un artículo
|
||||
- Botón "🗑️ Quitar de favoritos" - Eliminar de favoritos
|
||||
|
||||
## Próximos Pasos
|
||||
|
||||
- 📖 Lee el [README.md](README.md) completo para más opciones
|
||||
- 🔧 Consulta [ADDING_PLATFORMS.md](ADDING_PLATFORMS.md) para añadir nuevas plataformas
|
||||
- 🏗️ Revisa [REFACTORING.md](REFACTORING.md) para entender la arquitectura
|
||||
|
||||
## ¿Necesitas Ayuda?
|
||||
|
||||
Si tienes problemas:
|
||||
1. Verifica los logs en `monitor.log`
|
||||
2. Revisa que todos los archivos de configuración estén correctos
|
||||
3. Asegúrate de tener todas las dependencias instaladas
|
||||
|
||||
---
|
||||
|
||||
**¡Feliz monitoreo! 🛎️**
|
||||
19
README.md
19
README.md
@@ -18,13 +18,28 @@
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
2. Configura tus credenciales de Telegram en el archivo `config.yaml`:
|
||||
2. Configura los archivos de configuración:
|
||||
|
||||
**Opción A - Automática (recomendado):**
|
||||
```bash
|
||||
python setup_config.py
|
||||
```
|
||||
Este script creará automáticamente `config.yaml` y `workers.json` desde los archivos de muestra si no existen.
|
||||
|
||||
**Opción B - Manual:**
|
||||
```bash
|
||||
cp config.sample.yaml config.yaml
|
||||
cp workers.sample.json workers.json
|
||||
```
|
||||
|
||||
3. Edita `config.yaml` con tus credenciales de Telegram:
|
||||
```yaml
|
||||
telegram_channel: "@Tu_Canal_Telegram"
|
||||
telegram_token: "Tu_Token_De_Telegram"
|
||||
telegram_chat_id: "Tu_Chat_ID_Telegram"
|
||||
```
|
||||
|
||||
4. Personaliza `workers.json` con tus búsquedas deseadas (ver sección Configuración)
|
||||
|
||||
## Configuración 🛠️
|
||||
|
||||
Crea un archivo `args.json` con los parámetros de búsqueda. Wallabicher permite definir múltiples búsquedas y personalizar criterios para filtrar exactamente lo que quieres recibir.
|
||||
|
||||
207
REFACTORING.md
207
REFACTORING.md
@@ -1,207 +0,0 @@
|
||||
# Refactorización: Arquitectura Multi-Plataforma
|
||||
|
||||
## Resumen de Cambios
|
||||
|
||||
Se ha refactorizado completamente la arquitectura del proyecto para soportar múltiples plataformas de marketplace (Wallapop, Vinted, Buyee, etc.) mediante un diseño desacoplado y extensible.
|
||||
|
||||
## Cambios Principales
|
||||
|
||||
### 1. Nueva Estructura de Directorios
|
||||
|
||||
```
|
||||
├── platforms/ # NUEVO
|
||||
│ ├── __init__.py
|
||||
│ ├── base_platform.py # Clase abstracta para plataformas
|
||||
│ ├── platform_factory.py # Factory para crear plataformas
|
||||
│ ├── wallapop_platform.py # Implementación de Wallapop
|
||||
│ ├── vinted_platform_template.py # Template para nuevas plataformas
|
||||
│ └── README.md # Documentación de plataformas
|
||||
│
|
||||
├── models/ # NUEVO
|
||||
│ ├── __init__.py
|
||||
│ └── article.py # Modelo genérico de artículo
|
||||
│
|
||||
└── datalayer/
|
||||
└── wallapop_article.py # DEPRECADO (mantener por compatibilidad)
|
||||
```
|
||||
|
||||
### 2. Clases Nuevas
|
||||
|
||||
#### `models/article.py` - Modelo Genérico
|
||||
- **Propósito**: Representa un artículo de cualquier plataforma
|
||||
- **Cambios respecto a WallapopArticle**:
|
||||
- Añadido campo `platform` para identificar el origen
|
||||
- Método `get_images()` devuelve lista directa (no requiere procesamiento)
|
||||
- Método `get_modified_at()` devuelve string ya formateado
|
||||
- Igualdad considera plataforma (`id` + `platform`)
|
||||
|
||||
#### `platforms/base_platform.py` - Clase Abstracta
|
||||
- **Propósito**: Define la interfaz común para todas las plataformas
|
||||
- **Métodos abstractos**:
|
||||
- `get_platform_name()`: Retorna identificador de la plataforma
|
||||
- `create_url()`: Construye URL de búsqueda
|
||||
- `fetch_articles()`: Obtiene artículos de la plataforma
|
||||
- `parse_response()`: Parsea respuesta a objetos Article
|
||||
- **Métodos concretos**:
|
||||
- `get_request_headers()`: Headers por defecto (puede sobreescribirse)
|
||||
|
||||
#### `platforms/wallapop_platform.py` - Implementación Wallapop
|
||||
- **Propósito**: Lógica específica de Wallapop
|
||||
- **Migración desde Worker**:
|
||||
- `_create_url()` → `create_url()`
|
||||
- `_request_articles()` → `fetch_articles()`
|
||||
- `_parse_json_response()` → `parse_response()`
|
||||
- **Nuevas funcionalidades**:
|
||||
- Manejo de errores en parseo de artículos individuales
|
||||
- Logging específico de errores de Wallapop
|
||||
- Headers específicos de Wallapop (`X-DeviceOS`)
|
||||
|
||||
#### `platforms/platform_factory.py` - Factory Pattern
|
||||
- **Propósito**: Crear instancias de plataformas dinámicamente
|
||||
- **Funcionalidades**:
|
||||
- `create_platform(name, item_monitor)`: Instancia la plataforma
|
||||
- `get_available_platforms()`: Lista plataformas disponibles
|
||||
- `register_platform(name, class)`: Registra nuevas plataformas
|
||||
- **Ventajas**:
|
||||
- Añadir plataformas sin modificar código existente
|
||||
- Validación de plataformas soportadas
|
||||
- Mensajes de error descriptivos
|
||||
|
||||
### 3. Clases Modificadas
|
||||
|
||||
#### `managers/worker.py` - Refactorización Mayor
|
||||
**Eliminado** (lógica específica de Wallapop):
|
||||
- `_create_url()` - Movido a `WallapopPlatform.create_url()`
|
||||
- `_request_articles()` implementación completa - Movido a plataforma
|
||||
- `_parse_json_response()` - Movido a `WallapopPlatform.parse_response()`
|
||||
- Imports: `requests`, `WallapopArticle`
|
||||
- Constantes: `REQUEST_SLEEP_TIME`, `REQUEST_RETRY_TIME`, `USER_AGENT`
|
||||
|
||||
**Añadido** (lógica desacoplada):
|
||||
- `self._platform`: Instancia de la plataforma configurada
|
||||
- Inicialización de plataforma mediante `PlatformFactory`
|
||||
- Manejo de errores de inicialización de plataforma
|
||||
- Log de plataforma inicializada
|
||||
- `_request_articles()` ahora delega a `self._platform.fetch_articles()`
|
||||
|
||||
**Mantenido** (lógica común a todas las plataformas):
|
||||
- `_has_words()`: Búsqueda de palabras en texto
|
||||
- `_title_has_excluded_words()`: Filtrado de títulos
|
||||
- `_description_has_excluded_words()`: Filtrado de descripciones
|
||||
- `_title_has_required_words()`: Palabras requeridas en título
|
||||
- `_description_has_required_words()`: Palabras requeridas en descripción
|
||||
- `_title_first_word_is_excluded()`: Filtrado de primera palabra
|
||||
- `_meets_item_conditions()`: Validación completa de condiciones
|
||||
- `work()`: Loop principal de trabajo
|
||||
- `run()`: Manejo de errores y reinicios
|
||||
|
||||
#### `datalayer/item_monitor.py` - Campo de Plataforma
|
||||
**Añadido**:
|
||||
- Parámetro `platform` en `__init__()`
|
||||
- Campo `self._platform`
|
||||
- Método `get_platform()`
|
||||
- Default `'wallapop'` en `load_from_json()` para compatibilidad hacia atrás
|
||||
|
||||
### 4. Archivos de Configuración
|
||||
|
||||
#### `workers.json` - Campo Opcional de Plataforma
|
||||
**Añadido**:
|
||||
- Campo `"platform": "wallapop"` en primer item como ejemplo
|
||||
- Otros items usan el default (wallapop) por compatibilidad
|
||||
|
||||
**Ejemplo**:
|
||||
```json
|
||||
{
|
||||
"name": "Playstation 1",
|
||||
"platform": "wallapop",
|
||||
"search_query": "playstation",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Documentación
|
||||
|
||||
#### `platforms/README.md` - Guía Completa
|
||||
- Introducción a la arquitectura de plataformas
|
||||
- Cómo añadir una nueva plataforma (paso a paso)
|
||||
- Parámetros disponibles en ItemMonitor
|
||||
- Estructura del modelo Article
|
||||
- Lógica común del Worker vs lógica de plataforma
|
||||
|
||||
#### `platforms/vinted_platform_template.py` - Plantilla
|
||||
- Implementación esqueleto para Vinted
|
||||
- TODOs marcados claramente
|
||||
- Comentarios explicativos
|
||||
- Estructura JSON de ejemplo
|
||||
- Pasos de activación
|
||||
|
||||
#### `README.md` - Actualización Principal
|
||||
- Nueva sección "Arquitectura Multi-Plataforma"
|
||||
- Nueva sección "Añadir Nuevas Plataformas"
|
||||
- Actualización de descripción del proyecto
|
||||
- Tabla de parámetros con campo `platform`
|
||||
- Diagrama de estructura del proyecto
|
||||
- Lista de plataformas soportadas
|
||||
|
||||
## Ventajas de la Nueva Arquitectura
|
||||
|
||||
### ✅ Desacoplamiento
|
||||
- Lógica de plataforma separada de lógica de filtrado
|
||||
- Cada componente tiene una responsabilidad única
|
||||
- Fácil de mantener y testear
|
||||
|
||||
### ✅ Extensibilidad
|
||||
- Añadir plataformas sin tocar código existente
|
||||
- Factory pattern permite registro dinámico
|
||||
- Plantillas y documentación para nuevas plataformas
|
||||
|
||||
### ✅ Reutilización
|
||||
- Filtros comunes para todas las plataformas
|
||||
- Modelo Article unificado
|
||||
- Worker genérico
|
||||
|
||||
### ✅ Mantenibilidad
|
||||
- Código más limpio y organizado
|
||||
- Responsabilidades claras
|
||||
- Fácil de entender y modificar
|
||||
|
||||
## Compatibilidad Hacia Atrás
|
||||
|
||||
✅ **100% Compatible**: El código existente funciona sin cambios
|
||||
- Items sin campo `platform` usan "wallapop" por defecto
|
||||
- `WallapopArticle` aún existe (aunque ya no se usa)
|
||||
- Mismos filtros y funcionalidad
|
||||
|
||||
## Próximos Pasos
|
||||
|
||||
Para añadir nuevas plataformas:
|
||||
|
||||
1. **Vinted**: Completar el template existente
|
||||
2. **Buyee**: Crear nueva implementación
|
||||
3. **Amazon**: Posible integración futura
|
||||
4. **eBay**: Posible integración futura
|
||||
|
||||
## Migración
|
||||
|
||||
No se requiere migración. El sistema funciona con configuraciones existentes.
|
||||
|
||||
Para aprovechar las nuevas funcionalidades:
|
||||
1. Añade `"platform": "wallapop"` a tus items en `workers.json` (opcional)
|
||||
2. Implementa nuevas plataformas según `platforms/README.md`
|
||||
|
||||
## Testing
|
||||
|
||||
Recomendaciones para testing:
|
||||
1. Verificar que Wallapop sigue funcionando igual
|
||||
2. Probar con configuraciones sin campo `platform`
|
||||
3. Validar que los filtros funcionan con el nuevo modelo Article
|
||||
4. Probar manejo de errores en inicialización de plataformas
|
||||
|
||||
## Archivos a Mantener (Deprecados)
|
||||
|
||||
- `datalayer/wallapop_article.py`: Mantener por si hay dependencias externas
|
||||
|
||||
## Cambios en Dependencias
|
||||
|
||||
Ninguno. Las mismas dependencias funcionan con la nueva arquitectura.
|
||||
|
||||
331
SUMMARY.md
331
SUMMARY.md
@@ -1,331 +0,0 @@
|
||||
# ✅ Resumen de la Refactorización Multi-Plataforma
|
||||
|
||||
## 🎯 Objetivo Completado
|
||||
|
||||
Se ha desacoplado exitosamente la lógica específica de Wallapop del Worker, implementando una arquitectura extensible que permite añadir múltiples plataformas (Vinted, Buyee, etc.) sin modificar el código existente.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Archivos Creados
|
||||
|
||||
### Nuevos Directorios
|
||||
```
|
||||
platforms/ # Implementaciones de plataformas
|
||||
models/ # Modelos de datos genéricos
|
||||
```
|
||||
|
||||
### Nuevos Archivos de Código
|
||||
```
|
||||
✅ models/__init__.py
|
||||
✅ models/article.py # Modelo genérico de artículo
|
||||
✅ platforms/__init__.py
|
||||
✅ platforms/base_platform.py # Clase abstracta base
|
||||
✅ platforms/platform_factory.py # Factory para crear plataformas
|
||||
✅ platforms/wallapop_platform.py # Implementación de Wallapop
|
||||
✅ platforms/vinted_platform_template.py # Plantilla para Vinted
|
||||
```
|
||||
|
||||
### Nuevos Archivos de Documentación
|
||||
```
|
||||
✅ REFACTORING.md # Resumen técnico completo
|
||||
✅ ADDING_PLATFORMS.md # Guía para Vinted y Buyee
|
||||
✅ platforms/README.md # Documentación de plataformas
|
||||
✅ SUMMARY.md # Este archivo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Archivos Modificados
|
||||
|
||||
### Código
|
||||
```
|
||||
✅ managers/worker.py # Refactorizado para usar plataformas
|
||||
✅ datalayer/item_monitor.py # Añadido campo 'platform'
|
||||
✅ workers.json # Ejemplo con campo 'platform'
|
||||
```
|
||||
|
||||
### Documentación
|
||||
```
|
||||
✅ README.md # Actualizado con nueva arquitectura
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Arquitectura Implementada
|
||||
|
||||
### Patrón de Diseño: Strategy + Factory
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Worker │
|
||||
│ (Lógica común: filtros, validaciones) │
|
||||
└────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
│ usa
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ PlatformFactory │
|
||||
│ (Crea instancias de plataformas) │
|
||||
└────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
│ crea
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ BasePlatform │
|
||||
│ (Interfaz abstracta) │
|
||||
└────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
┌───────┴────────┬─────────────┬──────────┐
|
||||
▼ ▼ ▼ ▼
|
||||
┌────────────┐ ┌──────────┐ ┌─────────┐ ┌──────┐
|
||||
│ Wallapop │ │ Vinted │ │ Buyee │ │ ... │
|
||||
│ Platform │ │ Platform │ │Platform │ │ │
|
||||
└────────────┘ └──────────┘ └─────────┘ └──────┘
|
||||
│ │ │ │
|
||||
└────────────────┴─────────────┴──────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────┐
|
||||
│ Article │
|
||||
│ (Modelo) │
|
||||
└────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Separación de Responsabilidades
|
||||
|
||||
### ✅ Lógica COMÚN (Worker)
|
||||
Aplicada a todas las plataformas:
|
||||
- ✓ Filtrado por palabras excluidas en título
|
||||
- ✓ Filtrado por palabras excluidas en descripción
|
||||
- ✓ Filtrado por palabras requeridas
|
||||
- ✓ Filtrado por primera palabra del título
|
||||
- ✓ Deduplicación de artículos
|
||||
- ✓ Gestión de cola de notificaciones
|
||||
- ✓ Manejo de errores y reintentos
|
||||
- ✓ Logging y estadísticas
|
||||
|
||||
### 🔧 Lógica ESPECÍFICA (Plataformas)
|
||||
Cada plataforma implementa:
|
||||
- 🔧 Construcción de URL de búsqueda
|
||||
- 🔧 Headers HTTP específicos
|
||||
- 🔧 Peticiones a la API/sitio web
|
||||
- 🔧 Parseo de respuestas JSON/HTML
|
||||
- 🔧 Conversión a modelo Article genérico
|
||||
|
||||
---
|
||||
|
||||
## 📊 Comparativa: Antes vs Después
|
||||
|
||||
### Antes (Monolítico)
|
||||
```
|
||||
Worker
|
||||
├── Lógica de Wallapop (URL, API, parseo)
|
||||
├── Lógica de filtrado
|
||||
└── Gestión de artículos
|
||||
|
||||
❌ Difícil añadir nuevas plataformas
|
||||
❌ Código mezclado
|
||||
❌ No reutilizable
|
||||
```
|
||||
|
||||
### Después (Desacoplado)
|
||||
```
|
||||
Worker
|
||||
└── Lógica de filtrado (común)
|
||||
|
||||
Plataformas (separadas)
|
||||
├── WallapopPlatform
|
||||
├── VintedPlatform (plantilla)
|
||||
└── BuyeePlatform (por implementar)
|
||||
|
||||
✅ Fácil añadir plataformas
|
||||
✅ Código organizado
|
||||
✅ Altamente reutilizable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Cómo Usar
|
||||
|
||||
### 1. Configuración Básica (Wallapop - Compatible)
|
||||
Sin cambios necesarios, funciona con tu `workers.json` actual:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Gameboy",
|
||||
"search_query": "gameboy",
|
||||
"min_price": 10,
|
||||
"max_price": 100
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Configuración Explícita (Recomendado)
|
||||
Especifica la plataforma:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Gameboy en Wallapop",
|
||||
"platform": "wallapop",
|
||||
"search_query": "gameboy",
|
||||
"min_price": 10,
|
||||
"max_price": 100
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Añadir Nueva Plataforma (Vinted)
|
||||
Una vez implementada:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Gameboy en Vinted",
|
||||
"platform": "vinted",
|
||||
"search_query": "gameboy",
|
||||
"min_price": 10,
|
||||
"max_price": 100,
|
||||
"thread_id": 12
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Próximos Pasos para Vinted y Buyee
|
||||
|
||||
### Vinted (Más Fácil)
|
||||
1. Usa la plantilla en `platforms/vinted_platform_template.py`
|
||||
2. Completa los métodos con la API de Vinted
|
||||
3. Registra en `platform_factory.py`
|
||||
4. Prueba con búsquedas reales
|
||||
|
||||
**Documentación**: Ver `ADDING_PLATFORMS.md` para código completo
|
||||
|
||||
### Buyee (Más Complejo)
|
||||
1. Decide entre API de Yahoo o web scraping
|
||||
2. Implementa siguiendo el ejemplo en `ADDING_PLATFORMS.md`
|
||||
3. Instala BeautifulSoup si usas scraping: `pip install beautifulsoup4`
|
||||
4. Registra en `platform_factory.py`
|
||||
|
||||
**Documentación**: Ver `ADDING_PLATFORMS.md` para código completo
|
||||
|
||||
---
|
||||
|
||||
## ✅ Testing Realizado
|
||||
|
||||
```
|
||||
✅ Imports funcionan correctamente
|
||||
✅ PlatformFactory crea plataformas
|
||||
✅ ItemMonitor soporta campo 'platform'
|
||||
✅ Modelo Article funciona correctamente
|
||||
✅ Validación de plataformas no soportadas
|
||||
```
|
||||
|
||||
**Resultado**: 5/5 tests pasados ✓
|
||||
|
||||
---
|
||||
|
||||
## 📚 Documentación Disponible
|
||||
|
||||
| Archivo | Propósito |
|
||||
|---------|-----------|
|
||||
| `README.md` | Documentación principal del proyecto |
|
||||
| `REFACTORING.md` | Detalles técnicos de la refactorización |
|
||||
| `ADDING_PLATFORMS.md` | Guía completa para Vinted y Buyee |
|
||||
| `platforms/README.md` | Cómo añadir cualquier plataforma |
|
||||
| `SUMMARY.md` | Este resumen ejecutivo |
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Compatibilidad
|
||||
|
||||
### ✅ 100% Compatible con Código Existente
|
||||
- Workers sin campo `platform` usan "wallapop" por defecto
|
||||
- Misma funcionalidad de filtrado
|
||||
- Mismos resultados
|
||||
- No requiere cambios en configuración
|
||||
|
||||
### 🆕 Nuevas Capacidades
|
||||
- Soporte multi-plataforma
|
||||
- Arquitectura extensible
|
||||
- Fácil mantenimiento
|
||||
- Código más limpio
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Conceptos Implementados
|
||||
|
||||
- ✅ **Strategy Pattern**: Diferentes estrategias de búsqueda por plataforma
|
||||
- ✅ **Factory Pattern**: Creación dinámica de plataformas
|
||||
- ✅ **Dependency Injection**: Worker recibe plataforma
|
||||
- ✅ **Open/Closed Principle**: Abierto a extensión, cerrado a modificación
|
||||
- ✅ **Single Responsibility**: Cada clase tiene una responsabilidad
|
||||
- ✅ **DRY**: Lógica común no se repite
|
||||
|
||||
---
|
||||
|
||||
## 📈 Beneficios Conseguidos
|
||||
|
||||
### Para el Desarrollo
|
||||
- ✅ Código más limpio y organizado
|
||||
- ✅ Fácil de mantener y depurar
|
||||
- ✅ Testing más simple
|
||||
- ✅ Documentación completa
|
||||
|
||||
### Para Añadir Plataformas
|
||||
- ✅ Solo 3 pasos para añadir una plataforma
|
||||
- ✅ Plantillas y ejemplos disponibles
|
||||
- ✅ No tocar código existente
|
||||
- ✅ Factory maneja instanciación
|
||||
|
||||
### Para el Usuario
|
||||
- ✅ Más plataformas disponibles
|
||||
- ✅ Mismos filtros en todas
|
||||
- ✅ Configuración simple
|
||||
- ✅ Sin cambios en workers.json existente
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Resultado Final
|
||||
|
||||
**Sistema completamente funcional y probado** que:
|
||||
|
||||
1. ✅ Mantiene toda la funcionalidad de Wallapop
|
||||
2. ✅ Permite añadir Vinted fácilmente
|
||||
3. ✅ Permite añadir Buyee con guía completa
|
||||
4. ✅ Es 100% compatible con configuración existente
|
||||
5. ✅ Tiene arquitectura profesional y escalable
|
||||
6. ✅ Incluye documentación completa
|
||||
7. ✅ Ha pasado todos los tests
|
||||
|
||||
---
|
||||
|
||||
## 💡 Empezar a Usar
|
||||
|
||||
### Opción 1: Seguir como Antes
|
||||
```bash
|
||||
# No hagas nada, ya funciona con tu workers.json actual
|
||||
python3 wallamonitor.py
|
||||
```
|
||||
|
||||
### Opción 2: Añadir Vinted
|
||||
1. Lee `ADDING_PLATFORMS.md`
|
||||
2. Copia el código de Vinted
|
||||
3. Registra la plataforma
|
||||
4. Añade items con `"platform": "vinted"` en workers.json
|
||||
5. ¡Listo!
|
||||
|
||||
### Opción 3: Añadir Buyee
|
||||
1. Lee `ADDING_PLATFORMS.md`
|
||||
2. Decide API vs Scraping
|
||||
3. Implementa según el ejemplo
|
||||
4. Instala dependencias si es necesario
|
||||
5. Registra y usa
|
||||
|
||||
---
|
||||
|
||||
**¿Preguntas?** Consulta la documentación en los archivos `.md` creados.
|
||||
|
||||
**¿Problemas?** Revisa `REFACTORING.md` para detalles técnicos.
|
||||
|
||||
**¿Añadir plataforma?** Sigue `ADDING_PLATFORMS.md` o `platforms/README.md`.
|
||||
|
||||
88
setup_config.py
Executable file
88
setup_config.py
Executable file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script de inicialización de configuración para WallaMonitor.
|
||||
|
||||
Este script copia los archivos de configuración de muestra (.sample)
|
||||
a sus ubicaciones finales si estos no existen.
|
||||
|
||||
Uso:
|
||||
python setup_config.py
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
def setup_configuration():
|
||||
"""
|
||||
Inicializa los archivos de configuración necesarios.
|
||||
"""
|
||||
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
config_files = [
|
||||
{
|
||||
'name': 'config.yaml',
|
||||
'sample': 'config.sample.yaml',
|
||||
'description': 'Configuración de Telegram (token y canal)'
|
||||
},
|
||||
{
|
||||
'name': 'workers.json',
|
||||
'sample': 'workers.sample.json',
|
||||
'description': 'Configuración de búsquedas y monitores'
|
||||
}
|
||||
]
|
||||
|
||||
print("="*60)
|
||||
print(" WallaMonitor - Configuración Inicial")
|
||||
print("="*60)
|
||||
print()
|
||||
|
||||
files_created = False
|
||||
files_exist = []
|
||||
|
||||
for config in config_files:
|
||||
config_path = os.path.join(base_dir, config['name'])
|
||||
sample_path = os.path.join(base_dir, config['sample'])
|
||||
|
||||
if os.path.exists(config_path):
|
||||
files_exist.append(config['name'])
|
||||
print(f"✓ '{config['name']}' ya existe (no se sobrescribirá)")
|
||||
elif os.path.exists(sample_path):
|
||||
try:
|
||||
shutil.copy2(sample_path, config_path)
|
||||
files_created = True
|
||||
print(f"✓ '{config['name']}' creado desde '{config['sample']}'")
|
||||
print(f" → {config['description']}")
|
||||
except Exception as e:
|
||||
print(f"✗ Error al crear '{config['name']}': {e}")
|
||||
return False
|
||||
else:
|
||||
print(f"✗ ERROR: No se encontró el archivo de muestra '{config['sample']}'")
|
||||
return False
|
||||
|
||||
print()
|
||||
print("="*60)
|
||||
|
||||
if files_created:
|
||||
print("\n⚠️ IMPORTANTE: Edita los archivos de configuración antes de ejecutar:")
|
||||
print()
|
||||
print(" 1. config.yaml:")
|
||||
print(" - Añade tu token de Telegram Bot")
|
||||
print(" - Configura el canal/grupo de destino")
|
||||
print()
|
||||
print(" 2. workers.json:")
|
||||
print(" - Ajusta las búsquedas según tus necesidades")
|
||||
print(" - Configura los thread_id para tus hilos de Telegram")
|
||||
print()
|
||||
print(" Luego ejecuta: python wallamonitor.py")
|
||||
elif files_exist:
|
||||
print("\n✓ Todos los archivos de configuración ya existen.")
|
||||
print(" El sistema está listo para usar.")
|
||||
|
||||
print("\n" + "="*60)
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = setup_configuration()
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
@@ -2,12 +2,41 @@ import json
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from datalayer.item_monitor import ItemMonitor
|
||||
from datalayer.general_monitor import GeneralMonitor
|
||||
from managers.worker import Worker
|
||||
from managers.queue_manager import QueueManager
|
||||
|
||||
def initialize_config_files():
|
||||
"""
|
||||
Inicializa los archivos de configuración si no existen,
|
||||
copiando los archivos .sample correspondientes.
|
||||
"""
|
||||
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
config_files = [
|
||||
('config.yaml', 'config.sample.yaml'),
|
||||
('workers.json', 'workers.sample.json')
|
||||
]
|
||||
|
||||
for config_file, sample_file in config_files:
|
||||
config_path = os.path.join(base_dir, config_file)
|
||||
sample_path = os.path.join(base_dir, sample_file)
|
||||
|
||||
if not os.path.exists(config_path):
|
||||
if os.path.exists(sample_path):
|
||||
shutil.copy2(sample_path, config_path)
|
||||
print(f"✓ Archivo '{config_file}' creado desde '{sample_file}'")
|
||||
print(f" Por favor, edita '{config_file}' con tu configuración antes de continuar.")
|
||||
else:
|
||||
raise FileNotFoundError(
|
||||
f"No se encontró ni '{config_file}' ni '{sample_file}'. "
|
||||
f"Por favor, crea uno de estos archivos."
|
||||
)
|
||||
|
||||
def configure_logger():
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
|
||||
@@ -36,6 +65,7 @@ def parse_items_to_monitor():
|
||||
return items, general_args
|
||||
|
||||
if __name__ == "__main__":
|
||||
initialize_config_files()
|
||||
configure_logger()
|
||||
items, general_args = parse_items_to_monitor()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user