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 @@
+
+
+class HouseKeeperPlugin extends KTPlugin
+ {
+ var $autoRegister = true;
+ var $sNamespace = 'ktcore.housekeeper.plugin';
+
+ var $folders = array();
+
+ function HouseKeeperPlugin($sFilename = null)
+ {
+ parent::KTPlugin($sFilename);
+
+ $this->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 @@
+
+
+ | {i18n}Disk Mount{/i18n} |
+ {i18n}Size{/i18n} |
+ {i18n}Used{/i18n} |
+ {i18n}Available{/i18n} |
+ {i18n}Usage{/i18n} |
+
+
+
|
+{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}
+
+ | {$usages[usage].mounted} |
+ {$usages[usage].size} |
+ {$usages[usage].used} |
+ {$usages[usage].available} |
+ {$usages[usage].usage} |
+
+
+{/section}
+
|
+
+
+
+{if $orange==1 || $red==1}
+| {i18n}Free Space{/i18n} |
+{/if}
+{if $orange==1}
+ < {$warnPercent} % |
+{/if}
+{if $red==1}
+ < {$urgentPercent} % |
+{/if}
+{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}
+
+
+
+ | {i18n}Description{/i18n} |
+ # {i18n}Files{/i18n} |
+ {i18n}Space Used{/i18n} |
+ {i18n}Action{/i18n} |
+
+
|
+{section name=usage loop=$usages}
+{if $usages[usage].folder!= ''}
+
+ {$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} |
+
+{/if}
+{/section}
+
|
+
+