Skip to content

Commit 57a7c37

Browse files
committed
Add sync local directories to remote
1 parent 6472fd8 commit 57a7c37

File tree

2 files changed

+113
-12
lines changed

2 files changed

+113
-12
lines changed

composer.json

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
{
2-
"name": "spatie/dropbox-api",
3-
"description": "A minimal implementation of Dropbox API v2",
2+
"name": "hamidsamak/dropbox-api",
3+
"description": "A minimal implementation of Dropbox API v2 with syncing",
44
"keywords": [
5-
"spatie",
5+
"hamidsamak",
66
"dropbox-api",
77
"dropbox",
88
"api",
9-
"v2"
9+
"v2",
10+
"sync",
11+
"syncing"
1012
],
11-
"homepage": "https://github.com/spatie/dropbox-api",
13+
"homepage": "https://github.com/hamidsamak/dropbox-api",
1214
"license": "MIT",
1315
"authors": [
1416
{
@@ -22,6 +24,12 @@
2224
"email": "[email protected]",
2325
"homepage": "https://spatie.be",
2426
"role": "Developer"
27+
},
28+
{
29+
"name": "Hamid Samak",
30+
"email": "[email protected]",
31+
"homepage": "https://hamidsamak.ir",
32+
"role": "Developer"
2533
}
2634
],
2735
"require": {

src/Client.php

Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ public function uploadChunked(string $path, $contents, $mode = 'add', $chunkSize
441441

442442
$cursor = $this->uploadChunk(self::UPLOAD_SESSION_START, $stream, $chunkSize, null);
443443

444-
while (! $stream->eof()) {
444+
while (!$stream->eof()) {
445445
$cursor = $this->uploadChunk(self::UPLOAD_SESSION_APPEND, $stream, $chunkSize, $cursor);
446446
}
447447

@@ -601,7 +601,7 @@ protected function normalizePath(string $path): string
601601

602602
$path = trim($path, '/');
603603

604-
return ($path === '') ? '' : '/'.$path;
604+
return ($path === '') ? '' : '/' . $path;
605605
}
606606

607607
protected function getEndpointUrl(string $subdomain, string $endpoint): string
@@ -638,8 +638,8 @@ public function contentEndpointRequest(string $endpoint, array $arguments, $body
638638
} catch (ClientException $exception) {
639639
if (
640640
$isRefreshed
641-
|| ! $this->tokenProvider instanceof RefreshableTokenProvider
642-
|| ! $this->tokenProvider->refresh($exception)
641+
|| !$this->tokenProvider instanceof RefreshableTokenProvider
642+
|| !$this->tokenProvider->refresh($exception)
643643
) {
644644
throw $this->determineException($exception);
645645
}
@@ -662,8 +662,8 @@ public function rpcEndpointRequest(string $endpoint, array $parameters = null, b
662662
} catch (ClientException $exception) {
663663
if (
664664
$isRefreshed
665-
|| ! $this->tokenProvider instanceof RefreshableTokenProvider
666-
|| ! $this->tokenProvider->refresh($exception)
665+
|| !$this->tokenProvider instanceof RefreshableTokenProvider
666+
|| !$this->tokenProvider->refresh($exception)
667667
) {
668668
throw $this->determineException($exception);
669669
}
@@ -763,7 +763,100 @@ protected function getHeadersForBearerToken($token)
763763
protected function getHeadersForCredentials()
764764
{
765765
return [
766-
'Authorization' => 'Basic '.base64_encode("{$this->appKey}:{$this->appSecret}"),
766+
'Authorization' => 'Basic ' . base64_encode("{$this->appKey}:{$this->appSecret}"),
767767
];
768768
}
769+
770+
public function syncLocal(string $localPath, string $remotePath, bool $recursive = false, bool $delete = false)
771+
{
772+
$localPath = rtrim($localPath, '/');
773+
$remotePath = rtrim($remotePath, '/');
774+
775+
if (file_exists($localPath) === false || is_dir($localPath) === false) {
776+
throw new Exception('Local path not found');
777+
}
778+
779+
$localFiles = $this->localFiles($localPath, $recursive);
780+
$remoteFiles = $this->listFolder($remotePath, true);
781+
782+
if (isset($remoteFiles['entries']) && empty($remoteFiles['entries']) === false) {
783+
$uploads = [];
784+
$deletes = [];
785+
786+
foreach ($localFiles as $localFile) {
787+
$localFileRelative = str_replace($localPath, '', $localFile);
788+
$upload = true;
789+
790+
foreach ($remoteFiles['entries'] as $remoteFile) {
791+
792+
if ($remoteFile['path_display'] == $remotePath . $localFileRelative) {
793+
$upload = false;
794+
795+
break;
796+
}
797+
}
798+
799+
if ($upload === true) {
800+
$uploads[$localFile] = $remotePath . $localFileRelative;
801+
}
802+
}
803+
804+
if ($delete === true) {
805+
foreach ($remoteFiles['entries'] as $remoteFile) {
806+
if ($remoteFile['path_display'] == $remotePath) {
807+
continue;
808+
}
809+
810+
$delete_file = true;
811+
812+
foreach ($localFiles as $localFile) {
813+
$localFileRelative = str_replace($localPath, '', $localFile);
814+
815+
if ($remoteFile['path_display'] == $remotePath . $localFileRelative) {
816+
$delete_file = false;
817+
818+
break;
819+
}
820+
}
821+
822+
if ($delete_file === true) {
823+
$deletes[] = $remoteFile['path_display'];
824+
}
825+
}
826+
}
827+
828+
foreach ($uploads as $absolutePath => $relativePath) {
829+
if (is_file($absolutePath)) {
830+
$contents = file_get_contents($absolutePath);
831+
832+
if (empty($contents) === false) {
833+
$this->upload($relativePath, $contents);
834+
}
835+
} else if (is_dir($absolutePath)) {
836+
$this->createFolder($relativePath);
837+
}
838+
}
839+
840+
foreach ($deletes as $absolutePath => $relativePath) {
841+
$this->delete($relativePath);
842+
}
843+
}
844+
845+
return true;
846+
}
847+
848+
private function localFiles(string $path, bool $recursive = false)
849+
{
850+
$files = [];
851+
852+
foreach (glob($path . DIRECTORY_SEPARATOR . '*') as $file) {
853+
if (is_file($file)) {
854+
$files[] = $file;
855+
} else if (is_dir($file) && $recursive === true) {
856+
$files = array_merge($files, [$file], $this->localFiles($file));
857+
}
858+
}
859+
860+
return $files;
861+
}
769862
}

0 commit comments

Comments
 (0)