diff options
author | Robin Appelman <robin@icewind.nl> | 2023-04-03 17:28:47 +0200 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2023-04-03 17:30:57 +0200 |
commit | 013eedabbd42fef231b1dc95993460ef5621048c (patch) | |
tree | 66c937acf8a1ea223cdc74d930e726505d7101e8 /core | |
parent | 5024f295dcfdf850d2d95f419bcf122bf08be5c8 (diff) | |
download | nextcloud-server-013eedabbd42fef231b1dc95993460ef5621048c.tar.gz nextcloud-server-013eedabbd42fef231b1dc95993460ef5621048c.zip |
add command to generate a preview for a file
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'core')
-rw-r--r-- | core/Command/Preview/Generate.php | 141 | ||||
-rw-r--r-- | core/register_command.php | 1 |
2 files changed, 142 insertions, 0 deletions
diff --git a/core/Command/Preview/Generate.php b/core/Command/Preview/Generate.php new file mode 100644 index 00000000000..24e34c1bd76 --- /dev/null +++ b/core/Command/Preview/Generate.php @@ -0,0 +1,141 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2023 Robin Appelman <robin@icewind.nl> + * + * @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 <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Core\Command\Preview; + +use OCP\Files\Config\IUserMountCache; +use OCP\Files\IRootFolder; +use OCP\Files\Node; +use OCP\Files\File; +use OCP\Files\NotFoundException; +use OCP\IPreview; +use Symfony\Component\Console\Command\Command; +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 Generate extends Command { + private IRootFolder $rootFolder; + private IUserMountCache $userMountCache; + private IPreview $previewManager; + + public function __construct(IRootFolder $rootFolder, IUserMountCache $userMountCache, IPreview $previewManager) { + $this->rootFolder = $rootFolder; + $this->userMountCache = $userMountCache; + $this->previewManager = $previewManager; + + parent::__construct(); + } + + protected function configure() { + $this + ->setName('preview:generate') + ->setDescription('generate a preview for a file') + ->addArgument("file", InputArgument::REQUIRED, "path or fileid of the file to generate the preview for") + ->addOption("size", "s", InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, "size to generate the preview for in pixels, defaults to 64x64", ["64x64"]) + ->addOption("crop", "c", InputOption::VALUE_NONE, "crop the previews instead of maintaining aspect ratio") + ->addOption("mode", "m", InputOption::VALUE_REQUIRED, "mode for generating uncropped previews, 'cover' or 'fill'", IPreview::MODE_FILL); + } + + protected function execute(InputInterface $input, OutputInterface $output): int { + $fileInput = $input->getArgument("file"); + $sizes = $input->getOption("size"); + $sizes = array_map(function (string $size) use ($output, &$error) { + if (str_contains($size, 'x')) { + $sizeParts = explode('x', $size, 2); + } else { + $sizeParts = [$size, $size]; + } + if (!is_numeric($sizeParts[0]) || !is_numeric($sizeParts[1])) { + $output->writeln("<error>Invalid size $size</error>"); + return null; + } + + return array_map("intval", $sizeParts); + }, $sizes); + if (in_array(null, $sizes)) { + return 1; + } + + $mode = $input->getOption("mode"); + if ($mode !== IPreview::MODE_FILL && $mode !== IPreview::MODE_COVER) { + $output->writeln("<error>Invalid mode $mode</error>"); + return 1; + } + $crop = $input->getOption("crop"); + $file = $this->getFile($fileInput); + if (!$file) { + $output->writeln("<error>File $fileInput not found</error>"); + return 1; + } + if (!$file instanceof File) { + $output->writeln("<error>Can't generate previews for folders</error>"); + return 1; + } + + if (!$this->previewManager->isAvailable($file)) { + $output->writeln("<error>No preview generator available for file of type" . $file->getMimetype() . "</error>"); + return 1; + } + + $specifications = array_map(function (array $sizes) use ($crop, $mode) { + return [ + 'width' => $sizes[0], + 'height' => $sizes[1], + 'crop' => $crop, + 'mode' => $mode, + ]; + }, $sizes); + + $this->previewManager->generatePreviews($file, $specifications); + if (count($specifications) > 1) { + $output->writeln("generated <info>" . count($specifications) . "</info> previews"); + } else { + $output->writeln("preview generated"); + } + return 0; + } + + private function getFile(string $fileInput): ?Node { + if (is_numeric($fileInput)) { + $mounts = $this->userMountCache->getMountsForFileId((int)$fileInput); + if (!$mounts) { + return null; + } + $mount = $mounts[0]; + $userFolder = $this->rootFolder->getUserFolder($mount->getUser()->getUID()); + $nodes = $userFolder->getById((int)$fileInput); + if (!$nodes) { + return null; + } + return $nodes[0]; + } else { + try { + return $this->rootFolder->get($fileInput); + } catch (NotFoundException $e) { + return null; + } + } + } +} diff --git a/core/register_command.php b/core/register_command.php index df008402076..3c099519808 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -175,6 +175,7 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) { )); $application->add(\OC::$server->query(OC\Core\Command\Maintenance\RepairShareOwnership::class)); + $application->add(\OC::$server->get(\OC\Core\Command\Preview\Generate::class)); $application->add(\OC::$server->query(\OC\Core\Command\Preview\Repair::class)); $application->add(\OC::$server->query(\OC\Core\Command\Preview\ResetRenderedTexts::class)); |