Add app auth, dashboard, scheduler, video management, and new scrapers

- 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>
This commit is contained in:
Trey T
2026-04-16 07:48:10 -05:00
parent 4903b84aef
commit 236f36aae6
54 changed files with 9986 additions and 420 deletions
+74
View File
@@ -0,0 +1,74 @@
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;