diff --git a/README.md b/README.md
index 691e9867..774b47c1 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ Get detailed information about all the features and a 'getting started' tutorial
+ Comparing with previous backups
* Sync backups to other locations
+ Amazon s3 (work in progress)
+ + copy
+ Dropbox
+ rsync
+ SFTP
diff --git a/build.xml b/build.xml
index a7a6cb22..c8bfbcaa 100644
--- a/build.xml
+++ b/build.xml
@@ -105,8 +105,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/build/phar-patch.php b/build/phar-patch.php
index c98730c7..9d8ea67e 100755
--- a/build/phar-patch.php
+++ b/build/phar-patch.php
@@ -7,6 +7,11 @@
'search' => array('$this->set(CURLOPT_CAINFO', '$this->set(CURLOPT_CAPATH'),
'replace' => array('//$this->set(CURLOPT_CAINFO', '//$this->set(CURLOPT_CAPATH'),
),
+ array(
+ 'path' => __DIR__ . '/phar/copy/Api.php',
+ 'search' => array('curl_setopt($this->curl, CURLOPT_CAINFO'),
+ 'replace' => array('//curl_setopt($this->curl, CURLOPT_CAINFO'),
+ ),
);
foreach ( $patches as $file ) {
diff --git a/composer.json b/composer.json
index 0313d1c7..503bc11b 100644
--- a/composer.json
+++ b/composer.json
@@ -27,6 +27,7 @@
"ext-dom": "*",
"ext-json": "*",
"ext-spl": "*",
+ "barracuda/copy": "1.1.*",
"dropbox/dropbox-sdk": "1.1.*",
"phpseclib/phpseclib": "2.0.*@dev",
"phpunit/php-timer": "~1.0.2",
diff --git a/doc/config/sync/copycom.xml b/doc/config/sync/copycom.xml
new file mode 100644
index 00000000..c64bdcc4
--- /dev/null
+++ b/doc/config/sync/copycom.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Factory.php b/src/App/Factory.php
index 46b32e81..a0d3f148 100644
--- a/src/App/Factory.php
+++ b/src/App/Factory.php
@@ -43,6 +43,7 @@ abstract class Factory
'sizediffavgpercent' => '\\phpbu\\Backup\\Check\\SizeDiffAvgPercent',
),
'sync' => array(
+ 'copycom' => '\\phpbu\\Backup\\Sync\\Copycom',
'dropbox' => '\\phpbu\\Backup\\Sync\\Dropbox',
'ftp' => '\\phpbu\\Backup\\Sync\\Ftp',
'rsync' => '\\phpbu\\Backup\\Sync\\Rsync',
diff --git a/src/Backup/Sync/Copycom.php b/src/Backup/Sync/Copycom.php
new file mode 100644
index 00000000..3d3e32b4
--- /dev/null
+++ b/src/Backup/Sync/Copycom.php
@@ -0,0 +1,116 @@
+
+ * @copyright Sebastian Feldmann
+ * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
+ * @link http://www.phpbu.de/
+ * @since Class available since Release 1.1.1
+ */
+class Copycom implements Sync
+{
+ /**
+ * API access key
+ *
+ * @var string
+ */
+ protected $appKey;
+
+ /**
+ * API access token
+ *
+ * @var string
+ */
+ protected $appSecret;
+
+ /**
+ * API access key
+ *
+ * @var string
+ */
+ protected $userKey;
+
+ /**
+ * API access token
+ *
+ * @var string
+ */
+ protected $userSecret;
+
+ /**
+ * Remote path
+ *
+ * @var string
+ */
+ protected $path;
+
+ /**
+ * (non-PHPdoc)
+ * @see \phpbu\Backup\Sync::setup()
+ */
+ public function setup(array $config)
+ {
+ if (!class_exists('\\Barracuda\\Copy\\API')) {
+ throw new Exception('Copy api not loaded: use composer "barracuda/copy": "1.1.*" to install');
+ }
+ if (!isset($config['app.key']) || '' == $config['app.key']) {
+ throw new Exception('API access key is mandatory');
+ }
+ if (!isset($config['app.secret']) || '' == $config['app.secret']) {
+ throw new Exception('API access secret is mandatory');
+ }
+ if (!isset($config['user.key']) || '' == $config['user.key']) {
+ throw new Exception('User access key is mandatory');
+ }
+ if (!isset($config['user.secret']) || '' == $config['user.secret']) {
+ throw new Exception('User access secret is mandatory');
+ }
+ if (!isset($config['path']) || '' == $config['path']) {
+ throw new Exception('dropbox path is mandatory');
+ }
+ $this->appKey = $config['app.key'];
+ $this->appSecret = $config['app.secret'];
+ $this->userKey = $config['user.key'];
+ $this->userSecret = $config['user.secret'];
+ $this->path = $config['path'] . ( substr($config['path'], -1) !== '/' ? '/' : '' );
+ }
+
+ /**
+ * (non-PHPdoc)
+ * @see \phpbu\Backup\Sync::sync()
+ */
+ public function sync(Target $target, Result $result)
+ {
+ $sourcePath = $target->getPathnameCompressed();
+ $targetPath = $this->path . $target->getFilenameCompressed();
+
+ $copy = new \Barracuda\Copy\API($this->appKey, $this->appSecret, $this->userKey, $this->userSecret);
+
+ try {
+ // open a file to upload
+ $fh = fopen($sourcePath, 'rb');
+ // upload the file in 1MB chunks
+ $parts = array();
+ while ($data = fread($fh, 1024 * 1024)) {
+ $part = $copy->sendData($data);
+ array_push($parts, $part);
+ }
+ fclose($fh);
+ // finalize the file
+ $copy->createFile($targetPath, $parts);
+ } catch (\Exception $e) {
+ throw new Exception($e->getMessage(), null, $e);
+ }
+ $result->debug('upload: done');
+ }
+}
diff --git a/src/Backup/Sync/Dropbox.php b/src/Backup/Sync/Dropbox.php
index 879beedb..b8f4a812 100644
--- a/src/Backup/Sync/Dropbox.php
+++ b/src/Backup/Sync/Dropbox.php
@@ -1,7 +1,6 @@
getPathnameCompressed();
$dropboxPath = $this->path . $target->getFilenameCompressed();
- $client = new dbx\Client($this->token, "phpbu/1.1.0");
+ $client = new \Dropbox\Client($this->token, "phpbu/1.1.0");
- $pathError = dbx\Path::findErrorNonRoot($dropboxPath);
+ $pathError = \Dropbox\Path::findErrorNonRoot($dropboxPath);
if ($pathError !== null) {
throw new Exception('Invalid : ' . $pathError);
}