Calculate directory sizes in background
This commit is contained in:
@@ -5,17 +5,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
unav_json(unav_job_read($_GET['id'] ?? ''));
|
||||
}
|
||||
|
||||
unav_assert_writable();
|
||||
|
||||
$action = $_GET['action'] ?? '';
|
||||
if (!in_array($action, ['move', 'copy'], true)) {
|
||||
if (!in_array($action, ['move', 'copy', 'size'], true)) {
|
||||
unav_error(404, 'Unknown job action');
|
||||
}
|
||||
|
||||
$data = unav_request_data();
|
||||
$source = unav_existing_path($data['source'] ?? null);
|
||||
$destination = unav_destination_path($data['destination'] ?? null);
|
||||
unav_guard_destination($source['path'], $destination['path']);
|
||||
$destination = null;
|
||||
if (in_array($action, ['move', 'copy'], true)) {
|
||||
unav_assert_writable();
|
||||
$destination = unav_destination_path($data['destination'] ?? null);
|
||||
unav_guard_destination($source['path'], $destination['path']);
|
||||
}
|
||||
|
||||
$id = str_replace('.', '', uniqid($action . '-', true));
|
||||
$now = date(DATE_ATOM);
|
||||
@@ -27,7 +29,7 @@ $job = [
|
||||
'message' => 'Queued',
|
||||
'error' => null,
|
||||
'source' => $source['path'],
|
||||
'destination' => $destination['path'],
|
||||
'destination' => $destination['path'] ?? null,
|
||||
'createdAt' => $now,
|
||||
'updatedAt' => $now,
|
||||
];
|
||||
|
||||
@@ -9,12 +9,16 @@ function unav_run_job(string $id): void {
|
||||
$job = unav_job_read($id);
|
||||
try {
|
||||
unav_worker_update($job, 'running', 5, 'Preparing');
|
||||
unav_worker_guard($job['source'], $job['destination']);
|
||||
|
||||
if ($job['type'] === 'move') {
|
||||
unav_worker_guard($job['source'], $job['destination']);
|
||||
unav_worker_move($job['source'], $job['destination'], $job);
|
||||
} elseif ($job['type'] === 'copy') {
|
||||
unav_worker_guard($job['source'], $job['destination']);
|
||||
unav_worker_copy($job['source'], $job['destination'], $job);
|
||||
} elseif ($job['type'] === 'size') {
|
||||
$result = unav_worker_size($job['source'], $job);
|
||||
$job['result'] = $result;
|
||||
} else {
|
||||
throw new RuntimeException('Unknown job action');
|
||||
}
|
||||
@@ -55,6 +59,15 @@ function unav_worker_guard(string $source, string $destination): void {
|
||||
}
|
||||
}
|
||||
|
||||
function unav_worker_guard_source(string $source): string {
|
||||
$sourceReal = realpath($source);
|
||||
if ($sourceReal === false) {
|
||||
throw new RuntimeException('Source not found');
|
||||
}
|
||||
unav_worker_assert_inside_root($sourceReal);
|
||||
return $sourceReal;
|
||||
}
|
||||
|
||||
function unav_worker_assert_inside_root(string $path): void {
|
||||
foreach (unav_roots() as $root) {
|
||||
if (unav_is_inside($path, $root['path'])) {
|
||||
@@ -73,6 +86,38 @@ function unav_worker_move(string $source, string $destination, array &$job): voi
|
||||
unav_worker_delete($source);
|
||||
}
|
||||
|
||||
function unav_worker_size(string $source, array &$job): array {
|
||||
$sourceReal = unav_worker_guard_source($source);
|
||||
unav_worker_update($job, 'running', 10, 'Calculating size');
|
||||
$result = unav_worker_size_recursive($sourceReal);
|
||||
unav_worker_update($job, 'running', 95, 'Size calculated');
|
||||
return $result;
|
||||
}
|
||||
|
||||
function unav_worker_size_recursive(string $path): array {
|
||||
if (is_link($path)) {
|
||||
return ['size' => 0, 'files' => 0, 'directories' => 0];
|
||||
}
|
||||
if (is_file($path)) {
|
||||
return ['size' => filesize($path) ?: 0, 'files' => 1, 'directories' => 0];
|
||||
}
|
||||
if (!is_dir($path)) {
|
||||
return ['size' => 0, 'files' => 0, 'directories' => 0];
|
||||
}
|
||||
|
||||
$total = ['size' => 0, 'files' => 0, 'directories' => 1];
|
||||
foreach (scandir($path) ?: [] as $entry) {
|
||||
if ($entry === '.' || $entry === '..') {
|
||||
continue;
|
||||
}
|
||||
$child = unav_worker_size_recursive($path . '/' . $entry);
|
||||
$total['size'] += $child['size'];
|
||||
$total['files'] += $child['files'];
|
||||
$total['directories'] += $child['directories'];
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
|
||||
function unav_worker_copy(string $source, string $destination, array &$job): void {
|
||||
if (is_link($source)) {
|
||||
throw new RuntimeException('Copying symlinks is not allowed');
|
||||
|
||||
Reference in New Issue
Block a user