Merge pull request #3491 from nextcloud/fix/preview

This commit is contained in:
Julius Härtl 2024-02-22 19:47:31 +01:00 коммит произвёл GitHub
Родитель b784eeb24d 6da08e6eb5
Коммит 6d48310b9b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
10 изменённых файлов: 60 добавлений и 134 удалений

Просмотреть файл

@ -142,15 +142,15 @@ class AppConfig {
} }
public function getCollaboraUrlPublic(): string { public function getCollaboraUrlPublic(): string {
return $this->config->getAppValue(Application::APPNAME, self::PUBLIC_WOPI_URL, $this->getCollaboraUrlInternal()); return rtrim($this->config->getAppValue(Application::APPNAME, self::PUBLIC_WOPI_URL, $this->getCollaboraUrlInternal()), '/');
} }
public function getCollaboraUrlInternal(): string { public function getCollaboraUrlInternal(): string {
return $this->config->getAppValue(Application::APPNAME, self::WOPI_URL, ''); return rtrim($this->config->getAppValue(Application::APPNAME, self::WOPI_URL, ''), '/');
} }
public function getNextcloudUrl(): string { public function getNextcloudUrl(): string {
return $this->config->getAppValue(Application::APPNAME, self::WOPI_CALLBACK_URL, ''); return rtrim($this->config->getAppValue(Application::APPNAME, self::WOPI_CALLBACK_URL, ''), '/');
} }
public function getDisableCertificateValidation(): bool { public function getDisableCertificateValidation(): bool {

Просмотреть файл

@ -61,7 +61,6 @@ use OCP\Files\Template\ITemplateManager;
use OCP\Files\Template\TemplateFileCreator; use OCP\Files\Template\TemplateFileCreator;
use OCP\IConfig; use OCP\IConfig;
use OCP\IL10N; use OCP\IL10N;
use OCP\IPreview;
use OCP\Preview\BeforePreviewFetchedEvent; use OCP\Preview\BeforePreviewFetchedEvent;
use OCP\Security\CSP\AddContentSecurityPolicyEvent; use OCP\Security\CSP\AddContentSecurityPolicyEvent;
use OCP\Security\FeaturePolicy\AddFeaturePolicyEvent; use OCP\Security\FeaturePolicy\AddFeaturePolicyEvent;
@ -92,6 +91,13 @@ class Application extends App implements IBootstrap {
'getPathForToken', 'getPathForToken',
'getWopiForToken', 'getWopiForToken',
]); ]);
$context->registerPreviewProvider(EMF::class, EMF::MIMETYPE_REGEX);
$context->registerPreviewProvider(MSExcel::class, MSExcel::MIMETYPE_REGEX);
$context->registerPreviewProvider(MSWord::class, MSWord::MIMETYPE_REGEX);
$context->registerPreviewProvider(OOXML::class, OOXML::MIMETYPE_REGEX);
$context->registerPreviewProvider(OpenDocument::class, OpenDocument::MIMETYPE_REGEX);
$context->registerPreviewProvider(Pdf::class, Pdf::MIMETYPE_REGEX);
} }
public function boot(IBootContext $context): void { public function boot(IBootContext $context): void {
@ -153,43 +159,9 @@ class Application extends App implements IBootstrap {
}); });
}); });
$this->registerProvider();
$this->checkAndEnableCODEServer(); $this->checkAndEnableCODEServer();
} }
public function registerProvider() {
$container = $this->getContainer();
/** @var IPreview $previewManager */
$previewManager = $container->get(IPreview::class);
$previewManager->registerProvider('/application\/vnd.ms-excel/', function () use ($container) {
return $container->get(MSExcel::class);
});
$previewManager->registerProvider('/application\/msword/', function () use ($container) {
return $container->get(MSWord::class);
});
$previewManager->registerProvider('/application\/vnd.openxmlformats-officedocument.*/', function () use ($container) {
return $container->get(OOXML::class);
});
$previewManager->registerProvider('/application\/vnd.oasis.opendocument.*/', function () use ($container) {
return $container->get(OpenDocument::class);
});
$previewManager->registerProvider('/image\/emf/', function () use ($container) {
return $container->get(EMF::class);
});
if (!$previewManager->isMimeSupported('application/pdf')) {
$previewManager->registerProvider('/application\/pdf/', function () use ($container) {
return $container->get(Pdf::class);
});
}
}
public function checkAndEnableCODEServer() { public function checkAndEnableCODEServer() {
// Supported only on Linux OS, and x86_64 & ARM64 platforms // Supported only on Linux OS, and x86_64 & ARM64 platforms
$supportedArchs = ['x86_64', 'aarch64']; $supportedArchs = ['x86_64', 'aarch64'];

Просмотреть файл

@ -26,10 +26,11 @@ declare(strict_types=1);
namespace OCA\Richdocuments\Preview; namespace OCA\Richdocuments\Preview;
class EMF extends Office { class EMF extends Office {
public const MIMETYPE_REGEX = '/image\/emf/';
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function getMimeType() { public function getMimeType(): string {
return '/image\/emf/'; return self::MIMETYPE_REGEX;
} }
} }

Просмотреть файл

@ -22,10 +22,11 @@
namespace OCA\Richdocuments\Preview; namespace OCA\Richdocuments\Preview;
class MSExcel extends Office { class MSExcel extends Office {
public const MIMETYPE_REGEX = '/application\/vnd.ms-excel/';
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function getMimeType() { public function getMimeType(): string {
return '/application\/vnd.ms-excel/'; return self::MIMETYPE_REGEX;
} }
} }

Просмотреть файл

@ -22,10 +22,11 @@
namespace OCA\Richdocuments\Preview; namespace OCA\Richdocuments\Preview;
class MSWord extends Office { class MSWord extends Office {
public const MIMETYPE_REGEX = '/application\/msword/';
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function getMimeType() { public function getMimeType(): string {
return '/application\/msword/'; return self::MIMETYPE_REGEX;
} }
} }

Просмотреть файл

@ -22,10 +22,12 @@
namespace OCA\Richdocuments\Preview; namespace OCA\Richdocuments\Preview;
class OOXML extends Office { class OOXML extends Office {
public const MIMETYPE_REGEX = '/application\/vnd.openxmlformats-officedocument.*/';
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function getMimeType() { public function getMimeType(): string {
return '/application\/vnd.openxmlformats-officedocument.*/'; return self::MIMETYPE_REGEX;
} }
} }

Просмотреть файл

@ -21,39 +21,23 @@
*/ */
namespace OCA\Richdocuments\Preview; namespace OCA\Richdocuments\Preview;
use OC\Preview\Provider; use OCA\Richdocuments\AppConfig;
use OCA\Richdocuments\Capabilities; use OCA\Richdocuments\Capabilities;
use OCP\Files\File;
use OCP\Http\Client\IClientService; use OCP\Http\Client\IClientService;
use OCP\IConfig; use OCP\IImage;
use OCP\ILogger;
use OCP\Image; use OCP\Image;
use OCP\Preview\IProviderV2;
use Psr\Log\LoggerInterface;
abstract class Office extends Provider { abstract class Office implements IProviderV2 {
/** @var IClientService */ private array $capabilities = [];
private $clientService;
/** @var IConfig */ public function __construct(private IClientService $clientService, private AppConfig $config, Capabilities $capabilities, private LoggerInterface $logger) {
private $config;
/** @var array */
private $capabilitites;
/** @var ILogger */
private $logger;
public function __construct(IClientService $clientService, IConfig $config, Capabilities $capabilities, ILogger $logger) {
parent::__construct();
$this->clientService = $clientService;
$this->config = $config;
$this->capabilitites = $capabilities->getCapabilities()['richdocuments'] ?? []; $this->capabilitites = $capabilities->getCapabilities()['richdocuments'] ?? [];
$this->logger = $logger;
} }
private function getWopiURL() { public function isAvailable(\OCP\Files\FileInfo $file): bool {
return $this->config->getAppValue('richdocuments', 'wopi_url');
}
public function isAvailable(\OCP\Files\FileInfo $file) {
if (isset($this->capabilitites['collabora']['convert-to']['available'])) { if (isset($this->capabilitites['collabora']['convert-to']['available'])) {
return (bool)$this->capabilitites['collabora']['convert-to']['available']; return (bool)$this->capabilitites['collabora']['convert-to']['available'];
} }
@ -63,18 +47,17 @@ abstract class Office extends Provider {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
$fileInfo = $fileview->getFileInfo($path); if ($file->getSize() === 0) {
if (!$fileInfo || $fileInfo->getSize() === 0) { return null;
return false;
} }
$useTempFile = $fileInfo->isEncrypted() || !$fileInfo->getStorage()->isLocal(); $useTempFile = $file->isEncrypted() || !$file->getStorage()->isLocal();
if ($useTempFile) { if ($useTempFile) {
$fileName = $fileview->toTmpFile($path); $fileName = $file->getStorage()->getLocalFile($file->getInternalPath());
$stream = fopen($fileName, 'r'); $stream = fopen($fileName, 'r');
} else { } else {
$stream = $fileview->fopen($path, 'r'); $stream = $file->fopen('r');
} }
$client = $this->clientService->newClient(); $client = $this->clientService->newClient();
@ -88,17 +71,13 @@ abstract class Office extends Provider {
$options['verify'] = false; $options['verify'] = false;
} }
$options['multipart'] = [['name' => $path, 'contents' => $stream]]; $options['multipart'] = [['name' => $file->getName(), 'contents' => $stream]];
try { try {
$response = $client->post($this->getWopiURL(). '/lool/convert-to/png', $options); $response = $client->post($this->config->getCollaboraUrlInternal() . '/cool/convert-to/png', $options);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->logger->logException($e, [ $this->logger->info('Failed to convert preview: ' . $e->getMessage(), ['exception' => $e]);
'message' => 'Failed to convert file to preview', return null;
'level' => ILogger::INFO,
'app' => 'richdocuments',
]);
return false;
} }
$image = new Image(); $image = new Image();
@ -108,6 +87,6 @@ abstract class Office extends Provider {
$image->scaleDownToFit($maxX, $maxY); $image->scaleDownToFit($maxX, $maxY);
return $image; return $image;
} }
return false; return null;
} }
} }

Просмотреть файл

@ -23,10 +23,11 @@ namespace OCA\Richdocuments\Preview;
//.odt, .ott, .oth, .odm, .odg, .otg, .odp, .otp, .ods, .ots, .odc, .odf, .odb, .odi, .oxt //.odt, .ott, .oth, .odm, .odg, .otg, .odp, .otp, .ods, .ots, .odc, .odf, .odb, .odi, .oxt
class OpenDocument extends Office { class OpenDocument extends Office {
public const MIMETYPE_REGEX = '/application\/vnd.oasis.opendocument.*/';
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function getMimeType() { public function getMimeType(): string {
return '/application\/vnd.oasis.opendocument.*/'; return self::MIMETYPE_REGEX;
} }
} }

Просмотреть файл

@ -23,10 +23,11 @@
namespace OCA\Richdocuments\Preview; namespace OCA\Richdocuments\Preview;
class Pdf extends Office { class Pdf extends Office {
public const MIMETYPE_REGEX = '/application\/pdf/';
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function getMimeType() { public function getMimeType(): string {
return '/application\/pdf/'; return self::MIMETYPE_REGEX;
} }
} }

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.15.0@5c774aca4746caf3d239d9c8cadb9f882ca29352"> <files psalm-version="5.21.1@8c473e2437be8b6a8fd8f630f0f11a16b114c494">
<file src="lib/AppConfig.php"> <file src="lib/AppConfig.php">
<InvalidArgument> <InvalidArgument>
<code>[]</code> <code>[]</code>
@ -8,16 +8,6 @@
<code><![CDATA[array_key_exists($key, self::APP_SETTING_TYPES) && self::APP_SETTING_TYPES[$key] === 'array']]></code> <code><![CDATA[array_key_exists($key, self::APP_SETTING_TYPES) && self::APP_SETTING_TYPES[$key] === 'array']]></code>
</RedundantCondition> </RedundantCondition>
</file> </file>
<file src="lib/AppInfo/Application.php">
<MissingDependency>
<code>EMF</code>
<code>MSExcel</code>
<code>MSWord</code>
<code>OOXML</code>
<code>OpenDocument</code>
<code>Pdf</code>
</MissingDependency>
</file>
<file src="lib/Command/ActivateConfig.php"> <file src="lib/Command/ActivateConfig.php">
<UndefinedClass> <UndefinedClass>
<code>Command</code> <code>Command</code>
@ -28,12 +18,12 @@
<code>Command</code> <code>Command</code>
</UndefinedClass> </UndefinedClass>
</file> </file>
<file src="lib/Command/UpdateEmptyTemplates.php"> <file src="lib/Command/InstallDefaultFonts.php">
<UndefinedClass> <UndefinedClass>
<code>Command</code> <code>Command</code>
</UndefinedClass> </UndefinedClass>
</file> </file>
<file src="lib/Command/InstallDefaultFonts.php"> <file src="lib/Command/UpdateEmptyTemplates.php">
<UndefinedClass> <UndefinedClass>
<code>Command</code> <code>Command</code>
</UndefinedClass> </UndefinedClass>
@ -53,7 +43,7 @@
<code><![CDATA[$node->getId()]]></code> <code><![CDATA[$node->getId()]]></code>
</InvalidScalarArgument> </InvalidScalarArgument>
<RedundantCondition> <RedundantCondition>
<code><![CDATA[$app !== '']]></code> <code>$app !== ''</code>
</RedundantCondition> </RedundantCondition>
</file> </file>
<file src="lib/Controller/SettingsController.php"> <file src="lib/Controller/SettingsController.php">
@ -78,7 +68,7 @@
<code>null</code> <code>null</code>
</NullArgument> </NullArgument>
<TypeDoesNotContainType> <TypeDoesNotContainType>
<code><![CDATA[$path === '']]></code> <code>$path === ''</code>
</TypeDoesNotContainType> </TypeDoesNotContainType>
<UndefinedInterfaceMethod> <UndefinedInterfaceMethod>
<code>putContent</code> <code>putContent</code>
@ -95,35 +85,13 @@
<code><![CDATA[$share && method_exists($share, 'getAttributes')]]></code> <code><![CDATA[$share && method_exists($share, 'getAttributes')]]></code>
</RedundantCondition> </RedundantCondition>
</file> </file>
<file src="lib/Preview/EMF.php"> <file src="lib/Preview/Office.php">
<MissingDependency> <MissingDependency>
<code>Office</code> <code>Image</code>
</MissingDependency>
</file>
<file src="lib/Preview/MSExcel.php">
<MissingDependency>
<code>Office</code>
</MissingDependency>
</file>
<file src="lib/Preview/MSWord.php">
<MissingDependency>
<code>Office</code>
</MissingDependency>
</file>
<file src="lib/Preview/OOXML.php">
<MissingDependency>
<code>Office</code>
</MissingDependency>
</file>
<file src="lib/Preview/OpenDocument.php">
<MissingDependency>
<code>Office</code>
</MissingDependency>
</file>
<file src="lib/Preview/Pdf.php">
<MissingDependency>
<code>Office</code>
</MissingDependency> </MissingDependency>
<UndefinedThisPropertyAssignment>
<code><![CDATA[$this->capabilitites]]></code>
</UndefinedThisPropertyAssignment>
</file> </file>
<file src="lib/Service/ConnectivityService.php"> <file src="lib/Service/ConnectivityService.php">
<UndefinedClass> <UndefinedClass>