Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Deport directoryUsage compute inside the drivers. Currently implement…
Browse files Browse the repository at this point in the history
…ed for fs and S3. Fix #698

Ability to use a per-user bucket name in S3.
  • Loading branch information
cdujeu committed Nov 12, 2014
1 parent 59557cd commit 6708bd1
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 86 deletions.
53 changes: 53 additions & 0 deletions core/src/plugins/access.fs/class.fsAccessDriver.php
Expand Up @@ -101,6 +101,59 @@ public function getWrapperClassName()
return $this->wrapperClassName;
}

/**
* @param String $directoryPath
* @param Repository $repositoryResolvedOptions
* @return int
*/
public function directoryUsage($directoryPath, $repositoryResolvedOptions){

$dir = $repositoryResolvedOptions["PATH"].$directoryPath;
$size = -1;
if ( ( PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows") && class_exists("COM") ) {
$obj = new COM ( 'scripting.filesystemobject' );
if ( is_object ( $obj ) ) {
$ref = $obj->getfolder ( $dir );
$size = floatval($ref->size);
$obj = null;
}
} else {
if(PHP_OS == "Darwin") $option = "-sk";
else $option = "-sb";
$cmd = '/usr/bin/du '.$option.' ' . escapeshellarg($dir);
$io = popen ( $cmd , 'r' );
$size = fgets ( $io, 4096);
$size = trim(str_replace($dir, "", $size));
$size = floatval($size);
if(PHP_OS == "Darwin") $s = $s * 1024;
pclose ( $io );
}
if($size != -1){
return $size;
}else{
return $this->recursiveDirUsageByListing($directoryPath);
}

}

protected function recursiveDirUsageByListing($path){
$total_size = 0;
$files = scandir($path);

foreach ($files as $t) {
if (is_dir(rtrim($path, '/') . '/' . $t)) {
if ($t <> "." && $t <> "..") {
$size = $this->recursiveDirUsageByListing(rtrim($path, '/') . '/' . $t);
$total_size += $size;
}
} else {
$size = sprintf("%u", filesize(rtrim($path, '/') . '/' . $t));
$total_size += $size;
}
}
return $total_size;
}

public function redirectActionsToMethod(&$contribNode, $arrayActions, $targetMethod)
{
$actionXpath=new DOMXPath($contribNode->ownerDocument);
Expand Down
34 changes: 32 additions & 2 deletions core/src/plugins/access.s3/class.s3AccessDriver.php
Expand Up @@ -68,9 +68,7 @@ public function detectStreamWrapper($register = false){
}
$this->s3Client = S3Client::factory($options);
$this->s3Client->registerStreamWrapper();
//$this->s3Client->addSubscriber(LogPlugin::getDebugPlugin());
}

return parent::detectStreamWrapper($register);
}

Expand All @@ -93,11 +91,36 @@ public function initRepository()
}
}

/**
* @return Aws\Common\Client\AbstractClient
*/
public function getS3Service(){
return $this->s3Client;
}

/**
* @param String $directoryPath
* @param Repository $repositoryResolvedOptions
* @return int
*/
public function directoryUsage($directoryPath, $repositoryResolvedOptions){
$client = $this->getS3Service();
$bucket = (isSet($repositoryResolvedOptions["CONTAINER"])?$repositoryResolvedOptions["CONTAINER"]:$this->repository->getOption("CONTAINER"));
$path = (isSet($repositoryResolvedOptions["PATH"])?$repositoryResolvedOptions["PATH"]:"");
$objects = $client->getIterator('ListObjects', array(
'Bucket' => $bucket,
'Prefix' => $path
));

$usage = 0;
foreach ($objects as $object) {
$usage += (double)$object['Size'];
}
return $usage;

}

/**
* Parse
* @param DOMNode $contribNode
*/
Expand Down Expand Up @@ -132,4 +155,11 @@ public function filesystemFileSize($filePath)
return $bytesize;
}

