fix(scanner): resolve dirs via CLI/env/constants; write per-item JSON; skip trash
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## Changes 10/4/2025 v1.3.13
|
||||
|
||||
fix(scanner): resolve dirs via CLI/env/constants; write per-item JSON; skip trash
|
||||
|
||||
- scan_uploads.php now falls back to UPLOAD_DIR/META_DIR from config.php
|
||||
- prevents double slashes in metadata paths; respects app timezone
|
||||
- skips trash/profile_pics and symlinks; writes JSON only when missing
|
||||
- unblocks SCAN_ON_START so externally added files are indexed at boot
|
||||
|
||||
## Changes 10/4/2025 v1.3.12
|
||||
|
||||
Fix: robust PUID/PGID handling; optional ownership normalization (closes #43)
|
||||
|
||||
@@ -3,7 +3,7 @@ import { loadAdminConfigFunc } from './auth.js';
|
||||
import { showToast, toggleVisibility, attachEnterKeyListener } from './domUtils.js';
|
||||
import { sendRequest } from './networkUtils.js';
|
||||
|
||||
const version = "v1.3.12";
|
||||
const version = "v1.3.13";
|
||||
const adminTitle = `${t("admin_panel")} <small style="font-size:12px;color:gray;">${version}</small>`;
|
||||
|
||||
// ————— Inject updated styles —————
|
||||
|
||||
@@ -1,63 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* scan_uploads.php
|
||||
* Scans the uploads directory and creates metadata entries for new files/folders using config settings.
|
||||
* Scans the uploads directory and creates metadata entries for new files/folders.
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../config/config.php';
|
||||
|
||||
if (!isset($config['upload_dir']) || !isset($config['metadata_dir'])) {
|
||||
die("Missing configuration for upload_dir or metadata_dir\n");
|
||||
// Resolve directories from CLI opts, env, or config.php constants (in that order).
|
||||
$opt = getopt('', ['upload-dir::','metadata-dir::']) ?: [];
|
||||
$uploadDir = $opt['upload-dir'] ?? getenv('upload_dir') ?? getenv('UPLOAD_DIR') ?? (defined('UPLOAD_DIR') ? UPLOAD_DIR : null);
|
||||
$metadataDir = $opt['metadata-dir'] ?? getenv('metadata_dir') ?? getenv('META_DIR') ?? (defined('META_DIR') ? META_DIR : null);
|
||||
|
||||
if (!$uploadDir || !$metadataDir) {
|
||||
fwrite(STDERR, "Missing configuration for upload_dir or metadata_dir\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$uploadDir = $config['upload_dir'];
|
||||
$metadataDir = $config['metadata_dir'];
|
||||
date_default_timezone_set('UTC');
|
||||
// Normalize with exactly one trailing slash
|
||||
$uploadDir = rtrim($uploadDir, '/\\') . '/';
|
||||
$metadataDir = rtrim($metadataDir, '/\\') . '/';
|
||||
|
||||
// Respect the app-wide timezone already set in config.php (do NOT force UTC here)
|
||||
|
||||
/**
|
||||
* Recursively list files and folders under $dir.
|
||||
* Skips symlinks and internal folders we don't want to index.
|
||||
*/
|
||||
function scanDirectory(string $dir): array {
|
||||
$entries = @scandir($dir);
|
||||
if ($entries === false) return [];
|
||||
|
||||
function scanDirectory($dir) {
|
||||
$items = array_diff(scandir($dir), ['.', '..']);
|
||||
$results = [];
|
||||
foreach ($entries as $name) {
|
||||
if ($name === '.' || $name === '..') continue;
|
||||
$path = $dir . $name;
|
||||
|
||||
foreach ($items as $item) {
|
||||
$path = $dir . DIRECTORY_SEPARATOR . $item;
|
||||
$results[] = $path;
|
||||
// Skip symlinks to avoid loops
|
||||
if (is_link($path)) continue;
|
||||
|
||||
// Recurse into directories
|
||||
if (is_dir($path)) {
|
||||
$results = array_merge($results, scanDirectory($path));
|
||||
$results[] = $path . '/';
|
||||
$results = array_merge($results, scanDirectory($path . '/'));
|
||||
} else {
|
||||
$results[] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
function metadataPath($filePath, $uploadDir, $metadataDir) {
|
||||
$relativePath = ltrim(str_replace($uploadDir, '', $filePath), '/');
|
||||
return $metadataDir . '/' . $relativePath . '.json';
|
||||
/**
|
||||
* Build the metadata JSON path parallel to uploads/ for a given item.
|
||||
*/
|
||||
function metadataPath(string $itemPath, string $uploadDir, string $metadataDir): string {
|
||||
$relative = ltrim(str_replace($uploadDir, '', $itemPath), '/\\');
|
||||
return $metadataDir . $relative . '.json';
|
||||
}
|
||||
|
||||
$allItems = scanDirectory($uploadDir);
|
||||
|
||||
foreach ($allItems as $item) {
|
||||
// Derive a relative path (used in metadata and for skip rules)
|
||||
$relative = ltrim(str_replace($uploadDir, '', $item), '/\\');
|
||||
|
||||
// Skip some internal areas under uploads/
|
||||
if (strpos($relative, 'trash/') === 0 || strpos($relative, 'profile_pics/') === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$metaPath = metadataPath($item, $uploadDir, $metadataDir);
|
||||
|
||||
if (!file_exists($metaPath)) {
|
||||
$type = is_dir($item) ? 'folder' : 'file';
|
||||
$size = is_file($item) ? filesize($item) : 0;
|
||||
|
||||
$isDir = is_dir($item);
|
||||
$metadata = [
|
||||
'path' => str_replace($uploadDir, '', $item),
|
||||
'type' => $type,
|
||||
'size' => $size,
|
||||
'user' => 'Imported',
|
||||
'uploadDate' => date('c')
|
||||
'path' => rtrim($relative, '/'),
|
||||
'type' => $isDir ? 'folder' : 'file',
|
||||
'size' => (!$isDir && is_file($item)) ? (int)filesize($item) : 0,
|
||||
'user' => 'Imported',
|
||||
'uploadDate' => date('c'),
|
||||
];
|
||||
|
||||
if (!is_dir(dirname($metaPath))) {
|
||||
mkdir(dirname($metaPath), 0775, true);
|
||||
// Ensure parent directory exists with sane perms (umask from start.sh handles final modes)
|
||||
$parent = dirname($metaPath);
|
||||
if (!is_dir($parent)) {
|
||||
@mkdir($parent, 0775, true);
|
||||
}
|
||||
|
||||
file_put_contents($metaPath, json_encode($metadata, JSON_PRETTY_PRINT));
|
||||
echo "Created metadata for: {$item}\n";
|
||||
if (@file_put_contents($metaPath, json_encode($metadata, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)) === false) {
|
||||
fwrite(STDERR, "Failed to write metadata: {$metaPath}\n");
|
||||
} else {
|
||||
echo "Created metadata for: {$relative}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user