Skip to content

Commit

Permalink
point:scan from Files
Browse files Browse the repository at this point in the history
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
  • Loading branch information
ArtificialOwl committed Oct 23, 2021
1 parent 42b7ede commit aff0f7c
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 32 deletions.
55 changes: 30 additions & 25 deletions lib/Command/PointScan.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@
use OC\Core\Command\Base;
use OCA\Backup\Db\PointRequest;
use OCA\Backup\Exceptions\RestoringPointNotFoundException;
use OCA\Backup\Model\RestoringPoint;
use OCA\Backup\Service\ChunkService;
use OCA\Backup\Service\OutputService;
use OCA\Backup\Service\PointService;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
Expand Down Expand Up @@ -102,10 +103,9 @@ protected function configure() {
->setDescription(
'Scan a folder containing the data of a restoring point to add it in the list of available restoring point'
)
->addArgument(
'pointId', InputArgument::REQUIRED, 'Id of the restoring point'
)
->addArgument('folder', InputArgument::OPTIONAL, 'Folder to scan');
->addArgument('pointId', InputArgument::OPTIONAL, 'Id of the restoring point', '')
->addOption('owner', '', InputOption::VALUE_REQUIRED, 'owner of the metadata file')
->addOption('file', '', InputOption::VALUE_REQUIRED, 'file_id of the metadata file');
}


