const axios = require('axios'); const moment = require('moment-timezone'); const http = require('http'); const cron = require('node-cron'); const port = process.env.PORT || 7860; // URLs to keep alive (24-hour visit cycle) const webpages = [ 'https://huggingface.co/spaces/issaocean/deepseek-api', // deepseek2api 'https://huggingface.co/spaces/issaocean/miaoClaudeService', // ClaudeService 'https://huggingface.co/spaces/issaocean/keep-alive-24h', // keep-alive service 'https://huggingface.co/spaces/issaocean/gemini-balance', // Gemini Balance 'https://huggingface.co/spaces/issaocean/freeapi' // Blackbox2api ]; // Access logs for displaying detailed information const accessLogs = {}; // Create HTTP server const createServer = () => { const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.end(generateStatusPage()); }); server.listen(port, () => { console.log(`Server started on port: ${port}`); }); }; // Calculate next execution time function getNextExecutionTime() { const now = moment().tz('Asia/Hong_Kong'); // Calculate the next 24-hour point const nextExecution = moment().tz('Asia/Hong_Kong').add(12, 'hours').startOf('hour'); return nextExecution.format('YYYY-MM-DD HH:mm:ss'); } // Get server uptime let startTime = new Date(); function getUptime() { const now = new Date(); const uptimeMs = now - startTime; const days = Math.floor(uptimeMs / (24 * 60 * 60 * 1000)); const hours = Math.floor((uptimeMs % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000)); const minutes = Math.floor((uptimeMs % (60 * 60 * 1000)) / (60 * 1000)); const seconds = Math.floor((uptimeMs % (60 * 1000)) / 1000); return `${days}d ${hours}h ${minutes}m ${seconds}s`; } // Generate HTML status page function generateStatusPage() { const currentTime = moment().tz('Asia/Hong_Kong').format('YYYY-MM-DD HH:mm:ss'); let lastCheckTime = "Never checked"; if (Object.keys(accessLogs).length > 0) { lastCheckTime = Object.values(accessLogs).sort((a, b) => b.timestamp - a.timestamp)[0].time; } // Generate access record cards let webpageCards = ''; for (const url of webpages) { const log = accessLogs[url]; const status = log ? (log.status === 200 ? 'Success' : 'Failed') : 'Waiting'; const statusClass = log ? (log.status === 200 ? 'success' : 'error') : 'waiting'; const time = log ? log.time : 'Not checked yet'; const shortUrl = url.replace(/https?:\/\/(www\.)?huggingface\.co\/spaces\//, ''); const spaceName = shortUrl.split('/').pop(); webpageCards += `
${log && log.status === 200 ? '' : (log ? '' : '') }

${spaceName}

${shortUrl}

${status}

Last access: ${time}

`; } return ` HuggingFace Spaces Keep-Alive Service

HuggingFace Spaces Keep-Alive Service

Keep your HuggingFace Spaces applications online 24/7

Service Running

Current Time

${currentTime}

Last Check

${lastCheckTime}

Next Check

${getNextExecutionTime()}

Uptime

${getUptime()}

Monitoring Status

${webpageCards}
`; } // Access function async function access(url) { try { const response = await axios.get(url); const currentTime = moment().tz('Asia/Hong_Kong').format('YYYY-MM-DD HH:mm:ss'); accessLogs[url] = { status: response.status, time: currentTime, timestamp: Date.now() }; console.log(`${currentTime} Successfully accessed: ${url} - Status: ${response.status}`); } catch (error) { const currentTime = moment().tz('Asia/Hong_Kong').format('YYYY-MM-DD HH:mm:ss'); accessLogs[url] = { status: error.response ? error.response.status : 0, time: currentTime, timestamp: Date.now() }; console.error(`${currentTime} Failed to access ${url}, Error: ${error.message}`); } } // Batch visit all URLs async function batchVisit() { console.log(`${moment().tz('Asia/Hong_Kong').format('YYYY-MM-DD HH:mm:ss')} Starting 24-hour visit cycle...`); for (let url of webpages) { await access(url); } } // Restart function const restart = () => { console.log(`${moment().tz('Asia/Hong_Kong').format('YYYY-MM-DD HH:mm:ss')} Server restarting...`); process.exit(1); // Exit process, Docker will automatically restart }; // Start server createServer(); // Schedule task: every 24 hours cron.schedule('0 0 */24 * * *', async () => { await batchVisit(); // Visit all URLs first restart(); // Then restart the service }); // Run immediately on startup batchVisit().catch(console.error);