236f36aae6
- JWT-based app authentication with user roles, folder/route access control - Dashboard with storage stats, health checks, and recent activity - Auto-download/scrape scheduler (12h interval) with per-user and per-job configs - Video upload, tagging, HLS transcoding, and detail pages - New scrapers: LeakGallery, Mega (megajs), yt-dlp - FlareSolverr integration for Cloudflare-protected sites - Gallery: advanced filtering (date, size, search), sort modes, equal-mix shuffle - Forum sites management with stored cookies/auth - GridWall/GridCell components for responsive media grid - Media API with folder-access permissions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
75 lines
1.9 KiB
JavaScript
75 lines
1.9 KiB
JavaScript
import { Router } from 'express';
|
|
import { existsSync, accessSync, constants, statfsSync } from 'fs';
|
|
import { execFileSync } from 'child_process';
|
|
import { getAuthConfig } from './db.js';
|
|
import { getActiveDownloadCount } from './download.js';
|
|
import { getActiveScrapeCount } from './scrape.js';
|
|
|
|
const router = Router();
|
|
const MEDIA_PATH = process.env.MEDIA_PATH || './data/media';
|
|
const WVD_PATH = process.env.WVD_PATH || '/data/cdm/device.wvd';
|
|
|
|
router.get('/api/health', (req, res) => {
|
|
const result = {
|
|
uptime: Math.floor(process.uptime()),
|
|
sqlite: false,
|
|
authConfigured: false,
|
|
mediaPathWritable: false,
|
|
ffmpegAvailable: false,
|
|
pythonAvailable: false,
|
|
wvdPresent: false,
|
|
diskSpace: null,
|
|
activeDownloads: 0,
|
|
activeScrapes: 0,
|
|
};
|
|
|
|
// SQLite check
|
|
try {
|
|
getAuthConfig(); // simple query to verify DB works
|
|
result.sqlite = true;
|
|
} catch { /* ignore */ }
|
|
|
|
// Auth check
|
|
try {
|
|
result.authConfigured = !!getAuthConfig();
|
|
} catch { /* ignore */ }
|
|
|
|
// Media path writable
|
|
try {
|
|
accessSync(MEDIA_PATH, constants.W_OK);
|
|
result.mediaPathWritable = true;
|
|
} catch { /* ignore */ }
|
|
|
|
// FFmpeg
|
|
try {
|
|
execFileSync('ffmpeg', ['-version'], { timeout: 5000, stdio: 'pipe' });
|
|
result.ffmpegAvailable = true;
|
|
} catch { /* ignore */ }
|
|
|
|
// Python
|
|
try {
|
|
execFileSync('python3', ['--version'], { timeout: 5000, stdio: 'pipe' });
|
|
result.pythonAvailable = true;
|
|
} catch { /* ignore */ }
|
|
|
|
// WVD file
|
|
result.wvdPresent = existsSync(WVD_PATH);
|
|
|
|
// Disk space
|
|
try {
|
|
const stats = statfsSync(MEDIA_PATH);
|
|
result.diskSpace = {
|
|
free: stats.bfree * stats.bsize,
|
|
total: stats.blocks * stats.bsize,
|
|
};
|
|
} catch { /* ignore */ }
|
|
|
|
// Active jobs
|
|
result.activeDownloads = getActiveDownloadCount();
|
|
result.activeScrapes = getActiveScrapeCount();
|
|
|
|
res.json(result);
|
|
});
|
|
|
|
export default router;
|