2012-06-09 19:02:26 +00:00
< ? 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 />.
*/
2012-09-07 16:30:48 +00:00
namespace OC\Files\Storage ;
2013-08-18 17:14:14 +00:00
require_once __DIR__ . '/../3rdparty/Dropbox/autoload.php' ;
2012-10-11 21:17:59 +00:00
2012-09-07 16:30:48 +00:00
class Dropbox extends \OC\Files\Storage\Common {
2012-06-09 19:02:26 +00:00
private $dropbox ;
2012-10-06 11:44:53 +00:00
private $root ;
2012-10-11 21:06:57 +00:00
private $id ;
2012-06-09 19:02:26 +00:00
private $metaData = array ();
private static $tempFiles = array ();
2013-06-01 09:28:02 +00:00
/**
* check if curl is installed
*/
public static function checkDependencies () {
if ( function_exists ( 'curl_init' )) {
return true ;
} else {
$l = new \OC_L10N ( 'files_external' );
return $l -> t ( '<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of Dropbox is not possible. Please ask your system administrator to install it.' );
}
}
2012-06-09 19:02:26 +00:00
public function __construct ( $params ) {
2012-11-30 15:27:11 +00:00
if ( isset ( $params [ 'configured' ]) && $params [ 'configured' ] == 'true'
&& isset ( $params [ 'app_key' ])
&& isset ( $params [ 'app_secret' ])
&& isset ( $params [ 'token' ])
&& isset ( $params [ 'token_secret' ])
) {
2013-02-26 22:52:06 +00:00
$this -> root = isset ( $params [ 'root' ]) ? $params [ 'root' ] : '' ;
$this -> id = 'dropbox::' . $params [ 'app_key' ] . $params [ 'token' ] . '/' . $this -> root ;
2012-09-07 16:30:48 +00:00
$oauth = new \Dropbox_OAuth_Curl ( $params [ 'app_key' ], $params [ 'app_secret' ]);
2012-08-13 21:07:56 +00:00
$oauth -> setToken ( $params [ 'token' ], $params [ 'token_secret' ]);
2012-09-07 16:30:48 +00:00
$this -> dropbox = new \Dropbox_API ( $oauth , 'dropbox' );
2012-08-13 21:07:56 +00:00
} else {
2012-09-07 16:30:48 +00:00
throw new \Exception ( 'Creating \OC\Files\Storage\Dropbox storage failed' );
2012-08-13 21:07:56 +00:00
}
2012-06-09 19:02:26 +00:00
}
2014-02-06 15:30:58 +00:00
/**
* @ param string $path
*/
2013-11-26 09:19:45 +00:00
private function deleteMetaData ( $path ) {
$path = $this -> root . $path ;
if ( isset ( $this -> metaData [ $path ])) {
unset ( $this -> metaData [ $path ]);
return true ;
}
return false ;
}
/**
* @ brief Returns the path ' s metadata
2014-02-06 15:30:58 +00:00
* @ param string $path path for which to return the metadata
2013-11-26 09:19:45 +00:00
* @ param $list if true , also return the directory ' s contents
* @ return directory contents if $list is true , file metadata if $list is
* false , null if the file doesn ' t exist or " false " if the operation failed
*/
2012-06-09 19:02:26 +00:00
private function getMetaData ( $path , $list = false ) {
2012-10-06 11:44:53 +00:00
$path = $this -> root . $path ;
2012-11-30 15:27:11 +00:00
if ( ! $list && isset ( $this -> metaData [ $path ])) {
2012-06-09 19:02:26 +00:00
return $this -> metaData [ $path ];
} else {
if ( $list ) {
2012-06-27 00:37:36 +00:00
try {
$response = $this -> dropbox -> getMetaData ( $path );
2012-10-08 11:50:59 +00:00
} catch ( \Exception $exception ) {
\OCP\Util :: writeLog ( 'files_external' , $exception -> getMessage (), \OCP\Util :: ERROR );
2012-06-27 00:37:36 +00:00
return false ;
}
2013-11-26 09:19:45 +00:00
$contents = array ();
2012-06-09 19:02:26 +00:00
if ( $response && isset ( $response [ 'contents' ])) {
// Cache folder's contents
2013-11-26 09:19:45 +00:00
foreach ( $response [ 'contents' ] as $file ) {
if ( ! isset ( $file [ 'is_deleted' ]) || ! $file [ 'is_deleted' ]) {
$this -> metaData [ $path . '/' . basename ( $file [ 'path' ])] = $file ;
$contents [] = $file ;
}
2012-06-09 19:02:26 +00:00
}
unset ( $response [ 'contents' ]);
2013-11-26 09:19:45 +00:00
}
if ( ! isset ( $response [ 'is_deleted' ]) || ! $response [ 'is_deleted' ]) {
2012-06-09 19:02:26 +00:00
$this -> metaData [ $path ] = $response ;
}
// Return contents of folder only
return $contents ;
} else {
try {
$response = $this -> dropbox -> getMetaData ( $path , 'false' );
2013-11-26 09:19:45 +00:00
if ( ! isset ( $response [ 'is_deleted' ]) || ! $response [ 'is_deleted' ]) {
$this -> metaData [ $path ] = $response ;
return $response ;
}
return null ;
2012-10-08 11:50:59 +00:00
} catch ( \Exception $exception ) {
2013-11-26 09:19:45 +00:00
if ( $exception instanceof \Dropbox_Exception_NotFound ) {
// don't log, might be a file_exist check
return false ;
}
2012-10-08 11:50:59 +00:00
\OCP\Util :: writeLog ( 'files_external' , $exception -> getMessage (), \OCP\Util :: ERROR );
2012-06-09 19:02:26 +00:00
return false ;
}
}
}
}
2012-10-11 21:06:57 +00:00
public function getId (){
return $this -> id ;
}
2012-06-09 19:02:26 +00:00
public function mkdir ( $path ) {
2012-10-06 11:44:53 +00:00
$path = $this -> root . $path ;
2012-06-27 19:23:26 +00:00
try {
$this -> dropbox -> createFolder ( $path );
return true ;
2012-10-08 11:50:59 +00:00
} catch ( \Exception $exception ) {
\OCP\Util :: writeLog ( 'files_external' , $exception -> getMessage (), \OCP\Util :: ERROR );
2012-06-27 19:23:26 +00:00
return false ;
}
2012-06-09 19:02:26 +00:00
}
public function rmdir ( $path ) {
2012-06-27 19:23:26 +00:00
return $this -> unlink ( $path );
2012-06-09 19:02:26 +00:00
}
public function opendir ( $path ) {
2012-11-30 15:27:11 +00:00
$contents = $this -> getMetaData ( $path , true );
2013-11-26 09:19:45 +00:00
if ( $contents !== false ) {
2012-06-09 19:02:26 +00:00
$files = array ();
foreach ( $contents as $file ) {
$files [] = basename ( $file [ 'path' ]);
}
2013-01-28 14:34:15 +00:00
\OC\Files\Stream\Dir :: register ( 'dropbox' . $path , $files );
2012-06-27 16:04:11 +00:00
return opendir ( 'fakedir://dropbox' . $path );
2012-06-09 19:02:26 +00:00
}
return false ;
}
public function stat ( $path ) {
2012-11-30 15:27:11 +00:00
$metaData = $this -> getMetaData ( $path );
if ( $metaData ) {
2012-06-09 19:02:26 +00:00
$stat [ 'size' ] = $metaData [ 'bytes' ];
$stat [ 'atime' ] = time ();
2012-06-27 00:37:36 +00:00
$stat [ 'mtime' ] = ( isset ( $metaData [ 'modified' ])) ? strtotime ( $metaData [ 'modified' ]) : time ();
2012-06-09 19:02:26 +00:00
return $stat ;
}
return false ;
}
public function filetype ( $path ) {
if ( $path == '' || $path == '/' ) {
return 'dir' ;
2012-11-30 15:27:11 +00:00
} else {
$metaData = $this -> getMetaData ( $path );
if ( $metaData ) {
if ( $metaData [ 'is_dir' ] == 'true' ) {
return 'dir' ;
} else {
return 'file' ;
}
2012-06-09 19:02:26 +00:00
}
}
return false ;
}
public function file_exists ( $path ) {
if ( $path == '' || $path == '/' ) {
return true ;
}
if ( $this -> getMetaData ( $path )) {
return true ;
}
return false ;
}
public function unlink ( $path ) {
2012-06-27 19:23:26 +00:00
try {
2013-11-26 09:19:45 +00:00
$this -> dropbox -> delete ( $this -> root . $path );
$this -> deleteMetaData ( $path );
2012-06-27 19:23:26 +00:00
return true ;
2012-10-08 11:50:59 +00:00
} catch ( \Exception $exception ) {
\OCP\Util :: writeLog ( 'files_external' , $exception -> getMessage (), \OCP\Util :: ERROR );
2012-06-27 19:23:26 +00:00
return false ;
}
}
public function rename ( $path1 , $path2 ) {
try {
2013-11-26 09:19:45 +00:00
// overwrite if target file exists and is not a directory
$destMetaData = $this -> getMetaData ( $path2 );
if ( isset ( $destMetaData ) && $destMetaData !== false && ! $destMetaData [ 'is_dir' ]) {
$this -> unlink ( $path2 );
}
$this -> dropbox -> move ( $this -> root . $path1 , $this -> root . $path2 );
$this -> deleteMetaData ( $path1 );
2012-06-27 19:23:26 +00:00
return true ;
2012-10-08 11:50:59 +00:00
} catch ( \Exception $exception ) {
\OCP\Util :: writeLog ( 'files_external' , $exception -> getMessage (), \OCP\Util :: ERROR );
2012-06-27 19:23:26 +00:00
return false ;
}
}
public function copy ( $path1 , $path2 ) {
2012-10-06 11:44:53 +00:00
$path1 = $this -> root . $path1 ;
$path2 = $this -> root . $path2 ;
2012-06-27 19:23:26 +00:00
try {
$this -> dropbox -> copy ( $path1 , $path2 );
return true ;
2012-10-08 11:50:59 +00:00
} catch ( \Exception $exception ) {
\OCP\Util :: writeLog ( 'files_external' , $exception -> getMessage (), \OCP\Util :: ERROR );
2012-06-27 19:23:26 +00:00
return false ;
}
2012-06-09 19:02:26 +00:00
}
public function fopen ( $path , $mode ) {
2012-10-06 11:44:53 +00:00
$path = $this -> root . $path ;
2012-06-09 19:02:26 +00:00
switch ( $mode ) {
case 'r' :
case 'rb' :
2012-09-07 16:30:48 +00:00
$tmpFile = \OC_Helper :: tmpFile ();
2012-06-27 19:23:26 +00:00
try {
$data = $this -> dropbox -> getFile ( $path );
file_put_contents ( $tmpFile , $data );
return fopen ( $tmpFile , 'r' );
2012-10-08 11:50:59 +00:00
} catch ( \Exception $exception ) {
\OCP\Util :: writeLog ( 'files_external' , $exception -> getMessage (), \OCP\Util :: ERROR );
2012-06-27 19:23:26 +00:00
return false ;
}
2012-06-09 19:02:26 +00:00
case 'w' :
case 'wb' :
case 'a' :
case 'ab' :
case 'r+' :
case 'w+' :
case 'wb+' :
case 'a+' :
case 'x' :
case 'x+' :
case 'c' :
case 'c+' :
if ( strrpos ( $path , '.' ) !== false ) {
$ext = substr ( $path , strrpos ( $path , '.' ));
} else {
$ext = '' ;
}
2012-09-07 16:30:48 +00:00
$tmpFile = \OC_Helper :: tmpFile ( $ext );
2013-01-28 14:34:15 +00:00
\OC\Files\Stream\Close :: registerCallback ( $tmpFile , array ( $this , 'writeBack' ));
2012-06-09 19:02:26 +00:00
if ( $this -> file_exists ( $path )) {
$source = $this -> fopen ( $path , 'r' );
file_put_contents ( $tmpFile , $source );
}
self :: $tempFiles [ $tmpFile ] = $path ;
return fopen ( 'close://' . $tmpFile , $mode );
}
return false ;
}
public function writeBack ( $tmpFile ) {
if ( isset ( self :: $tempFiles [ $tmpFile ])) {
$handle = fopen ( $tmpFile , 'r' );
2012-06-27 19:23:26 +00:00
try {
2012-07-20 14:48:28 +00:00
$this -> dropbox -> putFile ( self :: $tempFiles [ $tmpFile ], $handle );
2012-06-09 19:02:26 +00:00
unlink ( $tmpFile );
2012-10-08 11:50:59 +00:00
} catch ( \Exception $exception ) {
\OCP\Util :: writeLog ( 'files_external' , $exception -> getMessage (), \OCP\Util :: ERROR );
2012-06-09 19:02:26 +00:00
}
}
}
public function getMimeType ( $path ) {
if ( $this -> filetype ( $path ) == 'dir' ) {
return 'httpd/unix-directory' ;
2012-11-30 15:27:11 +00:00
} else {
$metaData = $this -> getMetaData ( $path );
if ( $metaData ) {
return $metaData [ 'mime_type' ];
}
2012-06-09 19:02:26 +00:00
}
return false ;
}
public function free_space ( $path ) {
2012-06-27 19:23:26 +00:00
try {
$info = $this -> dropbox -> getAccountInfo ();
2012-06-09 19:02:26 +00:00
return $info [ 'quota_info' ][ 'quota' ] - $info [ 'quota_info' ][ 'normal' ];
2012-10-08 11:50:59 +00:00
} catch ( \Exception $exception ) {
\OCP\Util :: writeLog ( 'files_external' , $exception -> getMessage (), \OCP\Util :: ERROR );
2012-06-27 19:23:26 +00:00
return false ;
2012-06-09 19:02:26 +00:00
}
}
public function touch ( $path , $mtime = null ) {
2013-11-25 11:44:27 +00:00
if ( $this -> file_exists ( $path )) {
return false ;
} else {
$this -> file_put_contents ( $path , '' );
}
2013-11-26 09:19:45 +00:00
return true ;
2012-06-09 19:02:26 +00:00
}
}