public function makeSharedRepositoryOptions($httpVars, $repository)
{
$newOptions = parent::makeSharedRepositoryOptions($httpVars, $repository);
$newOptions["CONTAINER"] = $this->repository->getOption("CONTAINER");
return $newOptions;
}

}
7 changes: 7 additions & 0 deletions core/src/plugins/access.swift/class.swiftAccessDriver.php
Expand Up @@ -118,4 +118,11 @@ public function isRemote()
return true;
}

public function makeSharedRepositoryOptions($httpVars, $repository)
{
$newOptions = parent::makeSharedRepositoryOptions($httpVars, $repository);
$newOptions["CONTAINER"] = $this->repository->getOption("CONTAINER");
return $newOptions;
}

}
2 changes: 1 addition & 1 deletion core/src/plugins/access.swift/manifest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ajxpdriver name="swift" enabled="false" label="CONF_MESSAGE[HPCloud (HPCloud Driver)]" description="CONF_MESSAGE[Access HPCloud (Open Stack) Object Storage]" mixins="filesystem_commons,slug_provider,template_provider" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:../core.ajaxplorer/ajxp_registry.xsd">
<ajxpdriver name="swift" enabled="false" label="CONF_MESSAGE[Open Stack (Swift)]" description="CONF_MESSAGE[Access Open Stack Object Storage via Swift API]" mixins="filesystem_commons,slug_provider,template_provider" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:../core.ajaxplorer/ajxp_registry.xsd">
<class_definition filename="plugins/access.swift/class.swiftAccessDriver.php" classname="swiftAccessDriver"/>
<client_settings icon="plugins/access.fs/icon.png">
<resources>
Expand Down
9 changes: 9 additions & 0 deletions core/src/plugins/core.access/class.AbstractAccessDriver.php
Expand Up @@ -105,6 +105,15 @@ public function makePublicletOptions($filePath, $password, $expires, $downloadli
*/
public function makeSharedRepositoryOptions($httpVars, $repository){}

/**
* @param $directoryPath string
* @param $repositoryResolvedOptions array
* @return integer
* @throw Exception
*/
public function directoryUsage($directoryPath, $repositoryResolvedOptions){
throw new Exception("Current driver does not support recursive directory usage!");
}

public function crossRepositoryCopy($httpVars)
{
Expand Down
126 changes: 43 additions & 83 deletions core/src/plugins/meta.quota/class.QuotaComputer.php
Expand Up @@ -63,7 +63,7 @@ protected function getWorkingPath()
}
}
$path = $repo->getOption("PATH");
if (iSset($originalUser)) {
if ( isSet($originalUser) ) {
$originalUser->setParent($clearParent);
$originalUser->setResolveAsParent(false);
AuthService::updateUser($originalUser);
Expand All @@ -72,6 +72,42 @@ protected function getWorkingPath()
return $path;
}

/**
* @return array
*/
protected function getWorkingRepositoryOptions()
{
$p = array();
$repo = $this->accessDriver->repository;
$clearParent = null;
// SPECIAL : QUOTA MUST BE COMPUTED ON PARENT REPOSITORY FOLDER
if ($repo->hasParent()) {
$parentOwner = $repo->getOwner();
if ($parentOwner !== null) {
$repo = ConfService::getRepositoryById($repo->getParentId());
$originalUser = AuthService::getLoggedUser();
$loggedUser = AuthService::getLoggedUser();
if (!$loggedUser->hasParent()) {
$loggedUser->setParent($parentOwner);
$clearParent = null;
} else {
$clearParent = $loggedUser->getParent();
}
$loggedUser->setResolveAsParent(true);
AuthService::updateUser($loggedUser);
}
}
$path = $repo->getOption("PATH");
$p["PATH"] = $path;
if ( isSet($originalUser) ) {
$originalUser->setParent($clearParent);
$originalUser->setResolveAsParent(false);
AuthService::updateUser($originalUser);
}
return $p;
}


/**
* @param AJXP_Node $node
* @param int $newSize
Expand All @@ -85,14 +121,10 @@ public function precheckQuotaUsage($node, $newSize = 0)
return null;
}
$delta = $newSize;
$path = $this->getWorkingPath();
$quota = $this->getAuthorized();
$soft = $this->getSoftLimit();
$q = $this->getUsage($path);
$q = $this->getUsage();
$this->logDebug("QUOTA : Previous usage was $q");
if ($q === false) {
$q = $this->computeDirSpace($path);
}
if ($q + $delta >= $quota) {
$mess = ConfService::getMessages();
throw new Exception($mess["meta.quota.3"]." (".AJXP_Utils::roundSize($quota) .")!");
Expand All @@ -117,15 +149,15 @@ protected function sendSoftLimitAlert()

public function getCurrentQuota($action, $httpVars, $fileVars)
{
$u = $this->getUsage($this->getWorkingPath());
$u = $this->getUsage();
HTMLWriter::charsetHeader("application/json");
print json_encode(array('USAGE' => $u, 'TOTAL' => $this->getAuthorized()));
return;
}

public function loadRepositoryInfo(&$data){
$data['meta.quota'] = array(
'usage' => $u = $this->getUsage($this->getWorkingPath()),
'usage' => $u = $this->getUsage(),
'total' => $this->getAuthorized()
);
}
Expand Down Expand Up @@ -172,12 +204,13 @@ protected function getSoftLimit()
* @param String $dir
* @return bool|int
*/
private function getUsage($dir)
private function getUsage()
{
$data = $this->getUserData();
$repo = $this->accessDriver->repository->getId();
$repoOptions = $this->getWorkingRepositoryOptions();
if (!isSet($data["REPO_USAGES"][$repo]) || $this->options["CACHE_QUOTA"] === false) {
$quota = $this->computeDirSpace($dir);
$quota = $this->accessDriver->directoryUsage("", $repoOptions);
if(!isset($data["REPO_USAGES"])) $data["REPO_USAGES"] = array();
$data["REPO_USAGES"][$repo] = $quota;
$this->saveUserData($data);
Expand Down Expand Up @@ -207,77 +240,4 @@ private function saveUserData($data)
AuthService::updateUser($logged);
}

private function computeDirSpace($dir)
{
$this->logDebug("Computing dir space for : ".$dir);
$s = -1;
if (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows") {

$obj = new COM ( 'scripting.filesystemobject' );
if ( is_object ( $obj ) ) {
$ref = $obj->getfolder ( $dir );
$s = floatval($ref->size);
$obj = null;
} else {
echo 'can not create object';
}
} else {
// Try to get quota via smbclient if accessDriver is smb.
if ($this->accessDriver->id == 'access.smb') {
$credential = AJXP_Safe::tryLoadingCredentialsFromSources("",$this->accessDriver->repository);
$strcmd = 'smbclient //'. $this->accessDriver->repository->options['HOST'] .'/' . $credential['user'] . ' -U ' . $credential['user'] . '%' . $credential['password'] . ' -c du';
$io = popen($strcmd, 'r');
$size = fgets($io, 4096);
$size = fgets($io, 4096);
$size = fgets($io, 4096);
$size = trim($size);

$num = explode(' ', $size);
if (!empty($num)) {
pclose($io);
$s = floatval(array_pop($num));
return $s;
}
else{
return 0;
}
}

if(PHP_OS == "Darwin") $option = "-sk";
else $option = "-sb";
$io = popen ( '/usr/bin/du '.$option.' ' . escapeshellarg($dir), 'r' );
$size = fgets ( $io, 4096);
$size = trim(str_replace($dir, "", $size));
$s = floatval($size);
if(PHP_OS == "Darwin") $s = $s * 1024;
//$s = intval(substr ( $size, 0, strpos ( $size, ' ' ) ));
pclose ( $io );
}
if ($s == -1) {
$s = $this->foldersize($dir);
}

return $s;
}

private function foldersize($path)
{
$total_size = 0;
$files = scandir($path);

foreach ($files as $t) {
if (is_dir(rtrim($path, '/') . '/' . $t)) {
if ($t<>"." && $t<>"..") {
$size = foldersize(rtrim($path, '/') . '/' . $t);
$total_size += $size;
}
} else {
$size = sprintf("%u", filesize(rtrim($path, '/') . '/' . $t));
$total_size += $size;
}
}
return $total_size;
}


}

0 comments on commit 6708bd1

Please sign in to comment.