]> source.dussan.org Git - nextcloud-server.git/commitdiff
renaming remote storage support to External storage support to clear up naming conflict
authorJan-Christoph Borchardt <jan@unhosted.org>
Fri, 30 Mar 2012 16:10:16 +0000 (18:10 +0200)
committerJan-Christoph Borchardt <jan@unhosted.org>
Fri, 30 Mar 2012 16:18:37 +0000 (18:18 +0200)
18 files changed:
apps/files_external/appinfo/app.php [new file with mode: 0644]
apps/files_external/appinfo/info.xml [new file with mode: 0644]
apps/files_external/lib/ftp.php [new file with mode: 0644]
apps/files_external/lib/google.php [new file with mode: 0644]
apps/files_external/lib/webdav.php [new file with mode: 0644]
apps/files_external/tests/config.php [new file with mode: 0644]
apps/files_external/tests/ftp.php [new file with mode: 0644]
apps/files_external/tests/google.php [new file with mode: 0644]
apps/files_external/tests/webdav.php [new file with mode: 0644]
apps/files_remote/appinfo/app.php [deleted file]
apps/files_remote/appinfo/info.xml [deleted file]
apps/files_remote/lib/ftp.php [deleted file]
apps/files_remote/lib/google.php [deleted file]
apps/files_remote/lib/webdav.php [deleted file]
apps/files_remote/tests/config.php [deleted file]
apps/files_remote/tests/ftp.php [deleted file]
apps/files_remote/tests/google.php [deleted file]
apps/files_remote/tests/webdav.php [deleted file]

diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php
new file mode 100644 (file)
index 0000000..95770b4
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_external/lib/ftp.php';
+OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_external/lib/webdav.php';
+OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php';
diff --git a/apps/files_external/appinfo/info.xml b/apps/files_external/appinfo/info.xml
new file mode 100644 (file)
index 0000000..fb58297
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<info>
+       <id>files_external</id>
+       <name>External storage support</name>
+       <description>Mount external storage sources</description>
+       <version>0.1</version>
+       <licence>AGPL</licence>
+       <author>Robin Appelman</author>
+       <require>3</require>
+       <types>
+               <filesystem/>
+       </types>
+</info>
diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php
new file mode 100644 (file)
index 0000000..802446b
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class OC_FileStorage_FTP extends OC_Filestorage_Common{
+       private $password;
+       private $user;
+       private $host;
+       private $secure;
+       private $root;
+
+       private static $tempFiles=array();
+       
+       public function __construct($params){
+               $this->host=$params['host'];
+               $this->user=$params['user'];
+               $this->password=$params['password'];
+               $this->secure=isset($params['secure'])?(bool)$params['secure']:false;
+               $this->root=isset($params['root'])?$params['root']:'/';
+               if(substr($this->root,0,1)!='/'){
+                       $this->root='/'.$this->root;
+               }
+               
+               //create the root folder if necesary
+               mkdir($this->constructUrl(''));
+       }
+
+       /**
+        * construct the ftp url
+        * @param string path
+        * @return string
+        */
+       public function constructUrl($path){
+               $url='ftp';
+               if($this->secure){
+                       $url.='s';
+               }
+               $url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path;
+               return $url;
+       }
+
+       public function mkdir($path){
+               return mkdir($this->constructUrl($path));
+       }
+
+       public function rmdir($path){
+               if($this->file_exists($path)){
+                       $succes=rmdir($this->constructUrl($path));
+                       clearstatcache();
+                       return $succes;
+               }else{
+                       return false;
+               }
+       }
+
+       public function opendir($path){
+               return opendir($this->constructUrl($path));
+       }
+
+       public function filetype($path){
+               return filetype($this->constructUrl($path));
+       }
+
+       public function is_readable($path){
+               return true;//not properly supported
+       }
+
+       public function is_writable($path){
+               return true;//not properly supported
+       }
+
+       public function file_exists($path){
+               return file_exists($this->constructUrl($path));
+       }
+
+       public function unlink($path){
+               $succes=unlink($this->constructUrl($path));
+               clearstatcache();
+               return $succes;
+       }
+
+       public function fopen($path,$mode){
+               switch($mode){
+                       case 'r':
+                       case 'rb':
+                       case 'w':
+                       case 'wb':
+                       case 'a':
+                       case 'ab':
+                               //these are supported by the wrapper
+                               $context = stream_context_create(array('ftp' => array('overwrite' => true)));
+                               return fopen($this->constructUrl($path),$mode,false,$context);
+                       case 'r+':
+                       case 'w+':
+                       case 'wb+':
+                       case 'a+':
+                       case 'x':
+                       case 'x+':
+                       case 'c':
+                       case 'c+':
+                               //emulate these
+                               if(strrpos($path,'.')!==false){
+                                       $ext=substr($path,strrpos($path,'.'));
+                               }else{
+                                       $ext='';
+                               }
+                               $tmpFile=OC_Helper::tmpFile($ext);
+                               OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
+                               if($this->file_exists($path)){
+                                       $this->getFile($path,$tmpFile);
+                               }
+                               self::$tempFiles[$tmpFile]=$path;
+                               return fopen('close://'.$tmpFile,$mode);
+               }
+       }
+
+       public function writeBack($tmpFile){
+               if(isset(self::$tempFiles[$tmpFile])){
+                       $this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]);
+                       unlink($tmpFile);
+               }
+       }
+
+       public function free_space($path){
+               return 0;
+       }
+
+       public function touch($path,$mtime=null){
+               if(is_null($mtime)){
+                       $fh=$this->fopen($path,'a');
+                       fwrite($fh,'');
+                       fclose($fh);
+               }else{
+                       return false;//not supported
+               }
+       }
+
+       public function getFile($path,$target){
+               return copy($this->constructUrl($path),$target);
+       }
+
+       public function uploadFile($path,$target){
+               return copy($path,$this->constructUrl($target));
+       }
+
+       public function rename($path1,$path2){
+               return rename($this->constructUrl($path1),$this->constructUrl($path2));
+       }
+
+       public function stat($path){
+               return stat($this->constructUrl($path));
+       }
+}
diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php
new file mode 100644 (file)
index 0000000..0d6db19
--- /dev/null
@@ -0,0 +1,409 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Michael Gapczynski
+* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
+*
+* 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 Affero General Public
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+require_once 'common.inc.php';
+
+class OC_Filestorage_Google extends OC_Filestorage_Common {
+
+       private $consumer;
+       private $oauth_token;
+       private $sig_method;
+       private $entries;
+
+       public function __construct($arguments) {
+               $consumer_key = isset($arguments['consumer_key']) ? $arguments['consumer_key'] : 'anonymous';
+               $consumer_secret = isset($arguments['consumer_secret']) ? $arguments['consumer_secret'] : 'anonymous';
+               $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
+               $this->oauth_token = new OAuthToken($arguments['token'], $arguments['token_secret']);
+               $this->sig_method = new OAuthSignatureMethod_HMAC_SHA1();
+               $this->entries = array();
+       }
+
+       private function sendRequest($feedUri, $http_method, $isDownload = false, $postData = null) {
+               $feedUri = trim($feedUri);
+               // create an associative array from each key/value url query param pair.
+               $params = array();
+               $pieces = explode('?', $feedUri);
+               if (isset($pieces[1])) {
+                       $params = explode_assoc('=', '&', $pieces[1]);
+               }
+               // urlencode each url parameter key/value pair
+               $tempStr = $pieces[0];
+               foreach ($params as $key => $value) {
+                       $tempStr .= '&' . urlencode($key) . '=' . urlencode($value);
+               }
+               $feedUri = preg_replace('/&/', '?', $tempStr, 1);
+               $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $http_method, $feedUri, $params);
+               $request->sign_request($this->sig_method, $this->consumer, $this->oauth_token);
+               $auth_header = $request->to_header();
+               $headers = array($auth_header, 'Content-Type: application/atom+xml', 'GData-Version: 3.0');
+               $curl = curl_init($feedUri);
+               curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+               curl_setopt($curl, CURLOPT_FAILONERROR, false);
+               curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+               switch ($http_method) {
+                       case 'GET':
+                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+                               break;
+                       case 'POST':
+                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+                               curl_setopt($curl, CURLOPT_POST, 1);
+                               curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
+                               break;
+                       case 'PUT':
+                               $headers[] = 'If-Match: *';
+                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+                               curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
+                               curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
+                               break;
+                       case 'DELETE':
+                               $headers[] = 'If-Match: *';
+                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+                               curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
+                               break;
+                       default:
+                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+               }
+               if ($isDownload) {
+                       $tmpFile = OC_Helper::tmpFile();
+                       $fp = fopen($tmpFile, 'w');
+                       curl_setopt($curl, CURLOPT_FILE, $fp);
+                       curl_exec($curl);
+                       curl_close($curl);
+                       return $tmpFile;
+               }
+               $result = curl_exec($curl);
+               curl_close($curl);
+               $dom = new DOMDocument();
+               $dom->loadXML($result);
+               return $dom;
+       }
+
+       private function getResource($path) {
+               $file = basename($path);
+               if (array_key_exists($file, $this->entries)) {
+                       return $this->entries[$file];
+               } else {
+                       // Strip the file extension; file could be a native Google Docs resource
+                       if ($pos = strpos($file, '.')) {
+                               $title = substr($file, 0, $pos);
+                               $dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$title, 'GET');
+                               // Check if request was successful and entry exists
+                               if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) {
+                                       $this->entries[$file] = $entry;
+                                       return $entry;
+                               }
+                       }
+                       $dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$file, 'GET');
+                       // Check if request was successful and entry exists
+                       if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) {
+                               $this->entries[$file] = $entry;
+                               return $entry;
+                       }
+                       return false;
+               }
+       }
+
+       private function getExtension($entry) {
+               $mimetype = $this->getMimeType('', $entry);
+               switch ($mimetype) {
+                       case 'httpd/unix-directory':
+                               return '';
+                       case 'application/vnd.oasis.opendocument.text':
+                               return 'odt';
+                       case 'application/vnd.oasis.opendocument.spreadsheet':
+                               return 'ods';
+                       case 'application/vnd.oasis.opendocument.presentation':
+                               return 'pptx';
+                       case 'text/html':
+                               return 'html';
+                       default:
+                               return 'html';
+               }
+       }
+       
+
+       public function mkdir($path) {
+               $dir = dirname($path);
+               // Check if path parent is root directory
+               if ($dir == '/' || $dir == '\.' || $dir == '.') {
+                       $feedUri = 'https://docs.google.com/feeds/default/private/full';
+               // Get parent content link
+               } else if ($dom = $this->getResource(basename($dir))) {
+                       $feedUri = $dom->getElementsByTagName('content')->item(0)->getAttribute('src');
+               }
+               if (isset($feedUri)) {
+                       $title = basename($path);
+                       // Construct post data
+                       $postData = '<?xml version="1.0" encoding="UTF-8"?>';
+                       $postData .= '<entry xmlns="http://www.w3.org/2005/Atom">';
+                       $postData .= '<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#folder"/>';
+                       $postData .= '<title>'.$title.'</title>';
+                       $postData .= '</entry>';
+                       if ($dom = $this->sendRequest($feedUri, 'POST', $postData)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       public function rmdir($path) {
+               return $this->unlink($path);
+       }
+
+       public function opendir($path) {
+               if ($path == '' || $path == '/') {
+                       $next = 'https://docs.google.com/feeds/default/private/full/folder%3Aroot/contents';
+               } else {
+                       if ($entry = $this->getResource($path)) {
+                               $next = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
+                       } else {
+                               return false;
+                       }
+               }
+               $files = array();
+               while ($next) {
+                       $dom = $this->sendRequest($next, 'GET');
+                       $links = $dom->getElementsByTagName('link');
+                       foreach ($links as $link) {
+                               if ($link->getAttribute('rel') == 'next') {
+                                       $next = $link->getAttribute('src');
+                                       break;
+                               } else {
+                                       $next = false;
+                               }
+                       }
+                       $entries = $dom->getElementsByTagName('entry');
+                       foreach ($entries as $entry) {
+                               $name = $entry->getElementsByTagName('title')->item(0)->nodeValue;
+                               // Google Docs resources don't always include extensions in title
+                               if (!strpos($name, '.')) {
+                                       $extension = $this->getExtension($entry);
+                                       if ($extension != '') {
+                                               $name .= '.'.$extension;
+                                       }
+                               }
+                               $files[] = $name;
+                               // Cache entry for future use
+                               $this->entries[$name] = $entry;
+                       }
+               }
+               OC_FakeDirStream::$dirs['google'] = $files;
+               return opendir('fakedir://google');
+       }
+
+       public function stat($path) {
+               if ($path == '' || $path == '/') {
+                       $stat['size'] = $this->free_space($path);
+                       $stat['atime'] = time();
+                       $stat['mtime'] = time();
+                       $stat['ctime'] = time();
+               } else if ($entry = $this->getResource($path)) {
+                       // NOTE: Native resources don't have a file size
+                       $stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue;
+//                     if (isset($atime = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue)) 
+//                     $stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue);
+                       $stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue);
+                       $stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue);
+               }
+               if (isset($stat)) {
+                       return $stat;
+               }
+               return false;
+       }
+
+       public function filetype($path) {
+               if ($path == '' || $path == '/') {
+                       return 'dir';
+               } else if ($entry = $this->getResource($path)) {
+                       $categories = $entry->getElementsByTagName('category');
+                       foreach ($categories as $category) {
+                               if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') {
+                                       $type = $category->getAttribute('label');
+                                       if (strlen(strstr($type, 'folder')) > 0) {
+                                               return 'dir';
+                                       } else {
+                                               return 'file';
+                                       }
+                               }
+                       }
+               }
+               return false;
+       }
+
+       public function is_readable($path) {
+               return true;
+       }
+
+       public function is_writable($path) {
+               if ($path == '' || $path == '/') {
+                       return true;
+               } else if ($entry = $this->getResource($path)) {
+                       // Check if edit or edit-media links exist
+                       $links = $entry->getElementsByTagName('link');
+                       foreach ($links as $link) {
+                               if ($link->getAttribute('rel') == 'edit') {
+                                       return true;
+                               } else if ($link->getAttribute('rel') == 'edit-media') {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+       
+       public function file_exists($path) {
+               if ($path == '' || $path == '/') {
+                       return true;
+               } else if ($this->getResource($path)) {
+                       return true;
+               }
+               return false;
+       }
+       
+       public function unlink($path) {
+               // Get resource self link to trash resource
+               if ($entry = $this->getResource($path)) {
+                       $links = $entry->getElementsByTagName('link');
+                       foreach ($links as $link) {
+                               if ($link->getAttribute('rel') == 'self') {
+                                       $feedUri = $link->getAttribute('href');
+                               }
+                       }
+               }
+               if (isset($feedUri)) {
+                       $this->sendRequest($feedUri, 'DELETE');
+                       return true;
+               }
+               return false;
+       }
+
+       public function rename($path1, $path2) {
+               // TODO Add support for moving to different collections
+               // Get resource edit link to rename resource
+               if ($entry = $this->getResource($path1)) {
+                       $etag = $entry->getElementsByTagName('entry')->item(0)->getAttribute('gd:etag');
+                       $links = $entry->getElementsByTagName('link');
+                       foreach ($links as $link) {
+                               if ($link->getAttribute('rel') == 'edit') {
+                                       $feedUri = $link->getAttribute('href');
+                               }
+                       }
+               }
+               if (isset($etag) && isset($feedUri)) {
+                       $title = basename($path2);
+                       // Construct post data
+                       $postData = '<?xml version="1.0" encoding="UTF-8"?>';
+                       $postData .= '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007" xmlns:gd="http://schemas.google.com/g/2005" gd:etag='.$etag.'>';
+                       $postData .= '<title>'.$title.'</title>';
+                       $postData .= '</entry>';
+                       $this->sendRequest($feedUri, 'PUT', $postData);
+                       return true;
+               }
+               return false;
+       }
+
+       public function fopen($path, $mode) {
+               if ($entry = $this->getResource($path)) {
+                       switch ($mode) {
+                               case 'r':
+                               case 'rb':
+                                       $extension = $this->getExtension($entry);
+                                       $downloadUri = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
+                                       // TODO Non-native documents don't need these additional parameters
+                                       $downloadUri .= '&exportFormat='.$extension.'&format='.$extension;
+                                       $tmpFile = $this->sendRequest($downloadUri, 'GET', true);
+                                       return fopen($tmpFile, 'r');
+                               case 'w':
+                               case 'wb':
+                               case 'a':
+                               case 'ab':
+                               case 'r+':
+                               case 'w+':
+                               case 'wb+':
+                               case 'a+':
+                               case 'x':
+                               case 'x+':
+                               case 'c':
+                               case 'c+':
+                                       // TODO Edit documents
+                       }
+                       
+               }
+               return false;
+       }
+
+       public function getMimeType($path, $entry = null) {
+               // Entry can be passed, because extension is required for opendir and the entry can't be cached without the extension
+               if ($entry == null) {
+                       if ($path == '' || $path == '/') {
+                               return 'httpd/unix-directory';
+                       } else {
+                               $entry = $this->getResource($path);
+                       }
+               }
+               if ($entry) {
+                       $mimetype = $entry->getElementsByTagName('content')->item(0)->getAttribute('type');
+                       // Native Google Docs resources often default to text/html, but it may be more useful to default to a corresponding ODF mimetype
+                       // Collections get reported as application/atom+xml, make sure it actually is a folder and fix the mimetype
+                       if ($mimetype == 'text/html' || $mimetype == 'application/atom+xml;type=feed') {
+                               $categories = $entry->getElementsByTagName('category');
+                               foreach ($categories as $category) {
+                                       if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') {
+                                               $type = $category->getAttribute('label');
+                                               if (strlen(strstr($type, 'folder')) > 0) {
+                                                       return 'httpd/unix-directory';
+                                               } else if (strlen(strstr($type, 'document')) > 0) {
+                                                       return 'application/vnd.oasis.opendocument.text';
+                                               } else if (strlen(strstr($type, 'spreadsheet')) > 0) {
+                                                       return 'application/vnd.oasis.opendocument.spreadsheet';
+                                               } else if (strlen(strstr($type, 'presentation')) > 0) {
+                                                       return 'application/vnd.oasis.opendocument.presentation';
+                                               } else if (strlen(strstr($type, 'drawing')) > 0) {
+                                                       return 'application/vnd.oasis.opendocument.graphics';
+                                               } else {
+                                                       // If nothing matches return text/html, all native Google Docs resources can be exported as text/html
+                                                       return 'text/html';
+                                               }
+                                       }
+                               }
+                       }
+                       return $mimetype;
+               }
+               return false;
+       }
+       
+       public function free_space($path) {
+               if ($dom = $this->sendRequest('https://docs.google.com/feeds/metadata/default', 'GET')) {
+                       // NOTE: Native Google Docs resources don't count towards quota
+                       $total = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesTotal')->item(0)->nodeValue;
+                       $used = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue;
+                       return $total - $used;
+               }
+               return false;
+       }
+  
+       public function touch($path, $mtime = null) {
+         
+       }
+
+}
\ No newline at end of file
diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php
new file mode 100644 (file)
index 0000000..7a2da5c
--- /dev/null
@@ -0,0 +1,293 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class OC_FileStorage_DAV extends OC_Filestorage_Common{
+       private $password;
+       private $user;
+       private $host;
+       private $secure;
+       private $root;
+       /**
+        * @var Sabre_DAV_Client
+        */
+       private $client;
+
+       private static $tempFiles=array();
+       
+       public function __construct($params){
+               $this->host=$params['host'];
+               $this->user=$params['user'];
+               $this->password=$params['password'];
+               $this->secure=isset($params['secure'])?(bool)$params['secure']:false;
+               $this->root=isset($params['root'])?$params['root']:'/';
+               if(substr($this->root,0,1)!='/'){
+                       $this->root='/'.$this->root;
+               }
+               if(substr($this->root,-1,1)!='/'){
+                       $this->root.='/';
+               }
+               
+               $settings = array(
+                       'baseUri' => $this->createBaseUri(),
+                       'userName' => $this->user,
+                       'password' => $this->password,
+               );
+               $this->client = new Sabre_DAV_Client($settings);
+
+               //create the root folder if necesary
+               $this->mkdir('');
+       }
+
+       private function createBaseUri(){
+               $baseUri='http';
+               if($this->secure){
+                       $baseUri.'s';
+               }
+               $baseUri.='://'.$this->host.$this->root;
+               return $baseUri;
+       }
+
+       public function mkdir($path){
+               $path=$this->cleanPath($path);
+               return $this->simpleResponse('MKCOL',$path,null,201);
+       }
+
+       public function rmdir($path){
+               $path=$this->cleanPath($path);
+               return $this->simpleResponse('DELETE',$path,null,204);
+       }
+
+       public function opendir($path){
+               $path=$this->cleanPath($path);
+               try{
+                       $response=$this->client->propfind($path, array(),1);
+                       $stripLength=strlen($this->root)+strlen($path);
+                       $id=md5('webdav'.$this->root.$path);
+                       OC_FakeDirStream::$dirs[$id]=array();
+                       foreach($response as $file=>$data){
+                               //strip root and path
+                               $file=trim(substr($file,$stripLength));
+                               $file=trim($file,'/');
+                               if($file){
+                                       OC_FakeDirStream::$dirs[$id][]=$file;
+                               }
+                       }
+                       return opendir('fakedir://'.$id);
+               }catch(Exception $e){
+                       return false;
+               }
+       }
+
+       public function filetype($path){
+               $path=$this->cleanPath($path);
+               try{
+                       $response=$this->client->propfind($path, array('{DAV:}resourcetype'));
+                       $responseType=$response["{DAV:}resourcetype"]->resourceType;
+                       return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file';
+               }catch(Exception $e){
+                       return false;
+               }
+       }
+
+       public function is_readable($path){
+               return true;//not properly supported
+       }
+
+       public function is_writable($path){
+               return true;//not properly supported
+       }
+
+       public function file_exists($path){
+               $path=$this->cleanPath($path);
+               try{
+                       $response=$this->client->propfind($path, array('{DAV:}resourcetype'));
+                       return true;//no 404 exception
+               }catch(Exception $e){
+                       return false;
+               }
+       }
+
+       public function unlink($path){
+               return $this->simpleResponse('DELETE',$path,null,204);
+       }
+
+       public function fopen($path,$mode){
+               $path=$this->cleanPath($path);
+               switch($mode){
+                       case 'r':
+                       case 'rb':
+                               //straight up curl instead of sabredav here, sabredav put's the entire get result in memory
+                               $curl = curl_init();
+                               $fp = fopen('php://temp', 'r+');
+                               curl_setopt($curl,CURLOPT_USERPWD,$this->user.':'.$this->password);
+                               curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$path);
+                               curl_setopt($curl, CURLOPT_FILE, $fp);
+
+                               curl_exec ($curl);
+                               curl_close ($curl);
+                               rewind($fp);
+                               return $fp;
+                       case 'w':
+                       case 'wb':
+                       case 'a':
+                       case 'ab':
+                       case 'r+':
+                       case 'w+':
+                       case 'wb+':
+                       case 'a+':
+                       case 'x':
+                       case 'x+':
+                       case 'c':
+                       case 'c+':
+                               //emulate these
+                               if(strrpos($path,'.')!==false){
+                                       $ext=substr($path,strrpos($path,'.'));
+                               }else{
+                                       $ext='';
+                               }
+                               $tmpFile=OC_Helper::tmpFile($ext);
+                               OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
+                               if($this->file_exists($path)){
+                                       $this->getFile($path,$tmpFile);
+                               }
+                               self::$tempFiles[$tmpFile]=$path;
+                               return fopen('close://'.$tmpFile,$mode);
+               }
+       }
+
+       public function writeBack($tmpFile){
+               if(isset(self::$tempFiles[$tmpFile])){
+                       $this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]);
+                       unlink($tmpFile);
+               }
+       }
+
+       public function free_space($path){
+               $path=$this->cleanPath($path);
+               try{
+                       $response=$this->client->propfind($path, array('{DAV:}quota-available-bytes'));
+                       if(isset($response['{DAV:}quota-available-bytes'])){
+                               return (int)$response['{DAV:}quota-available-bytes'];
+                       }else{
+                               return 0;
+                       }
+               }catch(Exception $e){
+                       return 0;
+               }
+       }
+
+       public function touch($path,$mtime=null){
+               if(is_null($mtime)){
+                       $mtime=time();
+               }
+               $path=$this->cleanPath($path);
+               $this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime,));
+       }
+
+       public function getFile($path,$target){
+               $source=$this->fopen($path,'r');
+               file_put_contents($target,$source);
+       }
+
+       public function uploadFile($path,$target){
+               $source=fopen($path,'r');
+
+               $curl = curl_init();
+               curl_setopt($curl,CURLOPT_USERPWD,$this->user.':'.$this->password);
+               curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$target);
+               curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
+               curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer
+               curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path));
+               curl_setopt($curl, CURLOPT_PUT, true);
+               curl_exec ($curl);
+               curl_close ($curl);
+       }
+
+       public function rename($path1,$path2){
+               $path1=$this->cleanPath($path1);
+               $path2=$this->root.$this->cleanPath($path2);
+               try{
+                       $response=$this->client->request('MOVE',$path1,null,array('Destination'=>$path2));
+                       return true;
+               }catch(Exception $e){
+                       echo $e;
+                       echo 'fail';
+                       var_dump($response);
+                       return false;
+               }
+       }
+
+       public function copy($path1,$path2){
+               $path1=$this->cleanPath($path1);
+               $path2=$this->root.$this->cleanPath($path2);
+               try{
+                       $response=$this->client->request('COPY',$path1,null,array('Destination'=>$path2));
+                       return true;
+               }catch(Exception $e){
+                       echo $e;
+                       echo 'fail';
+                       var_dump($response);
+                       return false;
+               }
+       }
+
+       public function stat($path){
+               $path=$this->cleanPath($path);
+               try{
+                       $response=$this->client->propfind($path, array('{DAV:}getlastmodified','{DAV:}getcontentlength'));
+                       if(isset($response['{DAV:}getlastmodified']) and isset($response['{DAV:}getcontentlength'])){
+                               return array(
+                                       'mtime'=>strtotime($response['{DAV:}getlastmodified']),
+                                       'size'=>(int)$response['{DAV:}getcontentlength'],
+                                       'ctime'=>-1,
+                               );
+                       }else{
+                               return array();
+                       }
+               }catch(Exception $e){
+                       return array();
+               }
+       }
+
+       public function getMimeType($path){
+               $path=$this->cleanPath($path);
+               try{
+                       $response=$this->client->propfind($path, array('{DAV:}getcontenttype','{DAV:}resourcetype'));
+                       $responseType=$response["{DAV:}resourcetype"]->resourceType;
+                       $type=(count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file';
+                       if($type=='dir'){
+                               return 'httpd/unix-directory';
+                       }elseif(isset($response['{DAV:}getcontenttype'])){
+                               return $response['{DAV:}getcontenttype'];
+                       }else{
+                               return false;
+                       }
+               }catch(Exception $e){
+                       return false;
+               }
+       }
+
+       private function cleanPath($path){
+               if(substr($path,0,1)=='/'){
+                       return substr($path,1);
+               }else{
+                       return $path;
+               }
+       }
+
+       private function simpleResponse($method,$path,$body,$expected){
+               $path=$this->cleanPath($path);
+               try{
+                       $response=$this->client->request($method,$path,$body);
+                       return $response['statusCode']==$expected;
+               }catch(Exception $e){
+                       return false;
+               }
+       }
+}
+
diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php
new file mode 100644 (file)
index 0000000..9b40d2b
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+return array(
+       'ftp'=>array(
+               'host'=>'localhost',
+               'user'=>'test',
+               'password'=>'test',
+               'root'=>'/test',
+       ),
+       'webdav'=>array(
+               'host'=>'localhost',
+               'user'=>'test',
+               'password'=>'test',
+               'root'=>'/owncloud/files/webdav.php',
+       ),
+       'google'=>array(
+               'consumer_key'=>'anonymous',
+               'consumer_secret'=>'anonymous',
+               'token'=>'test',
+               'token_secret'=>'test',
+               'root'=>'/google',
+       )
+);
diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php
new file mode 100644 (file)
index 0000000..aa56575
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class Test_Filestorage_FTP extends Test_FileStorage {
+       private $config;
+       private $id;
+
+       public function setUp(){
+               $id=uniqid();
+               $this->config=include('apps/files_external/tests/config.php');
+               $this->config['ftp']['root'].='/'.$id;//make sure we have an new empty folder to work in
+               $this->instance=new OC_Filestorage_FTP($this->config['ftp']);
+       }
+
+       public function tearDown(){
+               OC_Helper::rmdirr($this->instance->constructUrl(''));
+       }
+}
diff --git a/apps/files_external/tests/google.php b/apps/files_external/tests/google.php
new file mode 100644 (file)
index 0000000..1c02894
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Michael Gapczynski
+* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
+*
+* 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 Affero General Public
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+class Test_Filestorage_Google extends Test_FileStorage {
+       
+       private $config;
+       private $id;
+
+       public function setUp(){
+               $id=uniqid();
+               $this->config=include('apps/files_external/tests/config.php');
+               $this->config['google']['root'].='/'.$id;//make sure we have an new empty folder to work in
+               $this->instance=new OC_Filestorage_Google($this->config['google']);
+       }
+
+       public function tearDown(){
+               $this->instance->rmdir('/');
+       }
+}
diff --git a/apps/files_external/tests/webdav.php b/apps/files_external/tests/webdav.php
new file mode 100644 (file)
index 0000000..5179929
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class Test_Filestorage_DAV extends Test_FileStorage {
+       private $config;
+       private $id;
+
+       public function setUp(){
+               $id=uniqid();
+               $this->config=include('apps/files_external/tests/config.php');
+               $this->config['webdav']['root'].='/'.$id;//make sure we have an new empty folder to work in
+               $this->instance=new OC_Filestorage_DAV($this->config['webdav']);
+       }
+
+       public function tearDown(){
+               $this->instance->rmdir('/');
+       }
+}
diff --git a/apps/files_remote/appinfo/app.php b/apps/files_remote/appinfo/app.php
deleted file mode 100644 (file)
index 02c1c3a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_remote/lib/ftp.php';
-OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_remote/lib/webdav.php';
-OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_remote/lib/google.php';
diff --git a/apps/files_remote/appinfo/info.xml b/apps/files_remote/appinfo/info.xml
deleted file mode 100644 (file)
index 8cf66dd..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0"?>
-<info>
-       <id>files_remote</id>
-       <name>Remote storage support</name>
-       <description>Mount remote storage sources</description>
-       <version>0.1</version>
-       <licence>AGPL</licence>
-       <author>Robin Appelman</author>
-       <require>3</require>
-       <types>
-               <filesystem/>
-       </types>
-</info>
diff --git a/apps/files_remote/lib/ftp.php b/apps/files_remote/lib/ftp.php
deleted file mode 100644 (file)
index 802446b..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-class OC_FileStorage_FTP extends OC_Filestorage_Common{
-       private $password;
-       private $user;
-       private $host;
-       private $secure;
-       private $root;
-
-       private static $tempFiles=array();
-       
-       public function __construct($params){
-               $this->host=$params['host'];
-               $this->user=$params['user'];
-               $this->password=$params['password'];
-               $this->secure=isset($params['secure'])?(bool)$params['secure']:false;
-               $this->root=isset($params['root'])?$params['root']:'/';
-               if(substr($this->root,0,1)!='/'){
-                       $this->root='/'.$this->root;
-               }
-               
-               //create the root folder if necesary
-               mkdir($this->constructUrl(''));
-       }
-
-       /**
-        * construct the ftp url
-        * @param string path
-        * @return string
-        */
-       public function constructUrl($path){
-               $url='ftp';
-               if($this->secure){
-                       $url.='s';
-               }
-               $url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path;
-               return $url;
-       }
-
-       public function mkdir($path){
-               return mkdir($this->constructUrl($path));
-       }
-
-       public function rmdir($path){
-               if($this->file_exists($path)){
-                       $succes=rmdir($this->constructUrl($path));
-                       clearstatcache();
-                       return $succes;
-               }else{
-                       return false;
-               }
-       }
-
-       public function opendir($path){
-               return opendir($this->constructUrl($path));
-       }
-
-       public function filetype($path){
-               return filetype($this->constructUrl($path));
-       }
-
-       public function is_readable($path){
-               return true;//not properly supported
-       }
-
-       public function is_writable($path){
-               return true;//not properly supported
-       }
-
-       public function file_exists($path){
-               return file_exists($this->constructUrl($path));
-       }
-
-       public function unlink($path){
-               $succes=unlink($this->constructUrl($path));
-               clearstatcache();
-               return $succes;
-       }
-
-       public function fopen($path,$mode){
-               switch($mode){
-                       case 'r':
-                       case 'rb':
-                       case 'w':
-                       case 'wb':
-                       case 'a':
-                       case 'ab':
-                               //these are supported by the wrapper
-                               $context = stream_context_create(array('ftp' => array('overwrite' => true)));
-                               return fopen($this->constructUrl($path),$mode,false,$context);
-                       case 'r+':
-                       case 'w+':
-                       case 'wb+':
-                       case 'a+':
-                       case 'x':
-                       case 'x+':
-                       case 'c':
-                       case 'c+':
-                               //emulate these
-                               if(strrpos($path,'.')!==false){
-                                       $ext=substr($path,strrpos($path,'.'));
-                               }else{
-                                       $ext='';
-                               }
-                               $tmpFile=OC_Helper::tmpFile($ext);
-                               OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
-                               if($this->file_exists($path)){
-                                       $this->getFile($path,$tmpFile);
-                               }
-                               self::$tempFiles[$tmpFile]=$path;
-                               return fopen('close://'.$tmpFile,$mode);
-               }
-       }
-
-       public function writeBack($tmpFile){
-               if(isset(self::$tempFiles[$tmpFile])){
-                       $this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]);
-                       unlink($tmpFile);
-               }
-       }
-
-       public function free_space($path){
-               return 0;
-       }
-
-       public function touch($path,$mtime=null){
-               if(is_null($mtime)){
-                       $fh=$this->fopen($path,'a');
-                       fwrite($fh,'');
-                       fclose($fh);
-               }else{
-                       return false;//not supported
-               }
-       }
-
-       public function getFile($path,$target){
-               return copy($this->constructUrl($path),$target);
-       }
-
-       public function uploadFile($path,$target){
-               return copy($path,$this->constructUrl($target));
-       }
-
-       public function rename($path1,$path2){
-               return rename($this->constructUrl($path1),$this->constructUrl($path2));
-       }
-
-       public function stat($path){
-               return stat($this->constructUrl($path));
-       }
-}
diff --git a/apps/files_remote/lib/google.php b/apps/files_remote/lib/google.php
deleted file mode 100644 (file)
index 0d6db19..0000000
+++ /dev/null
@@ -1,409 +0,0 @@
-<?php
-
-/**
-* ownCloud
-*
-* @author Michael Gapczynski
-* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
-*
-* 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 Affero General Public
-* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-require_once 'common.inc.php';
-
-class OC_Filestorage_Google extends OC_Filestorage_Common {
-
-       private $consumer;
-       private $oauth_token;
-       private $sig_method;
-       private $entries;
-
-       public function __construct($arguments) {
-               $consumer_key = isset($arguments['consumer_key']) ? $arguments['consumer_key'] : 'anonymous';
-               $consumer_secret = isset($arguments['consumer_secret']) ? $arguments['consumer_secret'] : 'anonymous';
-               $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
-               $this->oauth_token = new OAuthToken($arguments['token'], $arguments['token_secret']);
-               $this->sig_method = new OAuthSignatureMethod_HMAC_SHA1();
-               $this->entries = array();
-       }
-
-       private function sendRequest($feedUri, $http_method, $isDownload = false, $postData = null) {
-               $feedUri = trim($feedUri);
-               // create an associative array from each key/value url query param pair.
-               $params = array();
-               $pieces = explode('?', $feedUri);
-               if (isset($pieces[1])) {
-                       $params = explode_assoc('=', '&', $pieces[1]);
-               }
-               // urlencode each url parameter key/value pair
-               $tempStr = $pieces[0];
-               foreach ($params as $key => $value) {
-                       $tempStr .= '&' . urlencode($key) . '=' . urlencode($value);
-               }
-               $feedUri = preg_replace('/&/', '?', $tempStr, 1);
-               $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $http_method, $feedUri, $params);
-               $request->sign_request($this->sig_method, $this->consumer, $this->oauth_token);
-               $auth_header = $request->to_header();
-               $headers = array($auth_header, 'Content-Type: application/atom+xml', 'GData-Version: 3.0');
-               $curl = curl_init($feedUri);
-               curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
-               curl_setopt($curl, CURLOPT_FAILONERROR, false);
-               curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
-               switch ($http_method) {
-                       case 'GET':
-                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
-                               break;
-                       case 'POST':
-                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
-                               curl_setopt($curl, CURLOPT_POST, 1);
-                               curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
-                               break;
-                       case 'PUT':
-                               $headers[] = 'If-Match: *';
-                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
-                               curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
-                               curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
-                               break;
-                       case 'DELETE':
-                               $headers[] = 'If-Match: *';
-                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
-                               curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
-                               break;
-                       default:
-                               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
-               }
-               if ($isDownload) {
-                       $tmpFile = OC_Helper::tmpFile();
-                       $fp = fopen($tmpFile, 'w');
-                       curl_setopt($curl, CURLOPT_FILE, $fp);
-                       curl_exec($curl);
-                       curl_close($curl);
-                       return $tmpFile;
-               }
-               $result = curl_exec($curl);
-               curl_close($curl);
-               $dom = new DOMDocument();
-               $dom->loadXML($result);
-               return $dom;
-       }
-
-       private function getResource($path) {
-               $file = basename($path);
-               if (array_key_exists($file, $this->entries)) {
-                       return $this->entries[$file];
-               } else {
-                       // Strip the file extension; file could be a native Google Docs resource
-                       if ($pos = strpos($file, '.')) {
-                               $title = substr($file, 0, $pos);
-                               $dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$title, 'GET');
-                               // Check if request was successful and entry exists
-                               if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) {
-                                       $this->entries[$file] = $entry;
-                                       return $entry;
-                               }
-                       }
-                       $dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$file, 'GET');
-                       // Check if request was successful and entry exists
-                       if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) {
-                               $this->entries[$file] = $entry;
-                               return $entry;
-                       }
-                       return false;
-               }
-       }
-
-       private function getExtension($entry) {
-               $mimetype = $this->getMimeType('', $entry);
-               switch ($mimetype) {
-                       case 'httpd/unix-directory':
-                               return '';
-                       case 'application/vnd.oasis.opendocument.text':
-                               return 'odt';
-                       case 'application/vnd.oasis.opendocument.spreadsheet':
-                               return 'ods';
-                       case 'application/vnd.oasis.opendocument.presentation':
-                               return 'pptx';
-                       case 'text/html':
-                               return 'html';
-                       default:
-                               return 'html';
-               }
-       }
-       
-
-       public function mkdir($path) {
-               $dir = dirname($path);
-               // Check if path parent is root directory
-               if ($dir == '/' || $dir == '\.' || $dir == '.') {
-                       $feedUri = 'https://docs.google.com/feeds/default/private/full';
-               // Get parent content link
-               } else if ($dom = $this->getResource(basename($dir))) {
-                       $feedUri = $dom->getElementsByTagName('content')->item(0)->getAttribute('src');
-               }
-               if (isset($feedUri)) {
-                       $title = basename($path);
-                       // Construct post data
-                       $postData = '<?xml version="1.0" encoding="UTF-8"?>';
-                       $postData .= '<entry xmlns="http://www.w3.org/2005/Atom">';
-                       $postData .= '<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#folder"/>';
-                       $postData .= '<title>'.$title.'</title>';
-                       $postData .= '</entry>';
-                       if ($dom = $this->sendRequest($feedUri, 'POST', $postData)) {
-                               return true;
-                       }
-               }
-               return false;
-       }
-
-       public function rmdir($path) {
-               return $this->unlink($path);
-       }
-
-       public function opendir($path) {
-               if ($path == '' || $path == '/') {
-                       $next = 'https://docs.google.com/feeds/default/private/full/folder%3Aroot/contents';
-               } else {
-                       if ($entry = $this->getResource($path)) {
-                               $next = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
-                       } else {
-                               return false;
-                       }
-               }
-               $files = array();
-               while ($next) {
-                       $dom = $this->sendRequest($next, 'GET');
-                       $links = $dom->getElementsByTagName('link');
-                       foreach ($links as $link) {
-                               if ($link->getAttribute('rel') == 'next') {
-                                       $next = $link->getAttribute('src');
-                                       break;
-                               } else {
-                                       $next = false;
-                               }
-                       }
-                       $entries = $dom->getElementsByTagName('entry');
-                       foreach ($entries as $entry) {
-                               $name = $entry->getElementsByTagName('title')->item(0)->nodeValue;
-                               // Google Docs resources don't always include extensions in title
-                               if (!strpos($name, '.')) {
-                                       $extension = $this->getExtension($entry);
-                                       if ($extension != '') {
-                                               $name .= '.'.$extension;
-                                       }
-                               }
-                               $files[] = $name;
-                               // Cache entry for future use
-                               $this->entries[$name] = $entry;
-                       }
-               }
-               OC_FakeDirStream::$dirs['google'] = $files;
-               return opendir('fakedir://google');
-       }
-
-       public function stat($path) {
-               if ($path == '' || $path == '/') {
-                       $stat['size'] = $this->free_space($path);
-                       $stat['atime'] = time();
-                       $stat['mtime'] = time();
-                       $stat['ctime'] = time();
-               } else if ($entry = $this->getResource($path)) {
-                       // NOTE: Native resources don't have a file size
-                       $stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue;
-//                     if (isset($atime = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue)) 
-//                     $stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue);
-                       $stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue);
-                       $stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue);
-               }
-               if (isset($stat)) {
-                       return $stat;
-               }
-               return false;
-       }
-
-       public function filetype($path) {
-               if ($path == '' || $path == '/') {
-                       return 'dir';
-               } else if ($entry = $this->getResource($path)) {
-                       $categories = $entry->getElementsByTagName('category');
-                       foreach ($categories as $category) {
-                               if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') {
-                                       $type = $category->getAttribute('label');
-                                       if (strlen(strstr($type, 'folder')) > 0) {
-                                               return 'dir';
-                                       } else {
-                                               return 'file';
-                                       }
-                               }
-                       }
-               }
-               return false;
-       }
-
-       public function is_readable($path) {
-               return true;
-       }
-
-       public function is_writable($path) {
-               if ($path == '' || $path == '/') {
-                       return true;
-               } else if ($entry = $this->getResource($path)) {
-                       // Check if edit or edit-media links exist
-                       $links = $entry->getElementsByTagName('link');
-                       foreach ($links as $link) {
-                               if ($link->getAttribute('rel') == 'edit') {
-                                       return true;
-                               } else if ($link->getAttribute('rel') == 'edit-media') {
-                                       return true;
-                               }
-                       }
-               }
-               return false;
-       }
-       
-       public function file_exists($path) {
-               if ($path == '' || $path == '/') {
-                       return true;
-               } else if ($this->getResource($path)) {
-                       return true;
-               }
-               return false;
-       }
-       
-       public function unlink($path) {
-               // Get resource self link to trash resource
-               if ($entry = $this->getResource($path)) {
-                       $links = $entry->getElementsByTagName('link');
-                       foreach ($links as $link) {
-                               if ($link->getAttribute('rel') == 'self') {
-                                       $feedUri = $link->getAttribute('href');
-                               }
-                       }
-               }
-               if (isset($feedUri)) {
-                       $this->sendRequest($feedUri, 'DELETE');
-                       return true;
-               }
-               return false;
-       }
-
-       public function rename($path1, $path2) {
-               // TODO Add support for moving to different collections
-               // Get resource edit link to rename resource
-               if ($entry = $this->getResource($path1)) {
-                       $etag = $entry->getElementsByTagName('entry')->item(0)->getAttribute('gd:etag');
-                       $links = $entry->getElementsByTagName('link');
-                       foreach ($links as $link) {
-                               if ($link->getAttribute('rel') == 'edit') {
-                                       $feedUri = $link->getAttribute('href');
-                               }
-                       }
-               }
-               if (isset($etag) && isset($feedUri)) {
-                       $title = basename($path2);
-                       // Construct post data
-                       $postData = '<?xml version="1.0" encoding="UTF-8"?>';
-                       $postData .= '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007" xmlns:gd="http://schemas.google.com/g/2005" gd:etag='.$etag.'>';
-                       $postData .= '<title>'.$title.'</title>';
-                       $postData .= '</entry>';
-                       $this->sendRequest($feedUri, 'PUT', $postData);
-                       return true;
-               }
-               return false;
-       }
-
-       public function fopen($path, $mode) {
-               if ($entry = $this->getResource($path)) {
-                       switch ($mode) {
-                               case 'r':
-                               case 'rb':
-                                       $extension = $this->getExtension($entry);
-                                       $downloadUri = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
-                                       // TODO Non-native documents don't need these additional parameters
-                                       $downloadUri .= '&exportFormat='.$extension.'&format='.$extension;
-                                       $tmpFile = $this->sendRequest($downloadUri, 'GET', true);
-                                       return fopen($tmpFile, 'r');
-                               case 'w':
-                               case 'wb':
-                               case 'a':
-                               case 'ab':
-                               case 'r+':
-                               case 'w+':
-                               case 'wb+':
-                               case 'a+':
-                               case 'x':
-                               case 'x+':
-                               case 'c':
-                               case 'c+':
-                                       // TODO Edit documents
-                       }
-                       
-               }
-               return false;
-       }
-
-       public function getMimeType($path, $entry = null) {
-               // Entry can be passed, because extension is required for opendir and the entry can't be cached without the extension
-               if ($entry == null) {
-                       if ($path == '' || $path == '/') {
-                               return 'httpd/unix-directory';
-                       } else {
-                               $entry = $this->getResource($path);
-                       }
-               }
-               if ($entry) {
-                       $mimetype = $entry->getElementsByTagName('content')->item(0)->getAttribute('type');
-                       // Native Google Docs resources often default to text/html, but it may be more useful to default to a corresponding ODF mimetype
-                       // Collections get reported as application/atom+xml, make sure it actually is a folder and fix the mimetype
-                       if ($mimetype == 'text/html' || $mimetype == 'application/atom+xml;type=feed') {
-                               $categories = $entry->getElementsByTagName('category');
-                               foreach ($categories as $category) {
-                                       if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') {
-                                               $type = $category->getAttribute('label');
-                                               if (strlen(strstr($type, 'folder')) > 0) {
-                                                       return 'httpd/unix-directory';
-                                               } else if (strlen(strstr($type, 'document')) > 0) {
-                                                       return 'application/vnd.oasis.opendocument.text';
-                                               } else if (strlen(strstr($type, 'spreadsheet')) > 0) {
-                                                       return 'application/vnd.oasis.opendocument.spreadsheet';
-                                               } else if (strlen(strstr($type, 'presentation')) > 0) {
-                                                       return 'application/vnd.oasis.opendocument.presentation';
-                                               } else if (strlen(strstr($type, 'drawing')) > 0) {
-                                                       return 'application/vnd.oasis.opendocument.graphics';
-                                               } else {
-                                                       // If nothing matches return text/html, all native Google Docs resources can be exported as text/html
-                                                       return 'text/html';
-                                               }
-                                       }
-                               }
-                       }
-                       return $mimetype;
-               }
-               return false;
-       }
-       
-       public function free_space($path) {
-               if ($dom = $this->sendRequest('https://docs.google.com/feeds/metadata/default', 'GET')) {
-                       // NOTE: Native Google Docs resources don't count towards quota
-                       $total = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesTotal')->item(0)->nodeValue;
-                       $used = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue;
-                       return $total - $used;
-               }
-               return false;
-       }
-  
-       public function touch($path, $mtime = null) {
-         
-       }
-
-}
\ No newline at end of file
diff --git a/apps/files_remote/lib/webdav.php b/apps/files_remote/lib/webdav.php
deleted file mode 100644 (file)
index 7a2da5c..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-class OC_FileStorage_DAV extends OC_Filestorage_Common{
-       private $password;
-       private $user;
-       private $host;
-       private $secure;
-       private $root;
-       /**
-        * @var Sabre_DAV_Client
-        */
-       private $client;
-
-       private static $tempFiles=array();
-       
-       public function __construct($params){
-               $this->host=$params['host'];
-               $this->user=$params['user'];
-               $this->password=$params['password'];
-               $this->secure=isset($params['secure'])?(bool)$params['secure']:false;
-               $this->root=isset($params['root'])?$params['root']:'/';
-               if(substr($this->root,0,1)!='/'){
-                       $this->root='/'.$this->root;
-               }
-               if(substr($this->root,-1,1)!='/'){
-                       $this->root.='/';
-               }
-               
-               $settings = array(
-                       'baseUri' => $this->createBaseUri(),
-                       'userName' => $this->user,
-                       'password' => $this->password,
-               );
-               $this->client = new Sabre_DAV_Client($settings);
-
-               //create the root folder if necesary
-               $this->mkdir('');
-       }
-
-       private function createBaseUri(){
-               $baseUri='http';
-               if($this->secure){
-                       $baseUri.'s';
-               }
-               $baseUri.='://'.$this->host.$this->root;
-               return $baseUri;
-       }
-
-       public function mkdir($path){
-               $path=$this->cleanPath($path);
-               return $this->simpleResponse('MKCOL',$path,null,201);
-       }
-
-       public function rmdir($path){
-               $path=$this->cleanPath($path);
-               return $this->simpleResponse('DELETE',$path,null,204);
-       }
-
-       public function opendir($path){
-               $path=$this->cleanPath($path);
-               try{
-                       $response=$this->client->propfind($path, array(),1);
-                       $stripLength=strlen($this->root)+strlen($path);
-                       $id=md5('webdav'.$this->root.$path);
-                       OC_FakeDirStream::$dirs[$id]=array();
-                       foreach($response as $file=>$data){
-                               //strip root and path
-                               $file=trim(substr($file,$stripLength));
-                               $file=trim($file,'/');
-                               if($file){
-                                       OC_FakeDirStream::$dirs[$id][]=$file;
-                               }
-                       }
-                       return opendir('fakedir://'.$id);
-               }catch(Exception $e){
-                       return false;
-               }
-       }
-
-       public function filetype($path){
-               $path=$this->cleanPath($path);
-               try{
-                       $response=$this->client->propfind($path, array('{DAV:}resourcetype'));
-                       $responseType=$response["{DAV:}resourcetype"]->resourceType;
-                       return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file';
-               }catch(Exception $e){
-                       return false;
-               }
-       }
-
-       public function is_readable($path){
-               return true;//not properly supported
-       }
-
-       public function is_writable($path){
-               return true;//not properly supported
-       }
-
-       public function file_exists($path){
-               $path=$this->cleanPath($path);
-               try{
-                       $response=$this->client->propfind($path, array('{DAV:}resourcetype'));
-                       return true;//no 404 exception
-               }catch(Exception $e){
-                       return false;
-               }
-       }
-
-       public function unlink($path){
-               return $this->simpleResponse('DELETE',$path,null,204);
-       }
-
-       public function fopen($path,$mode){
-               $path=$this->cleanPath($path);
-               switch($mode){
-                       case 'r':
-                       case 'rb':
-                               //straight up curl instead of sabredav here, sabredav put's the entire get result in memory
-                               $curl = curl_init();
-                               $fp = fopen('php://temp', 'r+');
-                               curl_setopt($curl,CURLOPT_USERPWD,$this->user.':'.$this->password);
-                               curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$path);
-                               curl_setopt($curl, CURLOPT_FILE, $fp);
-
-                               curl_exec ($curl);
-                               curl_close ($curl);
-                               rewind($fp);
-                               return $fp;
-                       case 'w':
-                       case 'wb':
-                       case 'a':
-                       case 'ab':
-                       case 'r+':
-                       case 'w+':
-                       case 'wb+':
-                       case 'a+':
-                       case 'x':
-                       case 'x+':
-                       case 'c':
-                       case 'c+':
-                               //emulate these
-                               if(strrpos($path,'.')!==false){
-                                       $ext=substr($path,strrpos($path,'.'));
-                               }else{
-                                       $ext='';
-                               }
-                               $tmpFile=OC_Helper::tmpFile($ext);
-                               OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
-                               if($this->file_exists($path)){
-                                       $this->getFile($path,$tmpFile);
-                               }
-                               self::$tempFiles[$tmpFile]=$path;
-                               return fopen('close://'.$tmpFile,$mode);
-               }
-       }
-
-       public function writeBack($tmpFile){
-               if(isset(self::$tempFiles[$tmpFile])){
-                       $this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]);
-                       unlink($tmpFile);
-               }
-       }
-
-       public function free_space($path){
-               $path=$this->cleanPath($path);
-               try{
-                       $response=$this->client->propfind($path, array('{DAV:}quota-available-bytes'));
-                       if(isset($response['{DAV:}quota-available-bytes'])){
-                               return (int)$response['{DAV:}quota-available-bytes'];
-                       }else{
-                               return 0;
-                       }
-               }catch(Exception $e){
-                       return 0;
-               }
-       }
-
-       public function touch($path,$mtime=null){
-               if(is_null($mtime)){
-                       $mtime=time();
-               }
-               $path=$this->cleanPath($path);
-               $this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime,));
-       }
-
-       public function getFile($path,$target){
-               $source=$this->fopen($path,'r');
-               file_put_contents($target,$source);
-       }
-
-       public function uploadFile($path,$target){
-               $source=fopen($path,'r');
-
-               $curl = curl_init();
-               curl_setopt($curl,CURLOPT_USERPWD,$this->user.':'.$this->password);
-               curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$target);
-               curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
-               curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer
-               curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path));
-               curl_setopt($curl, CURLOPT_PUT, true);
-               curl_exec ($curl);
-               curl_close ($curl);
-       }
-
-       public function rename($path1,$path2){
-               $path1=$this->cleanPath($path1);
-               $path2=$this->root.$this->cleanPath($path2);
-               try{
-                       $response=$this->client->request('MOVE',$path1,null,array('Destination'=>$path2));
-                       return true;
-               }catch(Exception $e){
-                       echo $e;
-                       echo 'fail';
-                       var_dump($response);
-                       return false;
-               }
-       }
-
-       public function copy($path1,$path2){
-               $path1=$this->cleanPath($path1);
-               $path2=$this->root.$this->cleanPath($path2);
-               try{
-                       $response=$this->client->request('COPY',$path1,null,array('Destination'=>$path2));
-                       return true;
-               }catch(Exception $e){
-                       echo $e;
-                       echo 'fail';
-                       var_dump($response);
-                       return false;
-               }
-       }
-
-       public function stat($path){
-               $path=$this->cleanPath($path);
-               try{
-                       $response=$this->client->propfind($path, array('{DAV:}getlastmodified','{DAV:}getcontentlength'));
-                       if(isset($response['{DAV:}getlastmodified']) and isset($response['{DAV:}getcontentlength'])){
-                               return array(
-                                       'mtime'=>strtotime($response['{DAV:}getlastmodified']),
-                                       'size'=>(int)$response['{DAV:}getcontentlength'],
-                                       'ctime'=>-1,
-                               );
-                       }else{
-                               return array();
-                       }
-               }catch(Exception $e){
-                       return array();
-               }
-       }
-
-       public function getMimeType($path){
-               $path=$this->cleanPath($path);
-               try{
-                       $response=$this->client->propfind($path, array('{DAV:}getcontenttype','{DAV:}resourcetype'));
-                       $responseType=$response["{DAV:}resourcetype"]->resourceType;
-                       $type=(count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file';
-                       if($type=='dir'){
-                               return 'httpd/unix-directory';
-                       }elseif(isset($response['{DAV:}getcontenttype'])){
-                               return $response['{DAV:}getcontenttype'];
-                       }else{
-                               return false;
-                       }
-               }catch(Exception $e){
-                       return false;
-               }
-       }
-
-       private function cleanPath($path){
-               if(substr($path,0,1)=='/'){
-                       return substr($path,1);
-               }else{
-                       return $path;
-               }
-       }
-
-       private function simpleResponse($method,$path,$body,$expected){
-               $path=$this->cleanPath($path);
-               try{
-                       $response=$this->client->request($method,$path,$body);
-                       return $response['statusCode']==$expected;
-               }catch(Exception $e){
-                       return false;
-               }
-       }
-}
-
diff --git a/apps/files_remote/tests/config.php b/apps/files_remote/tests/config.php
deleted file mode 100644 (file)
index 9b40d2b..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-return array(
-       'ftp'=>array(
-               'host'=>'localhost',
-               'user'=>'test',
-               'password'=>'test',
-               'root'=>'/test',
-       ),
-       'webdav'=>array(
-               'host'=>'localhost',
-               'user'=>'test',
-               'password'=>'test',
-               'root'=>'/owncloud/files/webdav.php',
-       ),
-       'google'=>array(
-               'consumer_key'=>'anonymous',
-               'consumer_secret'=>'anonymous',
-               'token'=>'test',
-               'token_secret'=>'test',
-               'root'=>'/google',
-       )
-);
diff --git a/apps/files_remote/tests/ftp.php b/apps/files_remote/tests/ftp.php
deleted file mode 100644 (file)
index 03633b7..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-class Test_Filestorage_FTP extends Test_FileStorage {
-       private $config;
-       private $id;
-
-       public function setUp(){
-               $id=uniqid();
-               $this->config=include('apps/files_remote/tests/config.php');
-               $this->config['ftp']['root'].='/'.$id;//make sure we have an new empty folder to work in
-               $this->instance=new OC_Filestorage_FTP($this->config['ftp']);
-       }
-
-       public function tearDown(){
-               OC_Helper::rmdirr($this->instance->constructUrl(''));
-       }
-}
diff --git a/apps/files_remote/tests/google.php b/apps/files_remote/tests/google.php
deleted file mode 100644 (file)
index b49f9e4..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
-* ownCloud
-*
-* @author Michael Gapczynski
-* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
-*
-* 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 Affero General Public
-* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-class Test_Filestorage_Google extends Test_FileStorage {
-       
-       private $config;
-       private $id;
-
-       public function setUp(){
-               $id=uniqid();
-               $this->config=include('apps/files_remote/tests/config.php');
-               $this->config['google']['root'].='/'.$id;//make sure we have an new empty folder to work in
-               $this->instance=new OC_Filestorage_Google($this->config['google']);
-       }
-
-       public function tearDown(){
-               $this->instance->rmdir('/');
-       }
-}
\ No newline at end of file
diff --git a/apps/files_remote/tests/webdav.php b/apps/files_remote/tests/webdav.php
deleted file mode 100644 (file)
index 219fff8..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-class Test_Filestorage_DAV extends Test_FileStorage {
-       private $config;
-       private $id;
-
-       public function setUp(){
-               $id=uniqid();
-               $this->config=include('apps/files_remote/tests/config.php');
-               $this->config['webdav']['root'].='/'.$id;//make sure we have an new empty folder to work in
-               $this->instance=new OC_Filestorage_DAV($this->config['webdav']);
-       }
-
-       public function tearDown(){
-               $this->instance->rmdir('/');
-       }
-}