Auto commit: 2026-02-25T19:30:52.555Z

This commit is contained in:
Flatlogic Bot 2026-02-25 19:30:52 +00:00
parent 6b0e285541
commit 2e5c1af7eb
4 changed files with 181 additions and 8 deletions

36
api/automation.php Normal file
View File

@ -0,0 +1,36 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
try {
$db = db();
// 1. Check if there is an active "played" song within its duration (e.g. 5 minutes)
$stmt = $db->query("SELECT COUNT(*) FROM song_requests WHERE status = 'played' AND created_at > DATE_SUB(NOW(), INTERVAL 5 MINUTE)");
$hasActive = $stmt->fetchColumn();
if ($hasActive == 0) {
// 2. No active song? Let's take the oldest pending request and "execute" it
$stmt = $db->query("SELECT * FROM song_requests WHERE status = 'pending' ORDER BY is_priority DESC, created_at ASC LIMIT 1");
$next = $stmt->fetch();
if ($next) {
$stmt = $db->prepare("UPDATE song_requests SET status = 'played' WHERE id = ?");
$stmt->execute([$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;
}
}
echo json_encode(['success' => true, 'action' => 'none']);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}

53
api/current_song.php Normal file
View File

@ -0,0 +1,53 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
try {
$db = db();
// Check for a "manual override" song that was recently marked as played
// We look for a song marked as 'played' in the last 4 minutes (typical song duration)
$stmt = $db->query("SELECT artist, song, requester, youtube_url FROM song_requests WHERE status = 'played' AND created_at > DATE_SUB(NOW(), INTERVAL 4 MINUTE) ORDER BY created_at DESC LIMIT 1");
$override = $stmt->fetch();
if ($override) {
echo json_encode([
'success' => true,
'source' => 'local_request',
'artist' => $override['artist'],
'title' => $override['song'],
'requester' => $override['requester'],
'youtube_url' => $override['youtube_url'],
'cover' => './assets/pasted-20260215-163754-def41f49.png'
]);
exit;
}
// Fallback: Proxy RadioKing metadata
$radioKingUrl = 'https://www.radioking.com/widgets/api/v1/radio/828046/track/current';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $radioKingUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$resp = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200 && $resp) {
$data = json_decode($resp, true);
echo json_encode([
'success' => true,
'source' => 'radioking',
'artist' => $data['artist'] ?? 'Lili Records',
'title' => $data['title'] ?? 'La mejor música',
'cover' => $data['cover'] ?? './assets/pasted-20260215-163754-def41f49.png',
'duration' => $data['duration'] ?? 0,
'end_at' => $data['end_at'] ?? null,
'next_track' => $data['next_track'] ?? null
]);
} else {
echo json_encode(['success' => false, 'error' => 'Failed to fetch RadioKing metadata']);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}

View File

@ -70,8 +70,54 @@ if ($method === 'POST') {
} }
try { try {
$stmt = $db->prepare("INSERT INTO song_requests (artist, song, requester, source) VALUES (?, ?, ?, ?)"); // Auto-DJ: Check if we should "execute" this song immediately
$stmt->execute([$artist, $song, $requester, $source]); // If there's no song marked as 'played' in the last 5 minutes, we execute this one automatically
$checkStmt = $db->query("SELECT COUNT(*) FROM song_requests WHERE status = 'played' AND created_at > DATE_SUB(NOW(), INTERVAL 5 MINUTE)");
$activePlayed = $checkStmt->fetchColumn();
$initialStatus = 'pending';
$wasAutoExecuted = false;
if ($activePlayed == 0) {
$initialStatus = 'played';
$wasAutoExecuted = true;
}
$stmt = $db->prepare("INSERT INTO song_requests (artist, song, requester, source, status) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$artist, $song, $requester, $source, $initialStatus]);
if ($wasAutoExecuted) {
// Try to find a YouTube link for the song using AI
$youtubeUrl = null;
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 para una canción. Responde ÚNICAMENTE con el ID del video (ej: dQw4w9WgXcQ). Si no estás seguro, responde "None".'],
['role' => 'user', 'content' => "Encuentra el ID de YouTube para: $artist - $song"]
]
]);
if (!empty($aiResp['success'])) {
$id = trim(LocalAIApi::extractText($aiResp));
if ($id !== 'None' && strlen($id) > 5 && strlen($id) < 15) {
$youtubeUrl = "https://www.youtube.com/watch?v=$id";
}
}
} catch (Exception $e) {
error_log("AI YouTube search failed: " . $e->getMessage());
}
$stmt = $db->prepare("INSERT INTO song_requests (artist, song, requester, source, status, youtube_url) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$artist, $song, $requester, $source, $initialStatus, $youtubeUrl]);
// 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]);
} else {
$stmt = $db->prepare("INSERT INTO song_requests (artist, song, requester, source, status) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$artist, $song, $requester, $source, $initialStatus]);
}
// Award points for song request // Award points for song request
if ($requester !== 'Anónimo') { if ($requester !== 'Anónimo') {

View File

@ -3588,11 +3588,23 @@ $twitter_link = "https://twitter.com/";
} }
} }
// Initial fetch and poll async function checkAutomation() {
fetchMessages(); try {
updatePhotoCounter(); const response = await fetch('api/automation.php');
setInterval(fetchMessages, 3000); const data = await response.json();
setInterval(updatePhotoCounter, 30000); // Check limit status every 30s if (data.success && data.action === 'executed') {
// Force metadata update if something was executed
updateMetadata();
if (typeof fetchSongRequests === 'function') fetchSongRequests();
}
} catch (error) {
console.error('Automation error:', error);
}
}
// Run automation check every 15 seconds
setInterval(checkAutomation, 15000);
setTimeout(checkAutomation, 2000); // Initial check
// --- End Chat Functionality --- // --- End Chat Functionality ---
// --- Song Request Functionality --- // --- Song Request Functionality ---
@ -4435,7 +4447,7 @@ $twitter_link = "https://twitter.com/";
async function updateMetadata() { async function updateMetadata() {
try { try {
const response = await fetch('https://www.radioking.com/widgets/api/v1/radio/828046/track/current'); const response = await fetch('api/current_song.php');
const data = await response.json(); const data = await response.json();
if (data && data.title) { if (data && data.title) {
@ -4444,8 +4456,34 @@ $twitter_link = "https://twitter.com/";
const album = data.album || ''; const album = data.album || '';
const coverUrl = data.cover || './assets/pasted-20260215-163754-def41f49.png'; const coverUrl = data.cover || './assets/pasted-20260215-163754-def41f49.png';
const fullDisplay = `${artist} - ${title}`; const fullDisplay = `${artist} - ${title}`;
const source = data.source || 'radioking';
const requester = data.requester || '';
if (trackTitle.textContent !== title) { if (trackTitle.textContent !== title) {
// If it's a local request, show special label
const label = document.querySelector('.track-label');
if (source === 'local_request') {
label.innerHTML = `PETICIÓN DE <span style="color: #facc15;">${requester.toUpperCase()}</span>:`;
label.style.animation = 'pulse 1s infinite';
if (data.youtube_url) {
const youtubeBtn = document.createElement('a');
youtubeBtn.href = data.youtube_url;
youtubeBtn.target = '_blank';
youtubeBtn.style.background = '#ff0000';
youtubeBtn.style.color = '#fff';
youtubeBtn.style.padding = '4px 10px';
youtubeBtn.style.borderRadius = '12px';
youtubeBtn.style.fontSize = '0.65rem';
youtubeBtn.style.fontWeight = '800';
youtubeBtn.style.textDecoration = 'none';
youtubeBtn.style.marginLeft = '10px';
youtubeBtn.innerHTML = '<i class="bi bi-youtube"></i> VER VIDEO';
label.appendChild(youtubeBtn);
}
} else {
label.innerText = 'ESTÁS ESCUCHANDO:';
label.style.animation = 'none';
}
trackTitle.style.opacity = '0'; trackTitle.style.opacity = '0';
if (trackArtist) trackArtist.style.opacity = '0'; if (trackArtist) trackArtist.style.opacity = '0';
if (trackAlbum) trackAlbum.style.opacity = '0'; if (trackAlbum) trackAlbum.style.opacity = '0';