![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/.cursor-server/data/User/History/-1ae5e6bb/ |
// Track Status Monitor - Automatic Polling System
// This script automatically checks for track status updates every 30 seconds
class TrackMonitor {
constructor() {
this.monitorKey = 'soundstudiopro_monitor_2025';
this.pollingInterval = 60000; // 60 seconds (reduced from 30)
this.isPolling = false;
this.pollingTimer = null;
this.lastCheck = null;
this.onStatusUpdate = null; // Callback function
this.notifiedTrackIds = new Set(); // Track IDs that have already been notified
this.currentUserId = null; // Will be set from session or page data
}
// Start automatic polling
start() {
if (this.isPolling) {
console.log('đĩ Track monitor already running');
return;
}
console.log('đĩ Starting track status monitor...');
this.isPolling = true;
this.poll();
}
// Stop automatic polling
stop() {
if (this.pollingTimer) {
clearTimeout(this.pollingTimer);
this.pollingTimer = null;
}
this.isPolling = false;
console.log('đĩ Track monitor stopped');
}
// Perform a single check
async poll() {
if (!this.isPolling) return;
try {
console.log('đĩ Checking for track status updates...');
const response = await fetch(`/api/monitor.php?key=${this.monitorKey}`);
const data = await response.json();
if (data.error) {
console.error('đĩ Monitor error:', data.error);
return;
}
this.lastCheck = new Date();
// Process results
this.processResults(data);
// Schedule next poll
this.pollingTimer = setTimeout(() => this.poll(), this.pollingInterval);
} catch (error) {
console.error('đĩ Monitor polling error:', error);
// Retry in 60 seconds on error
this.pollingTimer = setTimeout(() => this.poll(), 60000);
}
}
// Process monitor results
processResults(data) {
const { fixed_tracks, failed_tracks, still_processing } = data;
// Show notifications for fixed tracks
if (fixed_tracks.length > 0) {
console.log(`đĩ ${fixed_tracks.length} track(s) completed!`);
this.showNotification(`${fixed_tracks.length} track(s) are ready to play!`, 'success');
// Trigger page refresh if we're on a relevant page
if (this.shouldRefreshPage()) {
setTimeout(() => {
window.location.reload();
}, 2000);
}
}
// Show notifications for failed tracks
if (failed_tracks.length > 0) {
console.log(`đĩ ${failed_tracks.length} track(s) failed`);
this.showNotification(`${failed_tracks.length} track(s) failed to process`, 'error');
}
// Call callback if provided
if (this.onStatusUpdate && typeof this.onStatusUpdate === 'function') {
this.onStatusUpdate(data);
}
// Update UI if we're on a page with tracks
this.updateTrackStatusUI(data);
}
// Show notification to user
showNotification(message, type = 'info') {
// Create notification element
const notification = document.createElement('div');
notification.className = `track-notification track-notification-${type}`;
notification.innerHTML = `
<div class="notification-content">
<span class="notification-icon">${type === 'success' ? 'â
' : type === 'error' ? 'â' : 'âšī¸'}</span>
<span class="notification-message">${message}</span>
<button class="notification-close" onclick="this.parentElement.parentElement.remove()">Ã</button>
</div>
`;
// Add styles
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: ${type === 'success' ? '#48bb78' : type === 'error' ? '#f56565' : '#4299e1'};
color: white;
padding: 15px 20px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 10000;
max-width: 400px;
animation: slideIn 0.3s ease-out;
`;
// Add to page
document.body.appendChild(notification);
// Auto-remove after 5 seconds
setTimeout(() => {
if (notification.parentElement) {
notification.remove();
}
}, 5000);
}
// Check if we should refresh the current page
shouldRefreshPage() {
const currentPage = window.location.pathname;
const relevantPages = ['/library_new.php', '/feed.php', '/dashboard.php', '/'];
return relevantPages.some(page => currentPage.includes(page));
}
// Update track status in UI
updateTrackStatusUI(data) {
const { fixed_tracks, failed_tracks } = data;
// Update processing tracks display
const processingElements = document.querySelectorAll('.track-status-processing');
processingElements.forEach(element => {
const trackId = element.getAttribute('data-track-id');
// Check if this track was fixed
const fixedTrack = fixed_tracks.find(track => track.track_id == trackId);
if (fixedTrack) {
element.innerHTML = '<span class="status-complete">â
Complete</span>';
element.className = 'track-status-complete';
// Update play button if it exists
const playButton = element.closest('.track-card').querySelector('.play-button');
if (playButton) {
playButton.disabled = false;
playButton.innerHTML = '<i class="fas fa-play"></i> Play';
}
}
// Check if this track failed
const failedTrack = failed_tracks.find(track => track.track_id == trackId);
if (failedTrack) {
element.innerHTML = '<span class="status-failed">â Failed</span>';
element.className = 'track-status-failed';
}
});
}
// Manual check (can be called from UI)
async manualCheck() {
console.log('đĩ Manual track status check...');
await this.poll();
}
// Set callback for status updates
setStatusUpdateCallback(callback) {
this.onStatusUpdate = callback;
}
}
// Global instance
window.trackMonitor = new TrackMonitor();
// Auto-start on pages that show tracks
document.addEventListener('DOMContentLoaded', function() {
const currentPage = window.location.pathname;
const trackPages = ['/library_new.php', '/feed.php', '/dashboard.php', '/'];
if (trackPages.some(page => currentPage.includes(page))) {
console.log('đĩ Auto-starting track monitor on track page');
window.trackMonitor.start();
}
});
// Add CSS for notifications
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
.track-notification .notification-content {
display: flex;
align-items: center;
gap: 10px;
}
.track-notification .notification-close {
background: none;
border: none;
color: white;
font-size: 18px;
cursor: pointer;
margin-left: auto;
}
.track-status-processing {
color: #ed8936;
font-weight: 600;
}
.track-status-complete {
color: #48bb78;
font-weight: 600;
}
.track-status-failed {
color: #f56565;
font-weight: 600;
}
`;
document.head.appendChild(style);