|
|
|
@ -7,29 +7,36 @@ |
|
|
|
*/ |
|
|
|
namespace OCA\Files_Trashbin\Command; |
|
|
|
|
|
|
|
use OC\Core\Command\Base; |
|
|
|
use OC\Files\SetupManager; |
|
|
|
use OC\User\LazyUser; |
|
|
|
use OCP\Files\IRootFolder; |
|
|
|
use OCP\Files\NotFoundException; |
|
|
|
use OCP\Files\NotPermittedException; |
|
|
|
use OCP\IDBConnection; |
|
|
|
use OCP\IUser; |
|
|
|
use OCP\IUserBackend; |
|
|
|
use OCP\IUserManager; |
|
|
|
use OCP\Util; |
|
|
|
use Symfony\Component\Console\Command\Command; |
|
|
|
use Symfony\Component\Console\Exception\InvalidOptionException; |
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
|
|
|
use Symfony\Component\Console\Input\InputOption; |
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
|
|
|
|
|
|
|
class CleanUp extends Command { |
|
|
|
class CleanUp extends Base { |
|
|
|
|
|
|
|
public function __construct( |
|
|
|
protected IRootFolder $rootFolder, |
|
|
|
protected IUserManager $userManager, |
|
|
|
protected IDBConnection $dbConnection, |
|
|
|
protected SetupManager $setupManager, |
|
|
|
) { |
|
|
|
parent::__construct(); |
|
|
|
} |
|
|
|
|
|
|
|
protected function configure() { |
|
|
|
protected function configure(): void { |
|
|
|
parent::configure(); |
|
|
|
$this |
|
|
|
->setName('trashbin:cleanup') |
|
|
|
->setDescription('Remove deleted files') |
|
|
|
@ -47,17 +54,18 @@ class CleanUp extends Command { |
|
|
|
} |
|
|
|
|
|
|
|
protected function execute(InputInterface $input, OutputInterface $output): int { |
|
|
|
$users = $input->getArgument('user_id'); |
|
|
|
$userIds = $input->getArgument('user_id'); |
|
|
|
$verbose = $input->getOption('verbose'); |
|
|
|
if (!empty($users) && $input->getOption('all-users')) { |
|
|
|
if (!empty($userIds) && $input->getOption('all-users')) { |
|
|
|
throw new InvalidOptionException('Either specify a user_id or --all-users'); |
|
|
|
} elseif (!empty($users)) { |
|
|
|
foreach ($users as $user) { |
|
|
|
if ($this->userManager->userExists($user)) { |
|
|
|
$output->writeln("Remove deleted files of <info>$user</info>"); |
|
|
|
} elseif (!empty($userIds)) { |
|
|
|
foreach ($userIds as $userId) { |
|
|
|
$user = $this->userManager->get($userId); |
|
|
|
if ($user) { |
|
|
|
$output->writeln("Remove deleted files of <info>$userId</info>"); |
|
|
|
$this->removeDeletedFiles($user, $output, $verbose); |
|
|
|
} else { |
|
|
|
$output->writeln("<error>Unknown user $user</error>"); |
|
|
|
$output->writeln("<error>Unknown user $userId</error>"); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -72,13 +80,14 @@ class CleanUp extends Command { |
|
|
|
$limit = 500; |
|
|
|
$offset = 0; |
|
|
|
do { |
|
|
|
$users = $backend->getUsers('', $limit, $offset); |
|
|
|
foreach ($users as $user) { |
|
|
|
$output->writeln(" <info>$user</info>"); |
|
|
|
$userIds = $backend->getUsers('', $limit, $offset); |
|
|
|
foreach ($userIds as $userId) { |
|
|
|
$output->writeln(" <info>$userId</info>"); |
|
|
|
$user = new LazyUser($userId, $this->userManager, null, $backend); |
|
|
|
$this->removeDeletedFiles($user, $output, $verbose); |
|
|
|
} |
|
|
|
$offset += $limit; |
|
|
|
} while (count($users) >= $limit); |
|
|
|
} while (count($userIds) >= $limit); |
|
|
|
} |
|
|
|
} else { |
|
|
|
throw new InvalidOptionException('Either specify a user_id or --all-users'); |
|
|
|
@ -87,32 +96,33 @@ class CleanUp extends Command { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* remove deleted files for the given user |
|
|
|
* Remove deleted files for the given user. |
|
|
|
*/ |
|
|
|
protected function removeDeletedFiles(string $uid, OutputInterface $output, bool $verbose): void { |
|
|
|
\OC_Util::tearDownFS(); |
|
|
|
\OC_Util::setupFS($uid); |
|
|
|
$path = '/' . $uid . '/files_trashbin'; |
|
|
|
if ($this->rootFolder->nodeExists($path)) { |
|
|
|
protected function removeDeletedFiles(IUser $user, OutputInterface $output, bool $verbose): void { |
|
|
|
$this->setupManager->tearDown(); |
|
|
|
$this->setupManager->setupForUser($user); |
|
|
|
$path = '/' . $user->getUID() . '/files_trashbin'; |
|
|
|
try { |
|
|
|
$node = $this->rootFolder->get($path); |
|
|
|
|
|
|
|
if ($verbose) { |
|
|
|
$output->writeln('Deleting <info>' . Util::humanFileSize($node->getSize()) . "</info> in trash for <info>$uid</info>."); |
|
|
|
} |
|
|
|
$node->delete(); |
|
|
|
if ($this->rootFolder->nodeExists($path)) { |
|
|
|
$output->writeln('<error>Trash folder sill exists after attempting to delete it</error>'); |
|
|
|
return; |
|
|
|
} |
|
|
|
$query = $this->dbConnection->getQueryBuilder(); |
|
|
|
$query->delete('files_trash') |
|
|
|
->where($query->expr()->eq('user', $query->createParameter('uid'))) |
|
|
|
->setParameter('uid', $uid); |
|
|
|
$query->executeStatement(); |
|
|
|
} else { |
|
|
|
} catch (NotFoundException|NotPermittedException) { |
|
|
|
if ($verbose) { |
|
|
|
$output->writeln("No trash found for <info>$uid</info>"); |
|
|
|
$output->writeln("No trash found for <info>{$user->getUID()}</info>"); |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if ($verbose) { |
|
|
|
$output->writeln('Deleting <info>' . Util::humanFileSize($node->getSize()) . "</info> in trash for <info>{$user->getUID()}</info>."); |
|
|
|
} |
|
|
|
$node->delete(); |
|
|
|
if ($this->rootFolder->nodeExists($path)) { |
|
|
|
$output->writeln('<error>Trash folder sill exists after attempting to delete it</error>'); |
|
|
|
return; |
|
|
|
} |
|
|
|
$query = $this->dbConnection->getQueryBuilder(); |
|
|
|
$query->delete('files_trash') |
|
|
|
->where($query->expr()->eq('user', $query->createParameter('uid'))) |
|
|
|
->setParameter('uid', $user->getUID()); |
|
|
|
$query->executeStatement(); |
|
|
|
} |
|
|
|
} |