Expand All @@ -119,29 +119,34 @@ protected function configure() {
* @throws NotPermittedException
*/
protected function execute(InputInterface $input, OutputInterface $output): int {
$pointId = $input->getArgument('pointId');
$folder = $input->getArgument('folder');

try {
$this->pointService->getRestoringPoint($pointId);
$output->writeln('A restoring point with this Id already exists');

return 0;
} catch (RestoringPointNotFoundException $e) {
$fileId = (int)$input->getOption('file');

if ($fileId > 0) {
$owner = $input->getOption('owner');
if (!$owner) {
throw new InvalidArgumentException('use --owner to specify the owner of the file');
}
$point = $this->pointService->generatePointFromFolder($fileId, $owner);

} else {
$pointId = $input->getArgument('pointId');

if ($pointId === '') {
throw new InvalidArgumentException('use --file or pointId');
}
try {
$this->pointService->getRestoringPoint($pointId);
$output->writeln('A restoring point with this Id already exists');

return 0;
} catch (RestoringPointNotFoundException $e) {
}

$point = $this->pointService->generatePointFromBackupFS($pointId);
}

// $scan = $this->pointService->scanPoint($pointId);

$point = new RestoringPoint();
$point->setId($pointId);
// $this->scanBaseFolder($point);


$point = $this->pointService->generatePointFromBackupFS($pointId);
// TODO: display info about the RP and ask for a confirmation before saving into database

// echo json_encode($point) . "\n";
$this->pointRequest->save($point);
$output->writeln($point->getId() . ' added to the list');

return 0;
}
Expand Down
76 changes: 73 additions & 3 deletions lib/Service/FilesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,18 @@
use ArtificialOwl\MySmallPhpTools\Traits\TStringTools;
use OC;
use OC\Files\Node\File;
use OC\Files\Node\Folder;
use OC\User\NoUserException;
use OCA\Backup\Db\ChangesRequest;
use OCA\Backup\Exceptions\RestoringPointNotFoundException;
use OCA\Backup\Model\ChangedFile;
use OCA\Backup\Model\RestoringData;
use OCA\Backup\Model\RestoringPoint;
use OCP\Files\FileInfo;
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\Lock\LockedException;

/**
Expand Down Expand Up @@ -185,19 +189,26 @@ public function changedFile(ChangedFile $file): void {

/**
* @param int $fileId
* @param string $owner
* @param Folder|null $folder
*
* @return RestoringPoint
* @throws NotPermittedException
* @throws NoUserException
* @throws RestoringPointNotFoundException
*/
public function getPointFromFileId(int $fileId): RestoringPoint {
$nodes = $this->rootFolder->getById($fileId);
public function getPointFromFileId(int $fileId, string $owner, ?Folder &$folder = null): RestoringPoint {
$storage = $this->rootFolder->getUserFolder($owner);
$nodes = $storage->getById($fileId);

foreach ($nodes as $node) {
if ($node->getType() !== FileInfo::TYPE_FILE) {
continue;
}

/** @var File $node */
$folder = $node->getParent();
try {
/** @var File $node */
/** @var RestoringPoint $point */
$point = $this->deserializeJson($node->getContent(), RestoringPoint::class);

Expand All @@ -211,4 +222,63 @@ public function getPointFromFileId(int $fileId): RestoringPoint {

throw new RestoringPointNotFoundException();
}


/**
* @param Folder $node
* @param string $path
*
* @return Folder
*/
public function getPackFolder(Folder $node, string $path): Folder {
foreach (explode('/', $path, 2) as $dir) {
if ($dir === '') {
continue;
}

try {
$sub = $node->get($dir);
if ($sub->getType() !== \OC\Files\FileInfo::TYPE_FOLDER) {
continue;
}
} catch (NotFoundException $e) {
try {
$sub = $node->newFolder($dir);
} catch (NotPermittedException $e) {
continue;
}
}
$node = $sub;
}

return $node;
}


/**
* @param Folder $input
* @param ISimpleFolder $output
* @param string $filename
*
* @throws LockedException
* @throws NotFoundException
* @throws NotPermittedException
*/
public function copyFileToAppData(Folder $input, ISimpleFolder $output, string $filename): void {
/** @var File $orig */
$orig = $input->get($filename);
if ($orig->getType() !== FileInfo::TYPE_FILE) {
return;
}

/** @var File $orig */
try {
$dest = $output->getFile($filename);
} catch (NotFoundException $e) {
$dest = $output->newFile($filename);
}

$dest->putContent($orig->getContent());
}

}
9 changes: 5 additions & 4 deletions lib/Service/PackService.php
Original file line number Diff line number Diff line change
Expand Up @@ -882,16 +882,17 @@ private function packChunkExtract(string $zipName): string {
public function getPackFolder(
RestoringPoint $point,
RestoringChunk $chunk,
string &$path = ''
string &$path = '',
string &$sub = ''
): ISimpleFolder {
if (!$point->hasBaseFolder() || !$point->hasRootFolder()) {
throw new RestoringPointNotInitiatedException('Restoring Point is not initiated');
}

$folder = $point->getBaseFolder();
if ($chunk->getPath() !== '') {
$path = '/' . $folder->getName() . '/' . $chunk->getPath();
// $path = '/' . $folder->getName() . '/' . $chunk->getPath() . '/' . $chunk->getName();
$sub = $chunk->getPath();
if ($sub !== '') {
$path = '/' . $folder->getName() . '/' . $sub;
$root = $point->getRootFolder();
try {
$folder = $root->getFolder($path);
Expand Down
32 changes: 32 additions & 0 deletions lib/Service/PointService.php
Original file line number Diff line number Diff line change
Expand Up @@ -528,13 +528,42 @@ public function loadSqlDump() {
}


public function generatePointFromFolder(int $fileId, string $owner): RestoringPoint {
$point = $this->filesService->getPointFromFileId($fileId, $owner, $folder);
$this->initBaseFolder($point);

$this->metadataService->saveMetadata($point);

foreach ($point->getRestoringData() as $data) {
foreach ($data->getChunks() as $chunk) {
$path = $sub = '';
$dest = $this->packService->getPackFolder($point, $chunk, $path, $sub);
$orig = $this->filesService->getPackFolder($folder, $sub);
if ($chunk->hasParts()) {
foreach ($chunk->getParts() as $part) {
$this->filesService->copyFileToAppData($orig, $dest, $part->getName());
}
} else {
$this->filesService->copyFileToAppData($orig, $dest, $chunk->getFilename());
}
}
}

$this->generateHealth($point);
$this->pointRequest->save($point);
$this->saveMetadata($point);

return $point;
}

/**
* @param string $pointId
*
* @return RestoringPoint
* @throws NotFoundException
* @throws NotPermittedException
* @throws RestoringPointNotFoundException
* @throws SignatoryException
*/
public function generatePointFromBackupFS(string $pointId): RestoringPoint {
$tmp = new RestoringPoint();
Expand All @@ -560,6 +589,9 @@ public function generatePointFromBackupFS(string $pointId): RestoringPoint {
throw new RestoringPointNotFoundException('cannot read ' . MetadataService::METADATA_FILE);
}

$this->generateHealth($point);
$this->pointRequest->save($point);

return $point;
}

Expand Down

0 comments on commit aff0f7c

Please sign in to comment.