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

Commit

Permalink
Experimental feature to monitor underlying storage changes. To be tes…
Browse files Browse the repository at this point in the history
…ted.
  • Loading branch information
cdujeu committed Jan 9, 2015
1 parent 2e7aa81 commit c62e432
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
94 changes: 94 additions & 0 deletions core/src/plugins/meta.syncable/class.ChangesTracker.php
Expand Up @@ -36,6 +36,96 @@ public function init($options)
parent::init($options);
}

protected function indexIsSync(){
// Grab all folders mtime and compare them
$repoIdentifier = $this->computeIdentifier($this->accessDriver->repository);
$res = dibi::query("SELECT [node_path],[mtime] FROM [ajxp_index] WHERE [md5] = %s AND [repository_identifier] = %s", 'directory', $repoIdentifier);
$modified = array();

// REGISTER ROOT ANYWAY: WE PROBABLY CAN'T GET A "FILEMTIME" ON IT.
$mod = array(
"url" => $this->accessDriver->getResourceUrl(""),
"path" => "/",
"children" => array()
);
$children = dibi::query("SELECT [node_path],[mtime] FROM [ajxp_index] WHERE [repository_identifier] = %s AND [node_path] LIKE %s AND [node_path] NOT LIKE %s",
$repoIdentifier, "/%", "/%/%");
foreach($children as $cRow){
$mod["children"][substr($cRow->node_path, 1)] = $cRow->mtime;
}
$modified[] = $mod;

clearstatcache();
// CHECK ALL FOLDERS
foreach($res as $row){
$path = $row->node_path;
$mtime = intval($row->mtime);
$url = $this->accessDriver->getResourceUrl($path);
$currentTime = @filemtime($url);
if($currentTime === false && !file_exists($url)) {
// Deleted folder!
$this->logDebug(__FUNCTION__, "Folder deleted directly on storage: ".$url);
$node = new AJXP_Node($url);
AJXP_Controller::applyHook("node.change", array(&$node, null, false));
continue;
}
if($currentTime > $mtime){
$mod = array(
"url" => $url,
"path" => $path,
"children" => array(),
"current_time" => $currentTime
);
$children = dibi::query("SELECT [node_path],[mtime],[md5] FROM [ajxp_index] WHERE [md5] != %s AND [repository_identifier] = %s AND [node_path] LIKE %s AND [node_path] NOT LIKE %s",
'directory', $repoIdentifier, "$path/%", "$path/%/%");
foreach($children as $cRow){
$mod["children"][substr($cRow->node_path, strlen($path)+1)] = $cRow->mtime;
}
$modified[] = $mod;
}
}

// NOW COMPUTE DIFFS
foreach($modified as $mod_data){
$url = $mod_data["url"];
$current_time = $mod_data["current_time"];
$currentChildren = $mod_data["children"];
$files = scandir($url);
foreach($files as $f){
if($f[0] == ".") continue;
$nodeUrl = $url."/".$f;
$node = new AJXP_Node($nodeUrl);
// Ignore dirs modified time
// if(is_dir($nodeUrl) && $mod_data["path"] != "/") continue;
if(!isSet($currentChildren[$f])){
// New items detected
$this->logDebug(__FUNCTION__, "New item detected on storage: ".$nodeUrl);
AJXP_Controller::applyHook("node.change", array(null, &$node, false));
continue;
}else {
if(is_dir($nodeUrl)) continue; // Make sure to not trigger a recursive indexation here.
if(filemtime($nodeUrl) > $currentChildren[$f]){
// Changed!
$this->logDebug(__FUNCTION__, "Item modified directly on storage: ".$nodeUrl);
AJXP_Controller::applyHook("node.change", array(&$node, &$node, false));
}
}
}
foreach($currentChildren as $cPath => $mtime){
if(!in_array($cPath, $files)){
// Deleted
$this->logDebug(__FUNCTION__, "File deleted directly on storage: ".$url."/".$cPath);
$node = new AJXP_Node($url."/".$cPath);
AJXP_Controller::applyHook("node.change", array(&$node, null, false));
}
}
// Now "touch" parent directory
if(isSet($current_time)){
dibi::query("UPDATE [ajxp_index] SET ", array("mtime" => $current_time), " WHERE [repository_identifier] = %s AND [node_path] = %s", $repoIdentifier, $mod_data["path"]);
}
}
}

public function switchActions($actionName, $httpVars, $fileVars)
{
if($actionName != "changes" || !isSet($httpVars["seq_id"])) return false;
Expand All @@ -47,6 +137,10 @@ public function switchActions($actionName, $httpVars, $fileVars)
$recycle = $currentRepo->getOption("RECYCLE_BIN");
$recycle = (!empty($recycle)?$recycle:false);

if($this->options["OBSERVE_STORAGE_CHANGES"]){
$this->indexIsSync();
}

HTMLWriter::charsetHeader('application/json', 'UTF-8');
if(isSet($httpVars["filter"])){
$filter = AJXP_Utils::decodeSecureMagic($httpVars["filter"]);
Expand Down
1 change: 1 addition & 0 deletions core/src/plugins/meta.syncable/manifest.xml
Expand Up @@ -5,6 +5,7 @@
<server_settings>
<global_param type="button" name="INSTALL_SQL" choices="run_plugin_action:meta.syncable:installSQLTables" label="CONF_MESSAGE[SQL Tables]" description="CONF_MESSAGE[Install SQL Tables]" mandatory="false"/>
<param name="REPO_SYNCABLE" type="boolean" label="Syncable Workspace" description="Workspace is syncable" default="true" scope="repository" expose="true"/>
<param name="OBSERVE_STORAGE_CHANGES" type="boolean" label="Observe storage changes [Experimental]" description="Continuously monitor underlying storage changes. This is experimental. Can be used if the storage content is modified OUTSIDE of Pydio." default="false" scope="repository" expose="false"/>
</server_settings>
<registry_contributions>
<actions>
Expand Down

0 comments on commit c62e432

Please sign in to comment.