From 51d228932fe6adbd29bdfe8c52d71ba03bf82069 Mon Sep 17 00:00:00 2001 From: Côme Chilliet Date: Tue, 15 Mar 2022 11:37:55 +0100 Subject: Add trashbin migrator to export and import trashbin data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- apps/files_trashbin/lib/AppInfo/Application.php | 13 ++- .../lib/UserMigration/TrashbinMigrator.php | 130 +++++++++++++++++++++ 2 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php (limited to 'apps/files_trashbin/lib') diff --git a/apps/files_trashbin/lib/AppInfo/Application.php b/apps/files_trashbin/lib/AppInfo/Application.php index 5f56b9ba1ea..41466a865ac 100644 --- a/apps/files_trashbin/lib/AppInfo/Application.php +++ b/apps/files_trashbin/lib/AppInfo/Application.php @@ -30,17 +30,20 @@ use OCA\Files_Trashbin\Capabilities; use OCA\Files_Trashbin\Expiration; use OCA\Files_Trashbin\Trash\ITrashManager; use OCA\Files_Trashbin\Trash\TrashManager; -use OCP\App\IAppManager; +use OCA\Files_Trashbin\UserMigration\TrashbinMigrator; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; +use OCP\App\IAppManager; use OCP\ILogger; use OCP\IServerContainer; class Application extends App implements IBootstrap { + public const APP_ID = 'files_trashbin'; + public function __construct(array $urlParams = []) { - parent::__construct('files_trashbin', $urlParams); + parent::__construct(self::APP_ID, $urlParams); } public function register(IRegistrationContext $context): void { @@ -50,6 +53,8 @@ class Application extends App implements IBootstrap { $context->registerServiceAlias(ITrashManager::class, TrashManager::class); /** Register $principalBackend for the DAV collection */ $context->registerServiceAlias('principalBackend', Principal::class); + + $context->registerUserMigrator(TrashbinMigrator::class); } public function boot(IBootContext $context): void { @@ -65,10 +70,10 @@ class Application extends App implements IBootstrap { \OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Files_Trashbin\Trashbin', 'ensureFileScannedHook'); \OCA\Files\App::getNavigationManager()->add(function () { - $l = \OC::$server->getL10N('files_trashbin'); + $l = \OC::$server->getL10N(self::APP_ID); return [ 'id' => 'trashbin', - 'appname' => 'files_trashbin', + 'appname' => self::APP_ID, 'script' => 'list.php', 'order' => 50, 'name' => $l->t('Deleted files'), diff --git a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php new file mode 100644 index 00000000000..3f3e674b875 --- /dev/null +++ b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php @@ -0,0 +1,130 @@ + + * + * @author Côme Chilliet + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 program. If not, see . + * + */ + +namespace OCA\Files_Trashbin\UserMigration; + +use OCA\Files_Trashbin\AppInfo\Application; +use OCP\Files\IRootFolder; +use OCP\Files\NotFoundException; +use OCP\IUser; +use OCP\UserMigration\IExportDestination; +use OCP\UserMigration\IImportSource; +use OCP\UserMigration\IMigrator; +use OCP\UserMigration\TMigratorBasicVersionHandling; +use OCP\UserMigration\UserMigrationException; +use Symfony\Component\Console\Output\OutputInterface; +use OCP\IDBConnection; + +class TrashbinMigrator implements IMigrator { + + use TMigratorBasicVersionHandling; + + protected const PATH_FILES = Application::APP_ID.'/files'; + protected const PATH_LOCATIONS = Application::APP_ID.'/locations.json'; + + protected IRootFolder $root; + + protected IDBConnection $dbc; + + public function __construct( + IRootFolder $rootFolder, + IDBConnection $dbc + ) { + $this->root = $rootFolder; + $this->dbc = $dbc; + } + + /** + * {@inheritDoc} + */ + public function export(IUser $user, IExportDestination $exportDestination, OutputInterface $output): void { + $output->writeln('Exporting trashbin into ' . Application::APP_ID . '…'); + + $uid = $user->getUID(); + + try { + $trashbinFolder = $this->root->get('/'.$uid.'/files_trashbin'); + $output->writeln("Exporting trashbin…"); + if ($exportDestination->copyFolder($trashbinFolder, static::PATH_FILES) === false) { + throw new UserMigrationException("Could not export trashbin."); + } + $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($uid); + if ($exportDestination->addFileContents(static::PATH_LOCATIONS, json_encode($originalLocations)) === false) { + throw new UserMigrationException("Could not export trashbin."); + } + } catch (NotFoundException $e) { + $output->writeln("No trashbin to export…"); + } + } + + /** + * {@inheritDoc} + */ + public function import(IUser $user, IImportSource $importSource, OutputInterface $output): void { + if ($importSource->getMigratorVersion(static::class) === null) { + $output->writeln('No version for ' . static::class . ', skipping import…'); + return; + } + + $output->writeln('Importing trashbin from ' . Application::APP_ID . '…'); + + $uid = $user->getUID(); + + if ($importSource->pathExists(static::PATH_FILES)) { + try { + $trashbinFolder = $this->root->get('/'.$uid.'/files_trashbin'); + } catch (NotFoundException $e) { + $trashbinFolder = $this->root->newFolder('/'.$uid.'/files_trashbin'); + } + $output->writeln("Importing trashbin files…"); + if ($importSource->copyToFolder($trashbinFolder, static::PATH_FILES) === false) { + throw new UserMigrationException("Could not import trashbin."); + } + $locations = json_decode($importSource->getFileContents(static::PATH_LOCATIONS), true, 512, JSON_THROW_ON_ERROR); + $insert = $this->dbc->getQueryBuilder(); + $insert->insert('files_trash') + ->values([ + 'id' => $insert->createParameter('id'), + 'timestamp' => $insert->createParameter('timestamp'), + 'location' => $insert->createParameter('location'), + 'user' => $insert->createNamedParameter($uid), + ]); + foreach ($locations as $id => $fileLocations) { + foreach ($fileLocations as $timestamp => $location) { + $insert + ->setParameter('id', $id) + ->setParameter('timestamp', $timestamp) + ->setParameter('location', $location) + ; + + $insert->executeStatement(); + } + } + } else { + $output->writeln("No trashbin to import…"); + } + } +} -- cgit v1.2.3 From 865ac4b6e02b59cc69df587a6ba1d3c92969a514 Mon Sep 17 00:00:00 2001 From: Côme Chilliet Date: Thu, 17 Mar 2022 14:49:29 +0100 Subject: Rename $insert var to $qb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- .../lib/UserMigration/TrashbinMigrator.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'apps/files_trashbin/lib') diff --git a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php index 3f3e674b875..c416ef0f810 100644 --- a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php +++ b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php @@ -104,23 +104,23 @@ class TrashbinMigrator implements IMigrator { throw new UserMigrationException("Could not import trashbin."); } $locations = json_decode($importSource->getFileContents(static::PATH_LOCATIONS), true, 512, JSON_THROW_ON_ERROR); - $insert = $this->dbc->getQueryBuilder(); - $insert->insert('files_trash') + $qb = $this->dbc->getQueryBuilder(); + $qb->insert('files_trash') ->values([ - 'id' => $insert->createParameter('id'), - 'timestamp' => $insert->createParameter('timestamp'), - 'location' => $insert->createParameter('location'), - 'user' => $insert->createNamedParameter($uid), + 'id' => $qb->createParameter('id'), + 'timestamp' => $qb->createParameter('timestamp'), + 'location' => $qb->createParameter('location'), + 'user' => $qb->createNamedParameter($uid), ]); foreach ($locations as $id => $fileLocations) { foreach ($fileLocations as $timestamp => $location) { - $insert + $qb ->setParameter('id', $id) ->setParameter('timestamp', $timestamp) ->setParameter('location', $location) ; - $insert->executeStatement(); + $qb->executeStatement(); } } } else { -- cgit v1.2.3 From 53c731d8f975ec8b0e577f7e348873a8833a1b38 Mon Sep 17 00:00:00 2001 From: Côme Chilliet Date: Tue, 22 Mar 2022 09:21:18 +0100 Subject: Rename PATH constants to show if folder or file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'apps/files_trashbin/lib') diff --git a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php index c416ef0f810..fad8103e796 100644 --- a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php +++ b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php @@ -42,8 +42,8 @@ class TrashbinMigrator implements IMigrator { use TMigratorBasicVersionHandling; - protected const PATH_FILES = Application::APP_ID.'/files'; - protected const PATH_LOCATIONS = Application::APP_ID.'/locations.json'; + protected const PATH_FILES_FOLDER = Application::APP_ID.'/files'; + protected const PATH_LOCATIONS_FILE = Application::APP_ID.'/locations.json'; protected IRootFolder $root; @@ -68,11 +68,11 @@ class TrashbinMigrator implements IMigrator { try { $trashbinFolder = $this->root->get('/'.$uid.'/files_trashbin'); $output->writeln("Exporting trashbin…"); - if ($exportDestination->copyFolder($trashbinFolder, static::PATH_FILES) === false) { + if ($exportDestination->copyFolder($trashbinFolder, static::PATH_FILES_FOLDER) === false) { throw new UserMigrationException("Could not export trashbin."); } $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($uid); - if ($exportDestination->addFileContents(static::PATH_LOCATIONS, json_encode($originalLocations)) === false) { + if ($exportDestination->addFileContents(static::PATH_LOCATIONS_FILE, json_encode($originalLocations)) === false) { throw new UserMigrationException("Could not export trashbin."); } } catch (NotFoundException $e) { @@ -93,17 +93,17 @@ class TrashbinMigrator implements IMigrator { $uid = $user->getUID(); - if ($importSource->pathExists(static::PATH_FILES)) { + if ($importSource->pathExists(static::PATH_FILES_FOLDER)) { try { $trashbinFolder = $this->root->get('/'.$uid.'/files_trashbin'); } catch (NotFoundException $e) { $trashbinFolder = $this->root->newFolder('/'.$uid.'/files_trashbin'); } $output->writeln("Importing trashbin files…"); - if ($importSource->copyToFolder($trashbinFolder, static::PATH_FILES) === false) { + if ($importSource->copyToFolder($trashbinFolder, static::PATH_FILES_FOLDER) === false) { throw new UserMigrationException("Could not import trashbin."); } - $locations = json_decode($importSource->getFileContents(static::PATH_LOCATIONS), true, 512, JSON_THROW_ON_ERROR); + $locations = json_decode($importSource->getFileContents(static::PATH_LOCATIONS_FILE), true, 512, JSON_THROW_ON_ERROR); $qb = $this->dbc->getQueryBuilder(); $qb->insert('files_trash') ->values([ -- cgit v1.2.3 From ecbcfca98aff39857e3fac622a667b7696cb0087 Mon Sep 17 00:00:00 2001 From: Côme Chilliet Date: Thu, 24 Mar 2022 11:04:09 +0100 Subject: Improve wording of output for trashbin migrator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apps/files_trashbin/lib') diff --git a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php index fad8103e796..578d08291a6 100644 --- a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php +++ b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php @@ -67,7 +67,7 @@ class TrashbinMigrator implements IMigrator { try { $trashbinFolder = $this->root->get('/'.$uid.'/files_trashbin'); - $output->writeln("Exporting trashbin…"); + $output->writeln("Exporting trashbin files…"); if ($exportDestination->copyFolder($trashbinFolder, static::PATH_FILES_FOLDER) === false) { throw new UserMigrationException("Could not export trashbin."); } -- cgit v1.2.3 From 7fa8b2eef7795aeb770bd3679bfbd30438388576 Mon Sep 17 00:00:00 2001 From: Côme Chilliet Date: Thu, 24 Mar 2022 17:31:21 +0100 Subject: Add a guard to check that trashbin folder is a folder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'apps/files_trashbin/lib') diff --git a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php index 578d08291a6..0aa41c1954f 100644 --- a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php +++ b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php @@ -27,8 +27,10 @@ declare(strict_types=1); namespace OCA\Files_Trashbin\UserMigration; use OCA\Files_Trashbin\AppInfo\Application; +use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; +use OCP\IDBConnection; use OCP\IUser; use OCP\UserMigration\IExportDestination; use OCP\UserMigration\IImportSource; @@ -36,7 +38,6 @@ use OCP\UserMigration\IMigrator; use OCP\UserMigration\TMigratorBasicVersionHandling; use OCP\UserMigration\UserMigrationException; use Symfony\Component\Console\Output\OutputInterface; -use OCP\IDBConnection; class TrashbinMigrator implements IMigrator { @@ -67,6 +68,9 @@ class TrashbinMigrator implements IMigrator { try { $trashbinFolder = $this->root->get('/'.$uid.'/files_trashbin'); + if (!$trashbinFolder instanceof Folder) { + throw new UserMigrationException('Could not export trashbin, /'.$uid.'/files_trashbin is not a folder'); + } $output->writeln("Exporting trashbin files…"); if ($exportDestination->copyFolder($trashbinFolder, static::PATH_FILES_FOLDER) === false) { throw new UserMigrationException("Could not export trashbin."); @@ -96,6 +100,9 @@ class TrashbinMigrator implements IMigrator { if ($importSource->pathExists(static::PATH_FILES_FOLDER)) { try { $trashbinFolder = $this->root->get('/'.$uid.'/files_trashbin'); + if (!$trashbinFolder instanceof Folder) { + throw new UserMigrationException('Could not import trashbin, /'.$uid.'/files_trashbin is not a folder'); + } } catch (NotFoundException $e) { $trashbinFolder = $this->root->newFolder('/'.$uid.'/files_trashbin'); } -- cgit v1.2.3