Auto commit: 2026-02-25T21:49:22.586Z
This commit is contained in:
parent
66f33d8ab6
commit
d28bf682c9
@ -48,49 +48,65 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$shouldWait) {
|
if (!$shouldWait) {
|
||||||
// 3. Take the oldest pending request and "execute" it
|
// 3. Take the oldest pending request and "execute" it using a transaction to avoid race conditions
|
||||||
$stmt = $db->query("SELECT * FROM song_requests WHERE status = 'pending' ORDER BY is_priority DESC, created_at ASC LIMIT 1");
|
$db->beginTransaction();
|
||||||
$next = $stmt->fetch();
|
try {
|
||||||
|
$stmt = $db->query("SELECT * FROM song_requests WHERE status = 'pending' ORDER BY is_priority DESC, created_at ASC LIMIT 1 FOR UPDATE");
|
||||||
if ($next) {
|
$next = $stmt->fetch();
|
||||||
// Find YouTube info before playing if missing
|
|
||||||
$youtubeUrl = $next['youtube_url'];
|
|
||||||
$duration = $next['duration'] ?? 240;
|
|
||||||
|
|
||||||
if (!$youtubeUrl) {
|
if ($next) {
|
||||||
try {
|
// Mark as played immediately within the transaction
|
||||||
require_once __DIR__ . '/../ai/LocalAIApi.php';
|
$stmt = $db->prepare("UPDATE song_requests SET status = 'played', created_at = NOW() WHERE id = ?");
|
||||||
$artist = $next['artist'];
|
$stmt->execute([$next['id']]);
|
||||||
$song = $next['song'];
|
$db->commit();
|
||||||
$aiResp = LocalAIApi::createResponse([
|
|
||||||
'input' => [
|
|
||||||
['role' => 'system', 'content' => 'Eres un asistente de radio. Tu tarea es encontrar el ID de YouTube oficial y la duración aproximada en segundos para una canción. Responde ÚNICAMENTE con un JSON: {"id": "...", "duration": ...}. Si no estás seguro, usa id null y duration 240.'],
|
|
||||||
['role' => 'user', 'content' => "Encuentra el ID de YouTube y duración para: $artist - $song"]
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
if (!empty($aiResp['success'])) {
|
|
||||||
$jsonText = LocalAIApi::extractText($aiResp);
|
|
||||||
$data = json_decode($jsonText, true);
|
|
||||||
if ($data && isset($data['id']) && $data['id'] !== null) {
|
|
||||||
$youtubeUrl = "https://www.youtube.com/watch?v={$data['id']}";
|
|
||||||
$duration = (int)($data['duration'] ?? 240);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
$stmt = $db->prepare("UPDATE song_requests SET status = 'played', youtube_url = ?, duration = ?, created_at = NOW() WHERE id = ?");
|
// Now that we "own" this request, we can do the slow AI/log operations
|
||||||
$stmt->execute([$youtubeUrl, $duration, $next['id']]);
|
$youtubeUrl = $next['youtube_url'];
|
||||||
|
$duration = $next['duration'] ?? 240;
|
||||||
// Log automation
|
|
||||||
$db->prepare("INSERT INTO automation_logs (message) VALUES (?)")->execute(["Auto-DJ ejecutó: {$next['artist']} - {$next['song']}"]);
|
if (!$youtubeUrl) {
|
||||||
|
try {
|
||||||
// Announce in chat
|
require_once __DIR__ . '/../ai/LocalAIApi.php';
|
||||||
$chatMsg = "🤖 [AUTO-DJ] Es el turno de: **{$next['artist']} - {$next['song']}** (Pedido por: **{$next['requester']}**) 🎧🔥";
|
$artist = $next['artist'];
|
||||||
$db->prepare("INSERT INTO messages (username, message, type) VALUES ('Sistema', ?, 'dj_power')")->execute([$chatMsg]);
|
$song = $next['song'];
|
||||||
|
$aiResp = LocalAIApi::createResponse([
|
||||||
echo json_encode(['success' => true, 'action' => 'executed', 'song' => $next['song']]);
|
'input' => [
|
||||||
exit;
|
['role' => 'system', 'content' => 'Eres un asistente de radio. Tu tarea es encontrar el ID de YouTube oficial y la duración aproximada en segundos para una canción. Responde ÚNICAMENTE con un JSON: {"id": "...", "duration": ...}. Si no estás seguro, usa id null y duration 240.'],
|
||||||
|
['role' => 'user', 'content' => "Encuentra el ID de YouTube y duración para: $artist - $song"]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
if (!empty($aiResp['success'])) {
|
||||||
|
$jsonText = LocalAIApi::extractText($aiResp);
|
||||||
|
$data = json_decode($jsonText, true);
|
||||||
|
if ($data && isset($data['id']) && $data['id'] !== null) {
|
||||||
|
$youtubeUrl = "https://www.youtube.com/watch?v={$data['id']}";
|
||||||
|
$duration = (int)($data['duration'] ?? 240);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {}
|
||||||
|
|
||||||
|
// Update with AI info
|
||||||
|
if ($youtubeUrl) {
|
||||||
|
$stmt = $db->prepare("UPDATE song_requests SET youtube_url = ?, duration = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$youtubeUrl, $duration, $next['id']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log automation
|
||||||
|
$db->prepare("INSERT INTO automation_logs (message) VALUES (?)")->execute(["Auto-DJ ejecutó: {$next['artist']} - {$next['song']}"]);
|
||||||
|
|
||||||
|
// Announce in chat
|
||||||
|
$chatMsg = "🤖 [AUTO-DJ] Es el turno de: **{$next['artist']} - {$next['song']}** (Pedido por: **{$next['requester']}**) 🎧🔥";
|
||||||
|
$db->prepare("INSERT INTO messages (username, message, type) VALUES ('Sistema', ?, 'dj_power')")->execute([$chatMsg]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true, 'action' => 'executed', 'song' => $next['song']]);
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
$db->rollBack();
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$db->rollBack();
|
||||||
|
throw $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -70,58 +70,34 @@ if ($method === 'POST') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Auto-DJ: Check if we should "execute" this song immediately
|
// Check for duplicates
|
||||||
// If there's no song marked as 'played' in the last 5 minutes, we execute this one automatically
|
// 1. Check if it's already in the pending queue
|
||||||
$checkStmt = $db->query("SELECT COUNT(*) FROM song_requests WHERE status = 'played' AND created_at > DATE_SUB(NOW(), INTERVAL 5 MINUTE)");
|
$stmt = $db->prepare("SELECT id FROM song_requests WHERE artist = ? AND song = ? AND status = 'pending' LIMIT 1");
|
||||||
$activePlayed = $checkStmt->fetchColumn();
|
$stmt->execute([$artist, $song]);
|
||||||
|
if ($stmt->fetch()) {
|
||||||
$initialStatus = 'pending';
|
echo json_encode(['success' => false, 'error' => 'Esta canción ya está en la cola de espera.']);
|
||||||
$wasAutoExecuted = false;
|
exit;
|
||||||
|
|
||||||
if ($activePlayed == 0) {
|
|
||||||
$initialStatus = 'played';
|
|
||||||
$wasAutoExecuted = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. Check if it was played in the last 30 minutes (to avoid repetition)
|
||||||
|
// We skip this check for priority requests or if the DJ is adding it
|
||||||
|
if ($source !== 'admin') {
|
||||||
|
$stmt = $db->prepare("SELECT id FROM song_requests WHERE artist = ? AND song = ? AND status = 'played' AND created_at > DATE_SUB(NOW(), INTERVAL 30 MINUTE) LIMIT 1");
|
||||||
|
$stmt->execute([$artist, $song]);
|
||||||
|
if ($stmt->fetch()) {
|
||||||
|
echo json_encode(['success' => false, 'error' => 'Esta canción se ha reproducido recientemente. ¡Prueba con otra!']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All requests start as pending. The automation.php script (called by clients)
|
||||||
|
// will handle moving them to 'played' status atomically.
|
||||||
|
$initialStatus = 'pending';
|
||||||
|
|
||||||
$stmt = $db->prepare("INSERT INTO song_requests (artist, song, requester, source, status, duration) VALUES (?, ?, ?, ?, ?, ?)");
|
$stmt = $db->prepare("INSERT INTO song_requests (artist, song, requester, source, status, duration) VALUES (?, ?, ?, ?, ?, ?)");
|
||||||
$stmt->execute([$artist, $song, $requester, $source, $initialStatus, 240]);
|
$stmt->execute([$artist, $song, $requester, $source, $initialStatus, 240]);
|
||||||
$requestId = $db->lastInsertId();
|
$requestId = $db->lastInsertId();
|
||||||
|
|
||||||
if ($wasAutoExecuted) {
|
|
||||||
// Try to find a YouTube link and duration for the song using AI
|
|
||||||
$youtubeUrl = null;
|
|
||||||
$duration = 240;
|
|
||||||
try {
|
|
||||||
require_once __DIR__ . '/../ai/LocalAIApi.php';
|
|
||||||
$aiResp = LocalAIApi::createResponse([
|
|
||||||
'input' => [
|
|
||||||
['role' => 'system', 'content' => 'Eres un asistente de radio. Tu tarea es encontrar el ID de YouTube oficial y la duración aproximada en segundos para una canción. Responde ÚNICAMENTE con un JSON: {"id": "...", "duration": ...}. Si no estás seguro, usa id null y duration 240.'],
|
|
||||||
['role' => 'user', 'content' => "Encuentra el ID de YouTube y duración para: $artist - $song"]
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
if (!empty($aiResp['success'])) {
|
|
||||||
$jsonText = LocalAIApi::extractText($aiResp);
|
|
||||||
$data = json_decode($jsonText, true);
|
|
||||||
if ($data && isset($data['id']) && $data['id'] !== null) {
|
|
||||||
$youtubeUrl = "https://www.youtube.com/watch?v={$data['id']}";
|
|
||||||
$duration = (int)($data['duration'] ?? 240);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
error_log("AI YouTube search failed: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($youtubeUrl || $duration != 240) {
|
|
||||||
$stmt = $db->prepare("UPDATE song_requests SET youtube_url = ?, duration = ? WHERE id = ?");
|
|
||||||
$stmt->execute([$youtubeUrl, $duration, $requestId]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Announce auto-execution
|
|
||||||
$chatMsg = "🚀 [AUTO-DJ] ¡Petición de **$requester** ejecutada automáticamente! 🎶 Sonando: **$artist - $song**" . ($youtubeUrl ? " (con video)" : "");
|
|
||||||
$db->prepare("INSERT INTO messages (username, message, type) VALUES ('Sistema', ?, 'dj_power')")->execute([$chatMsg]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Award points for song request
|
// Award points for song request
|
||||||
if ($requester !== 'Anónimo') {
|
if ($requester !== 'Anónimo') {
|
||||||
require_once __DIR__ . '/../includes/points_helper.php';
|
require_once __DIR__ . '/../includes/points_helper.php';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user