]> source.dussan.org Git - nextcloud-server.git/commitdiff
Initial version of remote ownCloud access through filesystem abstraction
authorRobin Appelman <icewind1991@gmail.com>
Wed, 7 Jul 2010 10:30:30 +0000 (12:30 +0200)
committerRobin Appelman <icewind1991@gmail.com>
Wed, 7 Jul 2010 10:30:30 +0000 (12:30 +0200)
files/api.php
inc/HTTP/WebDAV/Server/Filesystem.php
inc/lib_base.php
inc/lib_connect.php
inc/lib_files.php
inc/lib_filestorage.php
inc/lib_filesystem.php
inc/lib_remotestorage.php [new file with mode: 0644]

index fa94a512547ed7d879511b56accea484f7effc3a..d6e04d4550faff23bd40f7929a19aa43c7689c35 100755 (executable)
@@ -55,6 +55,9 @@ if($arguments['action']){
                case 'getfiles':
                        echo json_encode(OC_FILES::getdirectorycontent($arguments['dir']));
                        break;
+               case 'gettree':
+                       echo json_encode(OC_FILES::getTree($arguments['dir']));
+                       break;
                case 'find':
                        echo json_encode(OC_FILESYSTEM::find($arguments['path']));
                        break;
index a41d36873036ad1ca7762827cc7e6d52191b40e5..ea0625a5a1e9aadf0ec8c6ba3526f1dad5bed675 100755 (executable)
      */
     function PUT(&$options) 
     {
-               error_log("put $fspath");
         $fspath = $options["path"];
         $dir = dirname($fspath);
         if (!OC_FILESYSTEM::file_exists($dir) || !OC_FILESYSTEM::is_dir($dir)) {
index 5c9906d361d8fb7962271123f6b55414d54eea5f..a806d3e5bda64be7153befd6310b2b82cb0ccf8b 100755 (executable)
@@ -82,6 +82,7 @@ oc_require_once('lib_ocs.php');
 @oc_require_once('MDB2.php');
 @oc_require_once('MDB2/Schema.php');
 oc_require_once('lib_connect.php');
+oc_require_once('lib_remotestorage.php');
 
 
 if(!is_dir($CONFIG_DATADIRECTORY_ROOT)){
index 0c56d1a01d5e2e1ccd58874cdac050f93bef4ed5..9db867715e42e76d884ad66a3d5f7045a3c3fbb6 100644 (file)
@@ -75,7 +75,8 @@ class OC_REMOTE_CLOUD{
                curl_setopt($ch, CURLOPT_COOKIEFILE,$this->cookiefile); 
                curl_setopt($ch, CURLOPT_COOKIEJAR,$this->cookiefile); 
                curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
-               $result=trim(curl_exec($ch));
+               $result=curl_exec($ch);
+               $result=trim($result);
                $info=curl_getinfo($ch);
                $httpCode=$info['http_code'];
                curl_close($ch);
@@ -121,6 +122,70 @@ class OC_REMOTE_CLOUD{
                $this->cookiefile=false;
        }
        
+       /**
+       * create a new file or directory
+       * @param string $dir
+       * @param string $name
+       * @param string $type
+       */
+       public function newFile($dir,$name,$type){
+               if(!$this->connected){
+                       return false;
+               }
+               return $this->apiCall('new',array('dir'=>$dir,'name'=>$name,'type'=>$type),true);
+       }
+       
+       /**
+       * deletes a file or directory
+       * @param string $dir
+       * @param string $file
+       */
+       public function delete($dir,$name){
+               if(!$this->connected){
+                       return false;
+               }
+               return $this->apiCall('delete',array('dir'=>$dir,'file'=>$name),true);
+       }
+       
+       /**
+       * moves a file or directory
+       * @param string $sorceDir
+       * @param string $sorceFile
+       * @param string $targetDir
+       * @param string $targetFile
+       */
+       public function move($sourceDir,$sourceFile,$targetDir,$targetFile){
+               if(!$this->connected){
+                       return false;
+               }
+               return $this->apiCall('move',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true);
+       }
+       
+       /**
+       * copies a file or directory
+       * @param string $sorceDir
+       * @param string $sorceFile
+       * @param string $targetDir
+       * @param string $targetFile
+       */
+       public function copy($sourceDir,$sourceFile,$targetDir,$targetFile){
+               if(!$this->connected){
+                       return false;
+               }
+               return $this->apiCall('copy',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true);
+       }
+       
+       /**
+       * get a file tree
+       * @param string $dir
+       */
+       public function getTree($dir){
+               if(!$this->connected){
+                       return false;
+               }
+               return $this->apiCall('gettree',array('dir'=>$dir),true);
+       }
+       
        /**
        * get the files inside a directory of the remote cloud
        * @param string $dir
@@ -163,7 +228,12 @@ class OC_REMOTE_CLOUD{
                global $WEBROOT;
                $source=$sourceDir.'/'.$sourceFile;
                $tmp=OC_FILESYSTEM::toTmpFile($source);
-               $token=sha1(uniqid().$source);
+               return $this->sendTmpFile($tmp,$targetDir,$targetFile);
+       }
+       
+       public function sendTmpFile($tmp,$targetDir,$targetFile){
+               $token=sha1(uniqid().$tmp);
+               global $WEBROOT;
                $file=sys_get_temp_dir().'/'.'remoteCloudFile'.$token;
                rename($tmp,$file);
                if((isset($CONFIG_HTTPFORCESSL) and $CONFIG_HTTPFORCESSL) or isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') { 
index 20d40669d7752709bea2aea7e29ad6b13b50d5fd..8f694536f7ab96075c7acdf861fbfb74b24a8791 100755 (executable)
@@ -54,7 +54,7 @@ class OC_FILES {
                $dirs=array();
                $file=array();
                $files=array();
-               if (OC_FILESYSTEM::is_dir($directory)) {
+               if(OC_FILESYSTEM::is_dir($directory)) {
                        if ($dh = OC_FILESYSTEM::opendir($directory)) {
                        while (($filename = readdir($dh)) !== false) {
                                if($filename<>'.' and $filename<>'..' and substr($filename,0,1)!='.'){
@@ -136,7 +136,11 @@ class OC_FILES {
                        header('Expires: 0');
                        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
                        header('Pragma: public');
-                       header('Content-Length: ' . filesize($filename));
+                       if($zip){
+                               header('Content-Length: ' . filesize($filename));
+                       }else{
+                               header('Content-Length: ' . OC_FILESYSTEM::filesize($filename));
+                       }
                }elseif($zip or !OC_FILESYSTEM::file_exists($filename)){
                        header("HTTP/1.0 404 Not Found");
                        die('404 Not Found');
@@ -243,6 +247,16 @@ class OC_FILES {
                return OC_FILESYSTEM::getMimeType($path);
        }
        
+       /**
+       * get a file tree
+       *
+       * @param  string  path
+       * @return array
+       */
+       static function getTree($path){
+               return OC_FILESYSTEM::getTree($path);
+       }
+       
        /**
        * pull a file from a remote server
        * @param  string  source
@@ -257,8 +271,6 @@ class OC_FILES {
                $url=$source.="/files/pull.php?token=$token";
                $ch=curl_init();
                curl_setopt($ch,CURLOPT_URL,$url);
-               curl_setopt($ch,CURLOPT_POST,count($parameters));
-               curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
                curl_setopt($ch, CURLOPT_FILE, $fp);
                curl_exec($ch);
                fclose($fp);
@@ -306,4 +318,46 @@ if(!function_exists('sys_get_temp_dir')) {
     }
 }
 
+global $FAKEDIRS;
+$FAKEDIRS=array();
+
+class fakeDirStream{
+       private $name;
+       private $data;
+       private $index;
+       
+       public function dir_opendir($path,$options){
+               global $FAKEDIRS;
+               $url=parse_url($path);
+               $this->name=substr($path,strlen('fakedir://'));
+               $this->index=0;
+               if(isset($FAKEDIRS[$this->name])){
+                       $this->data=$FAKEDIRS[$this->name];
+               }else{
+                       $this->data=array();
+               }
+               return true;
+       }
+       
+       public function dir_readdir(){
+               if($this->index>=count($this->data)){
+                       return false;
+               }
+               $filename=$this->data[$this->index];
+               $this->index++;
+               return $filename;
+       }
+       
+       public function dir_closedir() {
+               $this->data=false;
+               $this->name='';
+               return true;
+       }
+
+       public function dir_rewinddir() {
+               $this->index=0;
+               return true;
+       }
+}
+stream_wrapper_register("fakedir", "fakeDirStream");
 ?>
\ No newline at end of file
index 85382a444471425a2aa0218169cd136ec4499196..10266d4eaf6d978a49e8e6ffb2c49ac302ed6878 100755 (executable)
@@ -62,7 +62,7 @@ class OC_FILESTORAGE{
        public function filemtime($path){}
        public function fileatime($path){}
        public function file_get_contents($path){}
-       public function file_put_contents($path){}
+       public function file_put_contents($path,$data){}
        public function unlink($path){}
        public function rename($path1,$path2){}
        public function copy($path1,$path2){}
@@ -149,8 +149,8 @@ class OC_FILESTORAGE_LOCAL extends OC_FILESTORAGE{
                }
                return $return;
        }
-       public function file_put_contents($path){
-               if($return=file_put_contents($this->datadir.$path)){
+       public function file_put_contents($path,$data){
+               if($return=file_put_contents($this->datadir.$path,$data)){
                        $this->notifyObservers($path,OC_FILEACTION_WRITE);
                }
        }
index 6eb317f442e223a3979148e696e041b6147d66e4..492e0c5d3825c9ee1f647edb9cc38eaad8c93883 100755 (executable)
@@ -199,7 +199,7 @@ class OC_FILESYSTEM{
                        return $storage->file_get_contents(substr($path,strlen(self::getMountPoint($path))));
                }
        }
-       static public function file_put_contents($path){
+       static public function file_put_contents($path,$data){
                if(self::canWrite($path) and $storage=self::getStorage($path)){
                        $this->notifyObservers($path,OC_FILEACTION_WRITE | OC_FILEACTION_CREATE);
                        return $storage->file_put_contents(substr($path,strlen(self::getMountPoint($path))));
diff --git a/inc/lib_remotestorage.php b/inc/lib_remotestorage.php
new file mode 100644 (file)
index 0000000..882f281
--- /dev/null
@@ -0,0 +1,323 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek 
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org 
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either 
+* version 3 of the License, or any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*  
+* You should have received a copy of the GNU Lesser General Public 
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+* 
+*/
+
+
+class OC_FILESTORAGE_REMOTE extends OC_FILESTORAGE{
+       private $url;
+       private $username;
+       private $password;
+       private $remote;
+       private $statCache;
+       private $statCacheDir=false;
+       private $changed=array();
+       
+       private function cacheDir($dir){
+               if($this->statCacheDir!=$dir or $this->statCacheDir===false){
+                       $this->statCache=$this->remote->getFiles($dir);
+                       $keys=array_keys($this->statCache);
+                       $this->statCacheDir=$dir;
+               }
+       }
+       
+       public function __construct($arguments){
+               $this->url=$arguments['url'];
+               $this->username=$arguments['username'];
+               $this->password=$arguments['password'];
+               $this->remote=OC_CONNECT::connect($this->url,$this->username,$this->password);
+       }
+       public function mkdir($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $return=$this->remote->newFile($parent,$name,'dir');
+               if($return){
+                       $this->notifyObservers($path,OC_FILEACTION_CREATE);
+               }
+               return $return;
+       }
+       public function rmdir($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $return=$this->remote->delete($parent,$name);
+               if($return){
+                       $this->notifyObservers($path,OC_FILEACTION_DELETE);
+               }
+               return $return;
+       }
+       public function opendir($path){
+               $this->cacheDir($path);
+               $dirs=array_keys($this->statCache);
+               $id=uniqid();
+               global $FAKEDIRS;
+               $FAKEDIRS[$id]=$dirs;
+               if($return=opendir("fakedir://$id")){
+                       $this->notifyObservers($path,OC_FILEACTION_READ);
+               }
+               return $return;
+       }
+       public function is_dir($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($path);
+               if($path=='' or $path=='/'){
+                       return true;
+               }
+               if(!isset($this->statCache[$name])){
+                       return false;
+               }
+               return ($this->statCache[$name]['type'=='dir']);
+       }
+       public function is_file($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return false;
+               }
+               return ($this->statCache[$name]['type'!='dir']);
+       }
+       public function stat($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return $false;
+               }
+               return $this->statCache[$name];
+       }
+       public function filetype($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return false;
+               }
+               return $this->statCache[$name]['type'];
+       }
+       public function filesize($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return $false;
+               }
+               return $this->statCache[$name]['size'];
+       }
+       public function is_readable($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return false;
+               }
+               return $this->statCache[$name]['readable'];
+       }
+       public function is_writeable($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return false;
+               }
+               return $this->statCache[$name]['writeable'];
+       }
+       public function file_exists($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               return isset($this->statCache[$name]);
+       }
+       public function readfile($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $file=$this->remote->getFile($parent,$name);
+               readfile($file);
+               unlink($file);
+       }
+       public function filectime($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return false;
+               }
+               return $this->statCache[$name]['ctime'];
+       }
+       public function filemtime($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return false;
+               }
+               return $this->statCache[$name]['mtime'];
+       }
+       public function fileatime($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return false;
+               }
+               return $this->statCache[$name]['atime'];
+       }
+       public function file_get_contents($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $file=$this->remote->getFile($parent,$name);
+               file_get_contents($file);
+               unlink($file);
+       }
+       public function file_put_contents($path,$data){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $file=$this->remote->getFile($parent,$name);
+               $file=tempnam(sys_get_temp_dir(),'oc_');
+               file_put_contents($file,$data);
+               if($return=$this->remote->sendTmpFile($file,$parent,$name)){
+                       $this->notifyObservers($path,OC_FILEACTION_WRITE);
+               }
+       }
+       public function unlink($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               if($return=$this->remote->delete($paren,$name)){
+                       $this->notifyObservers($path,OC_FILEACTION_DELETE);
+               }
+               return $return;
+       }
+       public function rename($path1,$path2){
+               $parent1=dirname($path1);
+               $name1=substr($path1,strlen($parent1)+1);
+               $parent2=dirname($path2);
+               $name2=substr($path2,strlen($parent2)+1);
+               if($return=$this->remote->move($parent1,$name1,$parent2,$name2)){
+                       $this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME);
+               }
+               return $return;
+       }
+       public function copy($path1,$path2){
+               $parent1=dirname($path1);
+               $name1=substr($path1,strlen($parent1)+1);
+               $parent2=dirname($path2);
+               $name2=substr($path2,strlen($parent2)+1);
+               if($return=$this->copy->rename($parent1,$name1,$parent2,$name2)){
+                       $this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME);
+               }
+               return $return;
+       }
+       public function fopen($path,$mode){
+               $changed=false;
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               $file=$this->remote->getFile($parent,$name);
+               if($return=fopen($file,$mode)){
+                       switch($mode){
+                               case 'r':
+                                       $this->notifyObservers($path,OC_FILEACTION_READ);
+                                       break;
+                               case 'r+':
+                               case 'w+':
+                               case 'x+':
+                               case 'a+':
+                                       $this->notifyObservers($path,OC_FILEACTION_READ | OC_FILEACTION_WRITE);
+                                       $this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file);
+                                       break;
+                               case 'w':
+                               case 'x':
+                               case 'a':
+                                       $this->notifyObservers($path,OC_FILEACTION_WRITE);
+                                       $this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file);
+                                       break;
+                       }
+               }
+               return $return;
+       }
+       
+       public function getMimeType($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               if(substr($name,0,1)=='/'){
+                       $name=substr($name,1);
+               }
+               $this->cacheDir($parent);
+               if(!isset($this->statCache[$name])){
+                       return false;
+               }
+               return $this->statCache[$name]['mime'];
+       }
+       
+       public function toTmpFile($path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               if(substr($name,0,1)=='/'){
+                       $name=substr($name,1);
+               }
+               $filename=$this->remote->getFile($parent,$name);
+               if($filename){
+                       $this->notifyObservers($path,OC_FILEACTION_READ);
+                       return $filename;
+               }else{
+                       return false;
+               }
+       }
+       
+       public function fromTmpFile($tmpFile,$path){
+               $parent=dirname($path);
+               $name=substr($path,strlen($parent)+1);
+               if($this->remote->sendTmpFile($tmpFile,$parent,$name)){
+                       $this->notifyObservers($path,OC_FILEACTION_CREATE);
+                       return true;
+               }else{
+                       return false;
+               }
+       }
+       
+       public function delTree($dir) {
+               $parent=dirname($dir);
+               $name=substr($dir,strlen($parent)+1);
+               $return=$this->remote->delete($parent,$name);
+               if($return=rmdir($dir)){
+                       $this->notifyObservers($dir,OC_FILEACTION_DELETE);
+               }
+               return $return;
+       }
+       
+       public function find($path){
+               return $this->getTree($path);
+       }
+       
+       public function getTree($dir) {
+               if($return=$this->remote->getTree($dir)){
+                       $this->notifyObservers($dir,OC_FILEACTION_READ);
+               }
+               return $return;
+       }
+       
+       public function __destruct(){
+               foreach($this->changed as $changed){
+                       $this->remote->sendTmpFile($changed['tmp'],$changed['dir'],$changed['file']);
+               }
+       }
+}
+
+?>