diff --git a/plugins/housekeeper/DiskUsageDashlet.inc.php b/plugins/housekeeper/DiskUsageDashlet.inc.php new file mode 100755 index 0000000..7f22ba7 --- /dev/null +++ b/plugins/housekeeper/DiskUsageDashlet.inc.php @@ -0,0 +1,138 @@ +sTitle = _kt('Disk Usage'); + $this->sClass = "ktInfo"; + } + + function is_active($oUser) + { + $dfCmd = KTUtil::findCommand('externalBinary/df','df'); + if ($dfCmd === false) + { + return false; + } + $this->dfCmd = $dfCmd; + + $config = KTConfig::getSingleton(); + $this->warningPercent = $config->get('DiskUsage/warningThreshold', 15); + $this->urgentPercent = $config->get('DiskUsage/urgentThreshold', 5); + + $this->getUsage(); + + return Permission::userIsSystemAdministrator(); + } + + function getUsage($refresh=false) + { + $check = true; + // check if we have a cached result + if (isset($_SESSION['DiskUsage'])) + { + // we will only do the check every 5 minutes + if (time() - $_SESSION['DiskUsage']['time'] < 5 * 60) + { + $check = false; + $this->usage = $_SESSION['DiskUsage']['usage']; + } + } + + // we will only check if the result is not cached, or after 5 minutes + if ($check) + { + $result = ktutil::pexec($this->dfCmd); + + $result = $result['out']; + unset($result[0]); + + $usage=array(); + foreach($result as $line) + { + preg_match('/(.*)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\%\s+(.*)/', $line, $matches); + list($line, $filesystem, $size, $used, $avail, $usedp, $mount) = $matches; + + if ($usedp >= 100 - $this->urgentPercent) + { + $colour = 'red'; + } + elseif ($usedp >= 100 - $this->warningPercent) + { + $colour = 'orange'; + } + + $usage[] = array( + 'filesystem'=>$filesystem, + 'size'=>KTUtil::filesizeToString($size), + 'used'=>KTUtil::filesizeToString($used), + 'available'=>KTUtil::filesizeToString($avail), + 'usage'=>$usedp . '%', + 'mounted'=>$mount, + 'colour'=>$colour + ); + } + + $this->usage = $usage; + + $_SESSION['DiskUsage']['time'] = time(); + $_SESSION['DiskUsage']['usage'] = $this->usage; + } + } + + function render() + { + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate('DiskUsage'); + + $oRegistry =& KTPluginRegistry::getSingleton(); + $oPlugin =& $oRegistry->getPlugin('ktcore.housekeeper.plugin'); + + $dispatcherURL = $oPlugin->getURLPath('HouseKeeperDispatcher.php'); + + + $aTemplateData = array( + 'context' => $this, + 'usages'=>$this->usage, + 'warnPercent'=>$this->warningPercent, + 'urgentPercent'=>$this->urgentPercent, + 'dispatcherURL'=>$dispatcherURL + ); + + return $oTemplate->render($aTemplateData); + } +} + + +?> diff --git a/plugins/housekeeper/FolderUsageDashlet.inc.php b/plugins/housekeeper/FolderUsageDashlet.inc.php new file mode 100755 index 0000000..359cf67 --- /dev/null +++ b/plugins/housekeeper/FolderUsageDashlet.inc.php @@ -0,0 +1,159 @@ +sTitle = _kt('System Folder Usage'); + $this->sClass = "ktInfo"; + } + + function is_active($oUser) + { + return Permission::userIsSystemAdministrator(); + } + + function scanPath($path,$pattern) + { + $files=0; + $filesize=0; + + if ($dh = opendir($path)) + { + while (($file = readdir($dh)) !== false) + { + if (substr($file,0,1) == '.') + { + continue; + } + + $full = $path . '/' . $file; + + if (!is_readable($full) || !is_writable($full)) + { + continue; + } + + if (is_dir($full)) + { + $result = $this->scanPath($full,$pattern); + $files += $result['files']; + $filesize += $result['filesize']; + continue; + } + if ($pattern != '') + { + if (preg_match('/' . $pattern . '/', $file) === false) + { + continue; + } + } + + $files++; + $filesize += filesize($full); + } + closedir($dh); + } + return array('files'=>$files,'filesize'=>$filesize,'dir'=>$path); + } + + function getUsage() + { + $check = true; + // check if we have a cached result + if (isset($_SESSION['SystemFolderUsage'])) + { + // we will only do the check every 5 minutes + if (time() - $_SESSION['SystemFolderUsage']['time'] < 5 * 60) + { + $check = false; + $this->usage = $_SESSION['SystemFolderUsage']['usage']; + } + } + + // we will only check if the result is not cached, or after 5 minutes + if ($check) + { + $usage = array(); + + $oRegistry =& KTPluginRegistry::getSingleton(); + $oPlugin =& $oRegistry->getPlugin('ktcore.housekeeper.plugin'); + + $folders = $oPlugin->getDirectories(); + + foreach($folders as $folder) + { + $directory = $folder['folder']; + $pattern = $folder['pattern']; + $canClean = $folder['canClean']; + $name = $folder['name']; + + $temp = $this->scanPath($directory,$pattern); + + $usage[] = array( + 'description'=>$name, + 'folder'=>$directory, + 'files'=>number_format($temp['files'],0,'.',','), + 'filesize'=>KTUtil::filesizeToString($temp['filesize']), + 'action'=>$i, + 'canClean'=>$canClean + ); + $this->usage = $usage; + } + + $_SESSION['SystemFolderUsage']['time'] = time(); + $_SESSION['SystemFolderUsage']['usage'] = $this->usage; + } + } + + function render() + { + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate('FolderUsage'); + + $oRegistry =& KTPluginRegistry::getSingleton(); + $oPlugin =& $oRegistry->getPlugin('ktcore.housekeeper.plugin'); + + $dispatcherURL = $oPlugin->getURLPath('HouseKeeperDispatcher.php'); + + $this->getUsage(); + + $aTemplateData = array( + 'context' => $this, + 'usages'=>$this->usage, + 'dispatcherURL'=>$dispatcherURL + ); + + return $oTemplate->render($aTemplateData); + } +} + + +?> diff --git a/plugins/housekeeper/HouseKeeperDispatcher.php b/plugins/housekeeper/HouseKeeperDispatcher.php new file mode 100644 index 0000000..5138544 --- /dev/null +++ b/plugins/housekeeper/HouseKeeperDispatcher.php @@ -0,0 +1,91 @@ +cleanDirectory($full,$pattern); + if (is_writable($full)) + { + @rmdir($full); + } + continue; + } + + if (!empty($pattern) && !preg_match('/' . $pattern . '/', $file)) + { + continue; + } + + if (is_writable($full)) + { + @unlink($full); + } + + } + closedir($dh); + } + + } + + function do_cleanup() + { + $folder = KTUtil::arrayGet($_REQUEST, 'folder'); + if (is_null($folder)) + { + exit(redirect(generateControllerLink('dashboard'))); + } + + $oRegistry =& KTPluginRegistry::getSingleton(); + $oPlugin =& $oRegistry->getPlugin('ktcore.housekeeper.plugin'); + + // we must avoid doing anything to the documents folder at all costs! + $folder = $oPlugin->getDirectory($folder); + if (is_null($folder) || !$folder['canClean']) + { + exit(redirect(generateControllerLink('dashboard'))); + } + + $this->cleanDirectory($folder['folder'], $folder['pattern']); + + $this->do_refreshFolderUsage(); + } + + function do_refreshDiskUsage() + { + session_unregister('DiskUsage'); + exit(redirect(generateControllerLink('dashboard'))); + } + + function do_refreshFolderUsage() + { + session_unregister('SystemFolderUsage'); + exit(redirect(generateControllerLink('dashboard'))); + } +} +$oDispatcher = new HouseKeeperDispatcher(); +$oDispatcher->dispatch(); + +?> \ No newline at end of file diff --git a/plugins/housekeeper/HouseKeeperPlugin.php b/plugins/housekeeper/HouseKeeperPlugin.php new file mode 100755 index 0000000..793600b --- /dev/null +++ b/plugins/housekeeper/HouseKeeperPlugin.php @@ -0,0 +1,96 @@ +sFriendlyName = _kt('Housekeeper'); + + $config = KTConfig::getSingleton(); + $tempDir = $config->get('urls/tmpDirectory'); + $cacheDir = $config->get('cache/cacheDirectory'); + $logDir = $config->get('urls/logDirectory'); + $docsDir = $config->get('urls/documentRoot'); + $luceneDir = $config->get('indexer/luceneDirectory'); + + $systemDir = OS_UNIX?'/tmp':'c:/windows/temp'; + + $this->folders = array( + array( + 'name'=>_kt('Smarty Cache'), + 'folder'=>$tempDir, + 'pattern'=>'^%%.*', + 'canClean'=>true + ), + array( + 'name'=>_kt('KnowledgeTree Cache'), + 'folder'=>$cacheDir, + 'pattern'=>'', + 'canClean'=>true + ), + array( + 'name'=>_kt('KnowledgeTree Logs'), + 'folder'=>$logDir, + 'pattern'=>'.+\.txt$', + 'canClean'=>true + ), + array( + 'name'=>_kt('System Temporary Folder'), + 'folder'=>$systemDir, + 'pattern'=>'(sess_.+)?(.+\.log$)?', + 'canClean'=>true + ), + array( + 'name'=>_kt('KnowledgeTree Documents'), + 'folder'=>$docsDir, + 'pattern'=>'', + 'canClean'=>false + ), + array( + 'name'=>_kt('KnowledgeTree Lucene Indexes'), + 'folder'=>$luceneDir, + 'pattern'=>'', + 'canClean'=>false + ), + ); + } + + function getDirectories() + { + return $this->folders; + } + + function getDirectory($folder) + { + foreach($this->folders as $dir) + { + if ($dir['folder'] == $folder) + { + return $dir; + } + } + return null; + } + + function setup() + { + $this->registerDashlet('DiskUsageDashlet', 'ktcore.diskusage.dashlet', 'DiskUsageDashlet.inc.php'); + $this->registerDashlet('FolderUsageDashlet', 'ktcore.folderusage.dashlet', 'FolderUsageDashlet.inc.php'); + + $oTemplating =& KTTemplating::getSingleton(); + $oTemplating->addLocation('housekeeper', '/plugins/housekeeper/templates'); + } + +} + +$oPluginRegistry =& KTPluginRegistry::getSingleton(); +$oPluginRegistry->registerPlugin('HouseKeeperPlugin', 'ktcore.housekeeper.plugin', __FILE__); + +?> \ No newline at end of file diff --git a/plugins/housekeeper/templates/DiskUsage.smarty b/plugins/housekeeper/templates/DiskUsage.smarty new file mode 100755 index 0000000..353d040 --- /dev/null +++ b/plugins/housekeeper/templates/DiskUsage.smarty @@ -0,0 +1,44 @@ + + + + + + + + + + +{assign var=orange value=0} +{assign var=red value=0} +{section name=usage loop=$usages} + +{if $usages[usage].colour == 'orange'} + {assign var=orange value=1} +{/if} +{if $usages[usage].colour == 'red'} + {assign var=red value=1} +{/if} + + + + + + + + +{/section} + +
{i18n}Disk Mount{/i18n}{i18n}Size{/i18n}{i18n}Used{/i18n}{i18n}Available{/i18n}{i18n}Usage{/i18n}

{$usages[usage].mounted}{$usages[usage].size}  {$usages[usage].used}  {$usages[usage].available}  {$usages[usage].usage}  

+ + +{if $orange==1 || $red==1} + +{/if} +{if $orange==1} + +{/if} +{if $red==1} + +{/if} + +
{i18n}Free Space{/i18n} < {$warnPercent} % < {$urgentPercent} %{i18n}refresh{/i18n}
\ No newline at end of file diff --git a/plugins/housekeeper/templates/FolderUsage.smarty b/plugins/housekeeper/templates/FolderUsage.smarty new file mode 100755 index 0000000..f948e54 --- /dev/null +++ b/plugins/housekeeper/templates/FolderUsage.smarty @@ -0,0 +1,36 @@ +{literal} + +{/literal} + + + + + + + + + +{section name=usage loop=$usages} +{if $usages[usage].folder!= ''} + + + + + + +{/if} +{/section} + +
{i18n}Description{/i18n}# {i18n}Files{/i18n}{i18n}Space Used{/i18n}{i18n}Action{/i18n}

{$usages[usage].description}
({$usages[usage].folder})
{$usages[usage].files}  {$usages[usage].filesize}  {if $usages[usage].canClean}{i18n}cleanup{/i18n}{else}{i18n}N/A{/i18n}{/if}  

+ + + +
{i18n}refresh{/i18n}