244 lines
10 KiB
PHP
244 lines
10 KiB
PHP
<?php
|
|
header('Content-Type: application/json');
|
|
require_once __DIR__ . '/../db/config.php';
|
|
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
$db = db();
|
|
|
|
if ($method === 'POST') {
|
|
if (isset($_POST['action'])) {
|
|
$action = $_POST['action'];
|
|
$id = (int)($_POST['id'] ?? 0);
|
|
|
|
if ($id <= 0) {
|
|
echo json_encode(['success' => false, 'error' => 'ID inválido']);
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
if ($action === 'mark_played') {
|
|
$username = trim($_POST['username'] ?? '');
|
|
|
|
// Get request info before updating
|
|
$stmt = $db->prepare("SELECT is_priority, created_at, artist, song FROM song_requests WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
$req = $stmt->fetch();
|
|
|
|
$stmt = $db->prepare("UPDATE song_requests SET status = 'played' WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
|
|
$bonus = false;
|
|
if ($req && $req['is_priority'] == 1 && !empty($username)) {
|
|
$createdAt = strtotime($req['created_at']);
|
|
$now = time();
|
|
$diff = $now - $createdAt;
|
|
|
|
// Award bonus if handled in less than 5 minutes (300 seconds)
|
|
if ($diff <= 300) {
|
|
require_once __DIR__ . '/../includes/points_helper.php';
|
|
awardLoyaltyPoints($username, 100);
|
|
|
|
// Announce bonus
|
|
$chatMsg = "⚡ ¡BONO DE EFICIENCIA! El DJ **$username** ha atendido un Salto VIP en récord (" . floor($diff/60) . "m " . ($diff%60) . "s). ¡Ha ganado **+100 LP**! 🎧👑";
|
|
$db->prepare("INSERT INTO messages (username, message, type) VALUES ('Sistema', ?, 'dj_power')")->execute([$chatMsg]);
|
|
$bonus = true;
|
|
}
|
|
}
|
|
|
|
echo json_encode(['success' => true, 'bonus_awarded' => $bonus, 'was_priority' => ($req && $req['is_priority'] == 1)]);
|
|
} elseif ($action === 'delete') {
|
|
$stmt = $db->prepare("DELETE FROM song_requests WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
echo json_encode(['success' => true]);
|
|
} else {
|
|
echo json_encode(['success' => false, 'error' => 'Acción no reconocida']);
|
|
}
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
$artist = trim($_POST['artist'] ?? '');
|
|
$song = trim($_POST['song'] ?? '');
|
|
$requester = trim($_POST['requester'] ?? 'Anónimo');
|
|
$source = trim($_POST['source'] ?? 'web');
|
|
|
|
if (empty($artist) || empty($song)) {
|
|
echo json_encode(['success' => false, 'error' => 'Falta artista o canción']);
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
// Auto-DJ: Check if we should "execute" this song immediately
|
|
// 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, duration) VALUES (?, ?, ?, ?, ?, ?)");
|
|
$stmt->execute([$artist, $song, $requester, $source, $initialStatus, 240]);
|
|
$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
|
|
if ($requester !== 'Anónimo') {
|
|
require_once __DIR__ . '/../includes/points_helper.php';
|
|
awardPoints($requester, 25);
|
|
|
|
if ($source === 'whatsapp') {
|
|
announceWhatsAppRequest($requester, $artist, $song);
|
|
} else {
|
|
announceSongRequest($requester, $artist, $song);
|
|
}
|
|
}
|
|
|
|
// Send Email Notification
|
|
try {
|
|
require_once __DIR__ . '/../mail/MailService.php';
|
|
$subject = "Nueva Petición de Canción: $artist - $song";
|
|
$htmlBody = "
|
|
<h3>Nueva Petición de Canción</h3>
|
|
<p><strong>De:</strong> $requester</p>
|
|
<p><strong>Artista:</strong> $artist</p>
|
|
<p><strong>Canción:</strong> $song</p>
|
|
<p><strong>Fuente:</strong> $source</p>
|
|
<p><strong>Fecha:</strong> " . date('Y-m-d H:i:s') . "</p>
|
|
";
|
|
MailService::sendMail(null, $subject, $htmlBody);
|
|
} catch (Exception $e) {
|
|
// Silently fail email but log it
|
|
error_log("Email request failed: " . $e->getMessage());
|
|
}
|
|
|
|
// Check if this user is now the #1 listener of the week
|
|
$topStmt = $db->query("
|
|
SELECT requester, COUNT(*) as total_requests
|
|
FROM song_requests
|
|
WHERE requester IS NOT NULL AND requester != '' AND requester != 'Anónimo'
|
|
AND created_at > DATE_SUB(NOW(), INTERVAL 7 DAY)
|
|
GROUP BY requester
|
|
ORDER BY total_requests DESC
|
|
LIMIT 1
|
|
");
|
|
$topListener = $topStmt->fetch();
|
|
|
|
$isNewTop = false;
|
|
if ($topListener && $topListener['requester'] === $requester) {
|
|
$isNewTop = true;
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'is_top' => $isNewTop,
|
|
'top_name' => $topListener['requester'] ?? ''
|
|
]);
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
if ($method === 'GET') {
|
|
$action = $_GET['action'] ?? 'list';
|
|
|
|
if ($action === 'stats') {
|
|
try {
|
|
// Top artists
|
|
$stmt = $db->query("SELECT artist, COUNT(*) as count FROM song_requests GROUP BY artist ORDER BY count DESC LIMIT 5");
|
|
$top_artists = $stmt->fetchAll();
|
|
|
|
// Top songs
|
|
$stmt = $db->query("SELECT artist, song, COUNT(*) as count FROM song_requests GROUP BY artist, song ORDER BY count DESC LIMIT 5");
|
|
$top_songs = $stmt->fetchAll();
|
|
|
|
// Request volume by hour (last 24 hours)
|
|
$stmt = $db->query("SELECT HOUR(created_at) as hour, COUNT(*) as count FROM song_requests WHERE created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR) GROUP BY hour ORDER BY hour ASC");
|
|
$volume_stats = $stmt->fetchAll();
|
|
|
|
// Visitor locations (last 10 minutes)
|
|
$stmt = $db->query("SELECT country, country_code, lat, lon, COUNT(*) as count FROM visitor_logs WHERE last_activity > DATE_SUB(NOW(), INTERVAL 10 MINUTE) GROUP BY country_code");
|
|
$locations = $stmt->fetchAll();
|
|
|
|
// Total requests today
|
|
$stmt = $db->query("SELECT COUNT(*) FROM song_requests WHERE DATE(created_at) = CURDATE()");
|
|
$requests_today = $stmt->fetchColumn();
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'top_artists' => $top_artists,
|
|
'top_songs' => $top_songs,
|
|
'volume_stats' => $volume_stats,
|
|
'locations' => $locations,
|
|
'requests_today' => $requests_today
|
|
]);
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
// Auto-archive requests older than 2 hours (7200 seconds)
|
|
$db->query("UPDATE song_requests SET status = 'played' WHERE status = 'pending' AND created_at < (NOW() - INTERVAL 2 HOUR)");
|
|
|
|
$status = $_GET['status'] ?? 'pending';
|
|
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 10;
|
|
|
|
if ($status === 'all') {
|
|
$stmt = $db->query("SELECT * FROM song_requests ORDER BY is_priority DESC, created_at DESC LIMIT $limit");
|
|
} else {
|
|
$stmt = $db->prepare("SELECT * FROM song_requests WHERE status = ? ORDER BY is_priority DESC, created_at DESC LIMIT $limit");
|
|
$stmt->execute([$status]);
|
|
}
|
|
|
|
$requests = $stmt->fetchAll();
|
|
echo json_encode(['success' => true, 'requests' => $requests]);
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'requests' => [], 'error' => $e->getMessage()]);
|
|
}
|
|
exit;
|
|
}
|
|
|