Files
2026-02-21 09:29:27 -05:00

101 lines
4.2 KiB
PHP

<?php
/**
* Worker para reintentar descargas de media fallidas
* Se ejecuta via cron cada 2 minutos
* Revisa la tabla media_queue e intenta procesar pendientes
*/
set_time_limit(300);
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../classes/MediaService.php';
$db = Database::getInstance();
// Incluir 'failed' con menos de 5 intentos para reintento
$rows = $db->fetchAll(
"SELECT * FROM media_queue WHERE (status = 'pending' OR (status = 'failed' AND (attempts IS NULL OR attempts < 5))) ORDER BY created_at ASC LIMIT 10"
);
if (empty($rows)) {
echo date('Y-m-d H:i:s') . " - No pending media jobs\n";
exit(0);
}
$ms = new MediaService();
$processed = 0;
$success = 0;
$failed = 0;
foreach ($rows as $idx => $r) {
// Pausa entre items para evitar saturar conexiones a Facebook
if ($idx > 0) sleep(2);
$processed++;
$attempts = intval($r['attempts'] ?? 0) + 1;
try {
// Marcar como procesando
$db->query("UPDATE media_queue SET status = 'processing', attempts = :att WHERE id = :id", ['att' => $attempts, 'id' => $r['id']]);
$res = null;
if (!empty($r['media_id'])) {
$res = $ms->fetchAndStoreFromGraph($r['media_id'], $r['subdir'] ?? date('Y/m'));
} elseif (!empty($r['media_url'])) {
if (preg_match('/^\d+$/', $r['media_url'])) {
$res = $ms->fetchAndStoreFromGraph($r['media_url'], $r['subdir'] ?? date('Y/m'));
} else {
$res = $ms->fetchAndStoreFromUrl($r['media_url'], $r['subdir'] ?? date('Y/m'));
}
}
if ($res && !empty($res['local_file'])) {
// Éxito
$db->query(
"UPDATE media_queue SET status = 'done', result = :res WHERE id = :id",
['res' => json_encode($res), 'id' => $r['id']]
);
// Actualizar conversations con el archivo local
if (!empty($r['conversation_id'])) {
$update = ['local_file' => $res['local_file']];
if (!empty($res['local_thumb'])) $update['local_thumb'] = $res['local_thumb'];
if (!empty($res['mime_type'])) $update['mime_type'] = $res['mime_type'];
$db->update('conversations', $update, 'id = :id', ['id' => $r['conversation_id']]);
echo date('Y-m-d H:i:s') . " - OK Media #{$r['id']} -> {$res['local_file']} (conv:{$r['conversation_id']})\n";
} else {
// Sin conversation_id: buscar por media_id/media_url
$mediaRef = !empty($r['media_id']) ? $r['media_id'] : $r['media_url'];
if ($mediaRef) {
try {
$db->query(
"UPDATE conversations SET local_file = :lf, local_thumb = :lt, mime_type = :mt WHERE (media_url = :mid OR whatsapp_media_id = :mid2) AND (local_file IS NULL OR local_file = '') LIMIT 5",
[
'lf' => $res['local_file'],
'lt' => $res['local_thumb'] ?? null,
'mt' => $res['mime_type'] ?? null,
'mid' => $mediaRef,
'mid2' => $mediaRef
]
);
} catch (Exception $e) {
error_log("[media_worker] Error updating conversations: " . $e->getMessage());
}
}
echo date('Y-m-d H:i:s') . " - OK Media #{$r['id']} -> {$res['local_file']} (sin conv_id)\n";
}
$success++;
} else {
throw new Exception('Download returned empty result');
}
} catch (Exception $e) {
$failed++;
$status = ($attempts >= 5) ? 'permanently_failed' : 'failed';
$db->query(
"UPDATE media_queue SET status = :st, attempts = :att, result = :res WHERE id = :id",
['st' => $status, 'att' => $attempts, 'res' => json_encode(['error' => $e->getMessage()]), 'id' => $r['id']]
);
echo date('Y-m-d H:i:s') . " - FAIL Media #{$r['id']} attempt {$attempts}: " . $e->getMessage() . "\n";
}
}
echo date('Y-m-d H:i:s') . " - Processed {$processed}: {$success} ok, {$failed} failed\n";