Skip to content

Commit ce44598

Browse files
AxelPALsebastianfeldmann
authored andcommitted
YandexDisk implementation
1 parent 356656d commit ce44598

File tree

8 files changed

+783
-2
lines changed

8 files changed

+783
-2
lines changed

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@
5555
"softlayer/objectstorage": "dev-master",
5656
"vlucas/phpdotenv": "~2.4",
5757
"google/apiclient":"^2.0",
58-
"php-opencloud/openstack": "^3.0"
58+
"php-opencloud/openstack": "^3.0",
59+
"arhitector/yandex": "^2.0"
5960
},
6061
"suggest": {
6162
"sebastianfeldmann/ftp": "Require ~0.9 to sync to an FTP server",
@@ -65,7 +66,8 @@
6566
"softlayer/objectstorage": "Require 'dev-master' to sync to Softlayer",
6667
"php-opencloud/openstack": "Require ~3.0 to sync to OpenStack",
6768
"vlucas/phpdotenv": "Require ~2.4 to use Dotenv adapter",
68-
"google/apiclient":"Require ~2.0 to sync to Google Drive"
69+
"google/apiclient":"Require ~2.0 to sync to Google Drive",
70+
"arhitector/yandex":"Require ~2.0 to sync to Yandex Disk"
6971
},
7072
"bin": [
7173
"phpbu"
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace phpbu\App\Backup\Collector;
4+
5+
use Arhitector\Yandex\Disk;
6+
use phpbu\App\Backup\Collector;
7+
use phpbu\App\Backup\File;
8+
use phpbu\App\Backup\Path;
9+
use phpbu\App\Backup\Target;
10+
11+
/**
12+
* YandexDisk class.
13+
*
14+
* @package phpbu
15+
* @subpackage Backup
16+
* @author Sebastian Feldmann <sebastian@phpbu.de>
17+
* @author Alexander Palchikov AxelPAL <axelpal@gmail.com>
18+
* @copyright Sebastian Feldmann <sebastian@phpbu.de>
19+
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
20+
* @link http://phpbu.de/
21+
*/
22+
class YandexDisk extends Remote implements Collector
23+
{
24+
/**
25+
* @var Disk
26+
*/
27+
protected $disk;
28+
29+
/**
30+
* OpenStack constructor.
31+
*
32+
* @param Target $target
33+
* @param Path $path
34+
* @param Disk $disk
35+
*/
36+
public function __construct(Target $target, Path $path, Disk $disk)
37+
{
38+
$this->setUp($target, $path);
39+
$this->disk = $disk;
40+
}
41+
42+
/**
43+
* Collect all created backups.
44+
*/
45+
protected function collectBackups()
46+
{
47+
$items = $this->disk->getResource($this->path->getPathThatIsNotChanging());
48+
foreach ($items->toArray()['items'] as $item) {
49+
if (($item instanceof Disk\Resource\Closed) && $this->isFileMatch($item->getPath())) {
50+
$file = new File\YandexDisk($this->disk, $item);
51+
$index = $this->getFileIndex($file);
52+
$this->files[$index] = $file;
53+
}
54+
}
55+
}
56+
}

src/Backup/File/YandexDisk.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace phpbu\App\Backup\File;
4+
5+
use Arhitector\Yandex\Disk;
6+
use Arhitector\Yandex\Disk\Resource\Closed;
7+
use InvalidArgumentException;
8+
use phpbu\App\Exception;
9+
10+
/**
11+
* YandexDisk class.
12+
*
13+
* @package phpbu
14+
* @subpackage Backup
15+
* @author Sebastian Feldmann <sebastian@phpbu.de>
16+
* @author Alexander Palchikov AxelPAL <axelpal@gmail.com>
17+
* @copyright Sebastian Feldmann <sebastian@phpbu.de>
18+
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
19+
* @link http://phpbu.de/
20+
*/
21+
class YandexDisk extends Remote
22+
{
23+
/**
24+
* YandexDisk api client.
25+
*
26+
* @var Disk
27+
*/
28+
protected $disk;
29+
30+
/**
31+
* YandexDisk constructor.
32+
*
33+
* @param Disk $disk
34+
* @param Closed $yandexFile
35+
*/
36+
public function __construct(Disk $disk, Closed $yandexFile)
37+
{
38+
$this->disk = $disk;
39+
$this->filename = $yandexFile->get('name');
40+
$this->pathname = $yandexFile->get('path');
41+
$this->size = $yandexFile->get('size');
42+
$this->lastModified = strtotime($yandexFile->get('modified'));
43+
}
44+
45+
/**
46+
* Deletes the file on YandexDisk.
47+
*
48+
* @throws Exception
49+
*/
50+
public function unlink()
51+
{
52+
try {
53+
$item = $this->disk->getResource($this->pathname);
54+
$item->delete($this->pathname);
55+
} catch (InvalidArgumentException $e) {
56+
throw new Exception($e->getMessage());
57+
}
58+
}
59+
}

src/Backup/Sync/YandexDisk.php

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<?php
2+
3+
namespace phpbu\App\Backup\Sync;
4+
5+
use Arhitector\Yandex\Disk;
6+
use phpbu\App\Backup\Collector;
7+
use phpbu\App\Backup\Sync;
8+
use phpbu\App\Backup\Target;
9+
use phpbu\App\Result;
10+
use phpbu\App\Util\Arr;
11+
use phpbu\App\Util\Path;
12+
13+
/**
14+
* Yandex.Disk
15+
*
16+
* @package phpbu
17+
* @subpackage Backup
18+
* @author Sebastian Feldmann <sebastian@phpbu.de>
19+
* @author Alexander Palchikov AxelPAL <axelpal@gmail.com>
20+
* @copyright Sebastian Feldmann <sebastian@phpbu.de>
21+
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
22+
* @link http://phpbu.de/
23+
*/
24+
class YandexDisk implements Sync\Simulator
25+
{
26+
use Cleanable;
27+
/**
28+
* API access token
29+
* Goto https://oauth.yandex.ru/client/new
30+
* create your app
31+
* - Check all Disks permissions
32+
* - generate access token:
33+
* 1) Goto https://oauth.yandex.ru/authorize?response_type=token&client_id=APP_ID (replace APP_ID with ID giving to you)
34+
* 2) Then you should get token parameter from GET-parameters of opened page
35+
*
36+
* @var string
37+
*/
38+
protected $token;
39+
40+
/**
41+
* Remote path
42+
*
43+
* @var \phpbu\App\Backup\Path
44+
*/
45+
protected $path;
46+
47+
/**
48+
* @var Disk
49+
*/
50+
protected $disk;
51+
52+
/**
53+
* Unix timestamp of generating path from placeholder.
54+
*
55+
* @var int
56+
*/
57+
protected $time;
58+
59+
/**
60+
* (non-PHPDoc)
61+
*
62+
* @param array $config
63+
* @throws Exception
64+
* @throws \phpbu\App\Exception
65+
* @see \phpbu\App\Backup\Sync::setup()
66+
*/
67+
public function setup(array $config): void
68+
{
69+
if (!class_exists(Disk::class)) {
70+
throw new Exception('Yandex.Disk sdk not loaded: use composer to install "arhitector/yandex"');
71+
}
72+
if (!Arr::isSetAndNotEmptyString($config, 'token')) {
73+
throw new Exception('API access token is mandatory');
74+
}
75+
if (!Arr::isSetAndNotEmptyString($config, 'path')) {
76+
throw new Exception('yandex.disk path is mandatory');
77+
}
78+
$this->token = $config['token'];
79+
$this->path = new \phpbu\App\Backup\Path(Path::withLeadingSlash($config['path']), time());
80+
81+
$this->setUpCleanable($config);
82+
}
83+
84+
/**
85+
* (non-PHPDoc)
86+
*
87+
* @param Target $target
88+
* @param Result $result
89+
* @throws Exception
90+
* @see \phpbu\App\Backup\Sync::sync()
91+
*/
92+
public function sync(Target $target, Result $result): void
93+
{
94+
$sourcePath = $target->getPathname();
95+
$yandexDiskPath = $this->path . '/' . $target->getFilename();
96+
$this->createDisk();
97+
98+
$size = null;
99+
if (stream_is_local($sourcePath) && file_exists($sourcePath)) {
100+
$size = filesize($sourcePath);
101+
}
102+
103+
try {
104+
$this->createFolders();
105+
$file = $this->createDisk()->getResource($yandexDiskPath);
106+
$file->upload($sourcePath, true);
107+
if ($file->has()) {
108+
$result->debug('upload: done (' . $size . ')');
109+
} else {
110+
$result->debug('upload: error while uploading file');
111+
}
112+
$this->cleanup($target, $result);
113+
} catch (\Exception $e) {
114+
throw new Exception($e->getMessage(), null, $e);
115+
}
116+
}
117+
118+
private function createFolders(): void
119+
{
120+
$folderPath = '';
121+
$folderPaths = explode('/', $this->path->getPath());
122+
if (!empty($folderPaths)) {
123+
foreach ($folderPaths as $folderPathPart) {
124+
if (!empty($folderPathPart)) {
125+
$folderPath .= "/$folderPathPart";
126+
$file = $this->createDisk()->getResource($folderPath);
127+
if (!$file->has()) {
128+
$file->create();
129+
}
130+
}
131+
}
132+
}
133+
}
134+
135+
/**
136+
* Simulate the sync execution.
137+
*
138+
* @param Target $target
139+
* @param Result $result
140+
*/
141+
public function simulate(Target $target, Result $result): void
142+
{
143+
$result->debug('sync backup to yandex disk' . PHP_EOL);
144+
145+
$this->isSimulation = true;
146+
$this->simulateRemoteCleanup($target, $result);
147+
}
148+
149+
/**
150+
* Creates the YandexDisk collector.
151+
*
152+
* @param Target $target
153+
* @return Collector
154+
*/
155+
protected function createCollector(Target $target): Collector
156+
{
157+
$collector = new Collector\YandexDisk($target, $this->path, $this->createDisk());
158+
$collector->setSimulation($this->isSimulation);
159+
160+
return $collector;
161+
}
162+
163+
/**
164+
* Create a YandexDisk api client.
165+
*
166+
* @return Disk
167+
*/
168+
protected function createDisk(): Disk
169+
{
170+
if (!$this->disk) {
171+
$this->disk = new Disk($this->token);
172+
}
173+
return $this->disk;
174+
}
175+
}

src/Factory.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class Factory
7070
'sftp' => '\\phpbu\\App\\Backup\\Sync\\Sftp',
7171
'softlayer' => '\\phpbu\\App\\Backup\\Sync\\SoftLayer',
7272
'openstack' => '\\phpbu\\App\\Backup\\Sync\\OpenStack',
73+
'yandex-disk' => '\\phpbu\\App\\Backup\\Sync\\YandexDisk',
7374
],
7475
'cleaner' => [
7576
'capacity' => '\\phpbu\\App\\Backup\\Cleaner\\Capacity',

0 commit comments

Comments
 (0)