* Change methods to get recursive directory size and to delete a directory recursively

* Allow "unlimited" disk quota
This commit is contained in:
bohwaz 2023-02-14 12:15:15 +01:00
parent 94635065b3
commit 6386bba8ac
5 changed files with 63 additions and 27 deletions

View file

@ -1,3 +1,12 @@
## 0.3.8
* Allow to have "unlimited" quota for users (actually, up to the maximum space available on disk) by setting `-1` as user quota
* Change method for recursive disk space and recursive directory delete
## 0.3.7
* Fix issue #25 dynamic properties with PHP 8.2
## 0.3.6
* Fix division by zero error when quota is zero

View file

@ -321,14 +321,10 @@ class Storage extends AbstractStorage
}
if (is_dir($target)) {
foreach (self::glob($target, '/*') as $file) {
$this->delete(substr($file, strlen($this->users->current()->path)));
}
rmdir($target);
self::deleteDirectory($target);
}
else {
unlink($target);
@unlink($target);
}
$this->getResourceProperties($uri)->clear();
@ -468,14 +464,14 @@ class Storage extends AbstractStorage
{
$total = 0;
$path = rtrim($path, '/');
$path = realpath($path);
foreach (self::glob($path, '/*', GLOB_NOSORT) as $f) {
if (is_dir($f)) {
$total += self::getDirectorySize($f);
}
else {
$total += filesize($f);
}
if (!$path || !file_exists($path)) {
return 0;
}
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS)) as $f) {
$total += $f->getSize();
}
return $total;
@ -483,7 +479,19 @@ class Storage extends AbstractStorage
static public function deleteDirectory(string $path): void
{
foreach (self::glob($path, '/*', GLOB_NOSORT) as $f) {
$path = rtrim($path, '/');
$path = realpath($path);
$dir = opendir($path);
while ($f = readdir($dir)) {
// Skip dots
if ($f == '.' || $f = '..') {
continue;
}
$f = $path . DIRECTORY_SEPARATOR . $f;
if (is_dir($f)) {
self::deleteDirectory($f);
@rmdir($f);
@ -493,6 +501,8 @@ class Storage extends AbstractStorage
}
}
closedir($dir);
@rmdir($path);
}

View file

@ -76,7 +76,7 @@ class Users
return $user;
}
public function create(string $login, string $password, int $quota = 0, bool $is_admin = false)
public function create(string $login, string $password, int $quota = DEFAULT_QUOTA, bool $is_admin = false)
{
$login = strtolower(trim($login));
$hash = password_hash(trim($password), null);
@ -97,7 +97,7 @@ class Users
}
if (isset($data['quota'])) {
$params['quota'] = (int) $data['quota'] * 1024 * 1024;
$params['quota'] = $data['quota'] <= 0 ? (int) $data['quota'] : (int) $data['quota'] * 1024 * 1024;
}
if (isset($data['is_admin'])) {
@ -297,9 +297,21 @@ class Users
$used = $total = $free = 0;
if ($user) {
$used = Storage::getDirectorySize($user->path);
$total = $user->quota;
$free = max(0, $total - $used);
if ($user->quota == -1) {
$total = (int) @disk_total_space($user->path);
$free = (int) @disk_free_space($user->path);
$used = $total - $free;
}
elseif ($user->quota == 0) {
$total = 0;
$free = 0;
$used = 0;
}
else {
$used = Storage::getDirectorySize($user->path);
$total = $user->quota;
$free = max(0, $total - $used);
}
}
return (object) compact('free', 'total', 'used');

View file

@ -77,6 +77,10 @@ if (!defined('KaraDAV\WWW_URL')) {
define('KaraDAV\WWW_URL', sprintf('http%s://%s%s%s', $https, $name, $port, $root));
}
if (!defined('KaraDAV\DEFAULT_QUOTA')) {
define('KaraDAV\DEFAULT_QUOTA', 200);
}
// Init database
if (!file_exists(DB_FILE)) {
$db = DB::getInstance();

View file

@ -88,7 +88,7 @@ elseif ($edit) {
$csrf = html_csrf();
$login = htmlspecialchars($user->login);
$is_admin = $user->is_admin ? 'checked="checked"' : '';
$quota = $user ? round($user->quota / 1024 / 1024) : DEFAULT_QUOTA;
$quota = $user ? ($user->quota > 0 ? round($user->quota / 1024 / 1024) : $user->quota) : DEFAULT_QUOTA;
echo '<form method="post" action="">
' . $csrf . '
@ -109,8 +109,9 @@ elseif ($edit) {
echo '
<dt><label for="f_quota">Quota</label></dt>
<dd><input type="number" name="quota" step="1" min="0" value="' . $quota . '" required="required" size="6" /> (in MB)</dd>
<!--<dd>Set to -1 to have unlimited space</dd>-->
<dd><input type="number" name="quota" step="1" min="-1" value="' . $quota . '" required="required" size="6" /> (in MB)</dd>
<dd>Set to <tt>0</tt> to disable upload.</dd>
<dd>Use <tt>-1</tt> to allow using all the available space on disk.</dd>
<dd><input type="submit" name="save" value="Save" /></dd>
</dl>
</fieldset>
@ -150,7 +151,7 @@ else {
<tbody>';
foreach ($users->list() as $user) {
$used = Storage::getDirectorySize($user->path);
$quota = $users->quota($user);
printf('<tr>
<th>%s</th>
@ -159,10 +160,10 @@ else {
<td><a href="?edit=%d" class="btn sm">Edit</a> <a href="?delete=%d" class="btn sm">Delete</a></td>
</tr>',
htmlspecialchars($user->login),
format_bytes($used),
format_bytes($user->quota),
$user->quota,
$used,
format_bytes($quota->used),
format_bytes($quota->total),
$quota->total,
$quota->used,
$user->is_admin ? 'Admin' : '',
$user->id,
$user->id