Add quota for home directories

Set default quota amount in Admin -> Applications -> Filemanager -> Quota
This commit is contained in:
nathan 2022-11-18 12:42:53 -07:00
parent 6857e858de
commit 8434549ace
7 changed files with 149 additions and 40 deletions

View File

@ -36,7 +36,7 @@ $setup_info['admin']['hooks']['config'] = 'admin_hooks::config';
$setup_info['admin']['hooks']['edit_group'] = \EGroupware\Admin\Groups::class.'::edit_group'; $setup_info['admin']['hooks']['edit_group'] = \EGroupware\Admin\Groups::class.'::edit_group';
// add account tab to addressbook.edit // add account tab to addressbook.edit
$setup_info['admin']['hooks']['addressbook_edit'] = 'admin.admin_account.addressbook_edit'; $setup_info['admin']['hooks']['addressbook_edit'][] = 'admin.admin_account.addressbook_edit';
// Dependencies for this app to work // Dependencies for this app to work
$setup_info['admin']['depends'][] = array( $setup_info['admin']['depends'][] = array(

View File

@ -52,13 +52,13 @@
<description/> <description/>
</row> </row>
<row> <row>
<description value="Primary group" for="account_primary_group"/> <description value="Primary group" for="account_primary_group"/>
<select-account id="account_primary_group" account_type="groups" class="et2_fullWidth"/> <select-account id="account_primary_group" account_type="groups" class="et2_fullWidth"/>
<description/> <description/>
<description/> <description value="Filesystem quota" disabled="!@epl"/>
<description/> <textbox id="quota" readonly="true" blur="@default_quota"/>
<description/> <description/>
</row> </row>
<row> <row>
<description value="Groups" for="account_groups"/> <description value="Groups" for="account_groups"/>
<select-account account_type="groups" id="account_groups" multiple="true" class="et2_fullWidth" span="4" tags="true"/> <select-account account_type="groups" id="account_groups" multiple="true" class="et2_fullWidth" span="4" tags="true"/>

View File

@ -275,7 +275,15 @@ class StreamWrapper extends Base implements StreamWrapperIface
*/ */
function stream_write ( $data ) function stream_write ( $data )
{ {
return fwrite($this->opened_stream,$data); Api\Hooks::process(
array(
'location' => 'vfs_pre-write',
'path' => $this->opened_stream_path,
'length' => strlen($data)
)
);
return fwrite($this->opened_stream, $data);
} }
/** /**

View File

@ -504,30 +504,51 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
*/ */
function PUT(&$options) function PUT(&$options)
{ {
$fspath = $this->base . $options["path"]; $fspath = $this->base . $options["path"];
$dir = dirname($fspath); $dir = dirname($fspath);
if (!file_exists($dir) || !is_dir($dir)) { if(!file_exists($dir) || !is_dir($dir))
return "409 Conflict"; // TODO right status code for both? {
} return "409 Conflict"; // TODO right status code for both?
}
$options["new"] = ! file_exists($fspath); $options["new"] = !file_exists($fspath);
if ($options["new"] && !$this->_is_writable($dir)) { if($options["new"] && !$this->_is_writable($dir))
return "403 Forbidden"; {
} return "403 Forbidden";
if (!$options["new"] && !$this->_is_writable($fspath)) { }
return "403 Forbidden"; if(!$options["new"] && !$this->_is_writable($fspath))
} {
if (!$options["new"] && is_dir($fspath)) { return "403 Forbidden";
return "403 Forbidden"; }
} if(!$options["new"] && is_dir($fspath))
{
return "403 Forbidden";
}
// Check quota
try
{
\EGroupware\Api\Hooks::process(
array(
'location' => 'vfs_pre-write',
'path' => $options['path'],
'length' => $options['content_length']
)
);
}
catch (Exception $e)
{
// $e->getMessage() has information about limits
return "413 Payload Too Large";
}
// for range requests we need to open with "c" as "w" truncates the file! // for range requests we need to open with "c" as "w" truncates the file!
$fp = fopen($fspath, empty($options['ranges']) ? "w" : "c"); $fp = fopen($fspath, empty($options['ranges']) ? "w" : "c");
return $fp; return $fp;
} }
/** /**

View File

@ -28,8 +28,8 @@ class filemanager_admin extends filemanager_ui
*/ */
public $public_functions = array( public $public_functions = array(
'index' => true, 'index' => true,
'fsck' => true, 'fsck' => true,
'quotaRecalc' => true, 'quota' => true,
); );
/** /**
@ -359,18 +359,69 @@ class filemanager_admin extends filemanager_ui
} }
$check_only = !isset($_POST['fix']); $check_only = !isset($_POST['fix']);
if (!($msgs = Vfs\Sqlfs\Utils::fsck($check_only))) if(!($msgs = Vfs\Sqlfs\Utils::fsck($check_only)))
{ {
$msgs = lang('Filesystem check reported no problems.'); $msgs = lang('Filesystem check reported no problems.');
} }
$content = '<p>'.implode("</p>\n<p>", (array)$msgs)."</p>\n"; $content = '<p>' . implode("</p>\n<p>", (array)$msgs) . "</p>\n";
$content .= Api\Html::form('<p>'.($check_only&&is_array($msgs) ? $content .= Api\Html::form('<p>' . ($check_only && is_array($msgs) ?
Api\Html::submit_button('fix', lang('Fix reported problems')) : ''). Api\Html::submit_button('fix', lang('Fix reported problems')) : '') .
Api\Html::submit_button('cancel', lang('Cancel')).'</p>', Api\Html::submit_button('cancel', lang('Cancel')) . '</p>',
'','/index.php',array('menuaction'=>'filemanager.filemanager_admin.fsck')); '', '/index.php', array('menuaction' => 'filemanager.filemanager_admin.fsck')
);
$GLOBALS['egw']->framework->render($content, lang('Admin').' - '.lang('Check virtual filesystem'), true); $GLOBALS['egw']->framework->render($content, lang('Admin') . ' - ' . lang('Check virtual filesystem'), true);
}
/**
* Admin tasks related to quota
*
* Manually trigger a directory size recalculation
*
* @param array $content
* @return void
* @throws Api\Exception\AssertionFailed
*/
public function quota(array $content = null)
{
if(is_array($content))
{
$button = key($content['button']);
switch($button)
{
case 'recalculate':
Framework::message($this->quotaRecalc());
break;
case 'save':
case 'apply':
if($button == 'apply')
{
break;
}
// fall-through for save
case 'cancel':
// Reload tracker app
if(Api\Json\Response::isJSONResponse())
{
Api\Json\Response::get()->apply('app.admin.load');
}
Framework::redirect_link('/index.php', array(
'menuaction' => 'admin.admin_ui.index',
'ajax' => 'true'
), 'admin');
break;
}
}
$content = [];
$readonlys['quota'] = !($GLOBALS['egw_info']['apps']['stylite']);
$tpl = new Etemplate('filemanager.quota');
$GLOBALS['egw_info']['flags']['app_header'] = lang('Quota');
$tpl->exec('filemanager.filemanager_admin.quota', $content, $sel_options, $readonlys);
} }
/** /**
@ -380,6 +431,6 @@ class filemanager_admin extends filemanager_ui
{ {
list($dirs, $iterations, $time) = Vfs\Sqlfs\Utils::quotaRecalc(); list($dirs, $iterations, $time) = Vfs\Sqlfs\Utils::quotaRecalc();
echo lang("Recalculated %1 directories in %2 iterations and %3 seconds", $dirs, $iterations, number_format($time, 1))."\n"; return lang("Recalculated %1 directories in %2 iterations and %3 seconds", $dirs, $iterations, number_format($time, 1)) . "\n";
} }
} }

View File

@ -94,11 +94,11 @@ class filemanager_hooks
{ {
if (is_array($location)) $location = $location['location']; if (is_array($location)) $location = $location['location'];
$file = Array( $file = array(
//'Site Configuration' => Egw::link('/index.php','menuaction=admin.admin_config.index&appname='.self::$appname.'&ajax=true'), //'Site Configuration' => Egw::link('/index.php','menuaction=admin.admin_config.index&appname='.self::$appname.'&ajax=true'),
'Custom fields' => Egw::link('/index.php','menuaction=admin.admin_customfields.index&appname='.self::$appname.'&ajax=true'), 'Custom fields' => Egw::link('/index.php', 'menuaction=admin.admin_customfields.index&appname=' . self::$appname . '&ajax=true'),
'Check virtual filesystem' => Egw::link('/index.php','menuaction=filemanager.filemanager_admin.fsck'), 'Check virtual filesystem' => Egw::link('/index.php', 'menuaction=filemanager.filemanager_admin.fsck'),
'Recalculate quota' => Egw::link('/index.php','menuaction=filemanager.filemanager_admin.quotaRecalc'), 'Quota' => Egw::link('/index.php', 'menuaction=filemanager.filemanager_admin.quota&ajax=true'),
'VFS mounts and versioning' => Egw::link('/index.php', 'menuaction=filemanager.filemanager_admin.index&ajax=true'), 'VFS mounts and versioning' => Egw::link('/index.php', 'menuaction=filemanager.filemanager_admin.index&ajax=true'),
); );
if ($location == 'admin') if ($location == 'admin')

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
<!-- $Id$ -->
<overlay>
<template id="filemanager.quota" template="" lang="" group="0" version="1.9.004">
<vbox>
<textbox label="Home quota" id="quota" blur="(EPL Only)" disabled="true"/>
<button label="Recalculate" id="button[recalculate]" statustext="Recalculate directory sizes"/>
<hbox span="2" class="dialogFooterToolbar">
<button label="Save" id="button[save]"/>
<button label="Apply" id="button[apply]"/>
<button label="Cancel" id="button[cancel]"/>
</hbox>
</vbox>
<styles>
#filemanager-quota_quota::part(form-control-input) {
max-width: 15ex;
}
#filemanager-quota > div > et2-vbox {
height: 100%;
}
.dialogFooterToolbar {
margin-top: auto;
}
</styles>
</template>
</overlay>