freax-media/get_files.php
2026-02-02 12:26:55 -05:00

113 lines
3.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* get_files.php - Recursively scans media directories and returns file structure as JSON
*/
declare(strict_types=1);
header('Content-Type: application/json; charset=utf-8');
// Media type from query parameter (default: videos)
$type = $_GET['type'] ?? 'videos';
// Resolve base directory (make this configurable via env in production)
$homeDir = getenv('HOME') ?: (getenv('USERPROFILE') ?: ('/home/' . get_current_user()));
$baseDir = rtrim($homeDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'GDrive';
$directories = [
'videos' => $baseDir . DIRECTORY_SEPARATOR . 'Videos',
'music' => $baseDir . DIRECTORY_SEPARATOR . 'Music',
];
// Extensions per tab (dont mix)
$extensionsByType = [
'videos' => ['mp4', 'mkv', 'avi', 'mov', 'wmv', 'flv', 'webm', 'm4v'],
'music' => ['mp3', 'wav', 'ogg', 'flac', 'm4a', 'aac', 'wma', 'opus'],
];
if (!isset($directories[$type])) {
echo json_encode(['error' => 'Invalid media type']);
exit;
}
$targetDir = $directories[$type];
$validExtensions = $extensionsByType[$type];
// Fail fast if dir missing
if (!is_dir($targetDir)) {
echo json_encode(['error' => 'Directory not found']);
exit;
}
/**
* Recursively scan a directory and build a folder->(folders/files) structure.
* Files are returned as paths relative to $baseDir.
*/
function scanDirectory(string $dir, string $baseDir, array $validExtensions): array
{
$result = [];
// scandir() can return false on permissions
$items = @scandir($dir);
if ($items === false) return [];
foreach ($items as $item) {
// Skip dot/hidden entries
if ($item === '.' || $item === '..' || ($item !== '' && $item[0] === '.')) {
continue;
}
$fullPath = $dir . DIRECTORY_SEPARATOR . $item;
if (is_dir($fullPath)) {
$sub = scanDirectory($fullPath, $baseDir, $validExtensions);
if (!empty($sub)) {
$result[$item] = $sub;
}
continue;
}
$ext = strtolower(pathinfo($item, PATHINFO_EXTENSION));
if (!in_array($ext, $validExtensions, true)) {
continue;
}
// Build a relative path from baseDir. Use realpath() to normalize.
$realBase = realpath($baseDir);
$realFile = realpath($fullPath);
if ($realBase === false || $realFile === false) {
continue;
}
// Enforce: file must live under baseDir
if (strpos($realFile, $realBase . DIRECTORY_SEPARATOR) !== 0) {
continue;
}
$relativePath = substr($realFile, strlen($realBase) + 1); // +1 skips the slash
$result[$item] = $relativePath;
}
// Sort: folders first, then files, alphabetically
uksort($result, function ($a, $b) use ($result) {
$aIsDir = is_array($result[$a]);
$bIsDir = is_array($result[$b]);
if ($aIsDir && !$bIsDir) return -1;
if (!$aIsDir && $bIsDir) return 1;
// IMPORTANT: keys can be ints if the filename is numeric (e.g. "01", "2026")
return strcasecmp((string)$a, (string)$b);
});
return $result;
}
$tree = scanDirectory($targetDir, $baseDir, $validExtensions);
echo json_encode(
empty($tree) ? ['message' => 'No media files found'] : $tree,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);