From aa48a5f94f2db398c639e95a89dc438203e89ca2 Mon Sep 17 00:00:00 2001 From: Daniel Kesselberg Date: Sun, 12 Nov 2023 12:33:21 +0100 Subject: feat: add preview provider for emf files based on office Signed-off-by: Daniel Kesselberg --- config/config.sample.php | 3 +- core/js/mimetypelist.js | 3 +- lib/composer/composer/autoload_classmap.php | 1 + lib/composer/composer/autoload_static.php | 1 + lib/private/Preview/EMF.php | 33 ++++++++++++++++++++++ lib/private/PreviewManager.php | 1 + lib/private/Repair/RepairMimeTypes.php | 11 ++++++++ resources/config/mimetypealiases.dist.json | 3 +- resources/config/mimetypemapping.dist.json | 1 + .../mimetypeListModified/core/js/mimetypelist.js | 1 + .../mimetypeListModified/core/signature.json | 4 +-- version.php | 2 +- 12 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 lib/private/Preview/EMF.php diff --git a/config/config.sample.php b/config/config.sample.php index ab86feedb85..75fb7721b18 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1285,6 +1285,7 @@ $CONFIG = [ * - ``OC\Preview\StarOffice`` * - ``OC\Preview\SVG`` * - ``OC\Preview\TIFF`` + * - ``OC\Preview\EMF`` * * * Defaults to the following providers: @@ -1945,7 +1946,7 @@ $CONFIG = [ * * Example for windows systems: ``array('?', '<', '>', ':', '*', '|', '"', chr(0), "\n", "\r")`` * see https://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits - * + * * Defaults to ``array()`` */ 'forbidden_chars' => [], diff --git a/core/js/mimetypelist.js b/core/js/mimetypelist.js index a2ca2c23d07..2e87ce756ba 100644 --- a/core/js/mimetypelist.js +++ b/core/js/mimetypelist.js @@ -113,7 +113,8 @@ OC.MimeTypeList={ "application/vnd.xmind.workbook": "mindmap", "image/targa": "image/tga", "application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform": "x-office/form", - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template" + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template", + "image/x-emf": "image/emf" }, files: [ "application", diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index cb94551e35e..a9af6f4ef98 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -1534,6 +1534,7 @@ return array( 'OC\\Preview\\BackgroundCleanupJob' => $baseDir . '/lib/private/Preview/BackgroundCleanupJob.php', 'OC\\Preview\\Bitmap' => $baseDir . '/lib/private/Preview/Bitmap.php', 'OC\\Preview\\Bundled' => $baseDir . '/lib/private/Preview/Bundled.php', + 'OC\\Preview\\EMF' => $baseDir . '/lib/private/Preview/EMF.php', 'OC\\Preview\\Font' => $baseDir . '/lib/private/Preview/Font.php', 'OC\\Preview\\GIF' => $baseDir . '/lib/private/Preview/GIF.php', 'OC\\Preview\\Generator' => $baseDir . '/lib/private/Preview/Generator.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index b19f568ac1f..89bab8addb9 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -1567,6 +1567,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Preview\\BackgroundCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Preview/BackgroundCleanupJob.php', 'OC\\Preview\\Bitmap' => __DIR__ . '/../../..' . '/lib/private/Preview/Bitmap.php', 'OC\\Preview\\Bundled' => __DIR__ . '/../../..' . '/lib/private/Preview/Bundled.php', + 'OC\\Preview\\EMF' => __DIR__ . '/../../..' . '/lib/private/Preview/EMF.php', 'OC\\Preview\\Font' => __DIR__ . '/../../..' . '/lib/private/Preview/Font.php', 'OC\\Preview\\GIF' => __DIR__ . '/../../..' . '/lib/private/Preview/GIF.php', 'OC\\Preview\\Generator' => __DIR__ . '/../../..' . '/lib/private/Preview/Generator.php', diff --git a/lib/private/Preview/EMF.php b/lib/private/Preview/EMF.php new file mode 100644 index 00000000000..2b5f40e66af --- /dev/null +++ b/lib/private/Preview/EMF.php @@ -0,0 +1,33 @@ + + * + * @author Daniel Kesselberg + * + * @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 OC\Preview; + +class EMF extends Office { + public function getMimeType(): string { + return '/image\/emf/'; + } +} diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php index 3af6848686e..8e41662262d 100644 --- a/lib/private/PreviewManager.php +++ b/lib/private/PreviewManager.php @@ -408,6 +408,7 @@ class PreviewManager implements IPreview { $this->registerCoreProvider(Preview\MSOffice2007::class, '/application\/vnd.openxmlformats-officedocument.*/', ["officeBinary" => $officeBinary]); $this->registerCoreProvider(Preview\OpenDocument::class, '/application\/vnd.oasis.opendocument.*/', ["officeBinary" => $officeBinary]); $this->registerCoreProvider(Preview\StarOffice::class, '/application\/vnd.sun.xml.*/', ["officeBinary" => $officeBinary]); + $this->registerCoreProvider(Preview\EMF::class, '/image\/emf/', ['officeBinary' => $officeBinary]); } } } diff --git a/lib/private/Repair/RepairMimeTypes.php b/lib/private/Repair/RepairMimeTypes.php index ee5a84ad65c..cab8d8ca02a 100644 --- a/lib/private/Repair/RepairMimeTypes.php +++ b/lib/private/Repair/RepairMimeTypes.php @@ -229,6 +229,13 @@ class RepairMimeTypes implements IRepairStep { return $this->updateMimetypes($updatedMimetypes); } + private function introduceEnhancedMetafileFormatType() { + $updatedMimetypes = [ + 'emf' => 'image/emf', + ]; + + return $this->updateMimetypes($updatedMimetypes); + } /** * Fix mime types @@ -286,5 +293,9 @@ class RepairMimeTypes implements IRepairStep { if (version_compare($ocVersionFromBeforeUpdate, '26.0.0.1', '<') && $this->introduceAsciidocType()) { $out->info('Fixed AsciiDoc mime types'); } + + if (version_compare($ocVersionFromBeforeUpdate, '28.0.0.5', '<') && $this->introduceEnhancedMetafileFormatType()) { + $out->info('Fixed Enhanced Metafile Format mime types'); + } } } diff --git a/resources/config/mimetypealiases.dist.json b/resources/config/mimetypealiases.dist.json index 67e79a52283..6b0bcf3e59a 100644 --- a/resources/config/mimetypealiases.dist.json +++ b/resources/config/mimetypealiases.dist.json @@ -114,5 +114,6 @@ "application/vnd.xmind.workbook": "mindmap", "image/targa": "image/tga", "application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform": "x-office/form", - "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template" + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template", + "image/x-emf": "image/emf" } diff --git a/resources/config/mimetypemapping.dist.json b/resources/config/mimetypemapping.dist.json index 7b631466972..88a09d0b928 100644 --- a/resources/config/mimetypemapping.dist.json +++ b/resources/config/mimetypemapping.dist.json @@ -51,6 +51,7 @@ "dot": ["application/msword"], "dotx": ["application/vnd.openxmlformats-officedocument.wordprocessingml.template"], "dv": ["video/dv"], + "emf": ["image/emf"], "eot": ["application/vnd.ms-fontobject"], "eps": ["application/postscript"], "epub": ["application/epub+zip"], diff --git a/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js b/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js index a8e98e786f5..ffcf5e1fb1c 100644 --- a/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js +++ b/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js @@ -115,6 +115,7 @@ OC.MimeTypeList={ "image/targa": "image/tga", "application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform": "x-office/form", "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template", + "image/x-emf": "image/emf", "my-custom/mimetype": "custom" }, files: [ diff --git a/tests/data/integritycheck/mimetypeListModified/core/signature.json b/tests/data/integritycheck/mimetypeListModified/core/signature.json index 43f489f6d3f..4ee844b87f8 100644 --- a/tests/data/integritycheck/mimetypeListModified/core/signature.json +++ b/tests/data/integritycheck/mimetypeListModified/core/signature.json @@ -1,7 +1,7 @@ { "hashes": { - "core\/js\/mimetypelist.js": "2a6ab9af5353d464c0dd3bd651cfc13ba35009463949bc45bd8f7073828fa34fbdac7a81ba2b188e7e0c97fc63c2167825b069f61341e507ca33213b1e6e4593" + "core\/js\/mimetypelist.js": "e9e515c5eeb08b02971e5943640bef89b6d1c2d746d5883bf974c6ac753f810685c7a20bf0ed4d32d8c046cd2cef6c045682c7d89c6a3b7b6c33122f5fd2088f" }, - "signature": "A5JmjvGiWC9iDaDL0\/wzIBx1ovV6xW5pL134ZtzcFh6dCRoYVZFZvInb98zz4Js3Y4R+uAv4XYKFgclG9BXjoa+q7SmN4qV95o870OsX3MEAaPRHEJv7V6P19hinwC0\/c6XUtMUlTn2IqdoacmELV3v+vmXiU0bYpNfqkYDjt1mCfl3EWB+uMCn+W849k1hoRc\/nI3JuDzl3VtP4G6zzJ3NexsXJOHOb6\/GyGVnkOltN3Ep5wBqXtr28LLLWWYbgxUEQ5ZNBd98PCpRm3r\/3eGreREccUzh+Kfo1XK+Rbnf8U6z3DXOwZK4cP\/CJBAhtlUDyw+TY58jcOSLxF2I61jqYoa8En2ukcQdXUvyTcsN+RzAKo+yhAPw0CJvDzb9zuS7gJUpev6nZnJKQ6dNQApQQILtwgz9dDlVKToxgyyhV1giTqEEZDvH1t2MSjz8fbGlm1YY60YJSs2SA\/cAff+sQVmoGCpRtdHriCDAET+5gTuz0wEXnvn6Jvxqxta9IZ0fisKCjfRH5FFdjfBM8Cgk6HOhSAfHoSH+ZFUGy8+NICZXe7CGr40iIjFLSIS0RgclQZSjYK8bfjA43XFpXeJNGjIvxHTr4tzm8gJ3YbVqCyN45HBcxS3q7yJCie3brqCZvXfXyhoGY6WhPAkBLQ+8nNP\/qeWlV8DMX+ZUYxso=", + "signature": "iKEOaoY+lowIZrDjozpCqDFtag8qtANZ4AqnwZG1HrzuP3Yv7uaCUZbpsyr4FklKyyZFbh4w5K3x5bacKq\/h7tFVu5A56sunSZIMDjO\/ToGFYtZC59hTi0mKlmR+rIbAwmlm2Qad0uSD+\/4bkihL\/haPAtV8IbHXqxwjcYjkPmyi0W3rN1sOycgbH8Hmu7UlkdZORGTVVHdMpQuIljaBGBonQUTnqUb2BVsZ7YKW3Ls1AKMBam\/OGrB8rAJOht5b86qIE1jzzU\/BI7Qs+r8C+sh84LpLgz\/33njaBNANwfnvbrcb4f\/95BZCL4DcMGfwJ\/VNRVJrBjQSweYb+ypq5WMMOUvHHEg4CovoH\/XbdCAbRVet34vRZnZe5F4bXQOZXp0eqbqoY+STwQ5Ku2O7YUWwfppjxWMMfs1hDUrvvMBFRCd5mla\/aktV7ugishcZdKUFyDsyOEtT292Cb5f\/62RqnMniD9a+TOBE1qWH5DXYQqRO9TUdVtGQ3ITbLxEAzlfUmwYoXp+wgKbzOXC4KFzpxJnxHM+vuURkO5lUza68gqiG8\/uhNcPQufDT5CjasQVBTK5tdoL64UnXqATgU3rrD\/MByOXWlZvMsAS+NjPkF30UnvqgApEwytOlTZ27+ntZjfwhM3DlXNKE3mzUx+tvVfwBDmhEpBK\/Qpk6HLc=", "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" } \ No newline at end of file diff --git a/version.php b/version.php index bc838f5f8a7..df9e8be9a7c 100644 --- a/version.php +++ b/version.php @@ -30,7 +30,7 @@ // between betas, final and RCs. This is _not_ the public version number. Reset minor/patch level // when updating major/minor version number. -$OC_Version = [28, 0, 0, 4]; +$OC_Version = [28, 0, 0, 5]; // The human-readable string $OC_VersionString = '28.0.0 beta 2'; -- cgit v1.2.3 From b5241d52204e5d88e2fba388041e02e0bd56aea7 Mon Sep 17 00:00:00 2001 From: Daniel Kesselberg Date: Mon, 13 Nov 2023 20:14:54 +0100 Subject: feat: allow multiple libreoffice invocations LibreOffice only allows one invocation per user profile.[^1] The office provider set the user profile to /tmp/owncloud-instanceid and therefore only one invocation per instance is allowed. This was introduced a while ago, yet it's unclear if this was intentionally or just a side effect.[^2] The limitation on one invocation leads to the situation that the preview generation only works for a couple of files if you upload a whole folder of emf or word files. This commit removes the limitation by using a new user profile for each preview. That's done by using instance id plus file id as postfix for getTemporaryFolder. This has some drawbacks: - Overload protection: If you upload 100 emf files, you may end up with 100 LibreOffice invocations. Though, you can use preview_concurrency_new to limit the number of previews that can be generated concurrently when php-sysvsem is available. - New profile: I assume it takes a few bits to generate a fresh LibreOffice user profile. It appears that there is no way to ask LibreOffice to not create a profile and just work with the defaults. The profile will be cleaned after use by our temp manager. - Remove the configuration option preview_office_cl_parameters: This is not strictly necessary yet, but if you set the configuration option, the generated path for the user profile is also missing. The configuration option is not well documented (e.g., it's unclear that the last option needs to be --outdir) and actually, there should be no reason to change it after all. [^1]: https://wiki.documentfoundation.org/UserProfile [^2]: https://github.com/owncloud/core/pull/9784 Signed-off-by: Daniel Kesselberg --- config/config.sample.php | 8 -------- lib/private/Preview/Office.php | 45 +++++++++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 75fb7721b18..27b99636a22 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1237,14 +1237,6 @@ $CONFIG = [ * Defaults to ``''`` (empty string) */ 'preview_libreoffice_path' => '/usr/bin/libreoffice', -/** - * Use this if LibreOffice/OpenOffice requires additional arguments. - * - * Defaults to ``''`` (empty string) - */ -'preview_office_cl_parameters' => - ' --headless --nologo --nofirststartwizard --invisible --norestore '. - '--convert-to png --outdir ', /** * custom path for ffmpeg binary diff --git a/lib/private/Preview/Office.php b/lib/private/Preview/Office.php index 3ba7c5a21a0..bc0c554a192 100644 --- a/lib/private/Preview/Office.php +++ b/lib/private/Preview/Office.php @@ -31,6 +31,8 @@ namespace OC\Preview; use OCP\Files\File; use OCP\Files\FileInfo; use OCP\IImage; +use OCP\ITempManager; +use OCP\Server; use Psr\Log\LoggerInterface; abstract class Office extends ProviderV2 { @@ -49,15 +51,41 @@ abstract class Office extends ProviderV2 { return null; } + $tempManager = Server::get(ITempManager::class); + + // The file to generate the preview for. $absPath = $this->getLocalFile($file); - $tmpDir = \OC::$server->getTempManager()->getTempBaseDir(); + // The destination for the LibreOffice user profile. + // LibreOffice can rune once per user profile and therefore instance id and file id are included. + $profile = $tempManager->getTemporaryFolder( + 'nextcloud-office-profile-' . \OC_Util::getInstanceId() . '-' . $file->getId() + ); + + // The destination for the LibreOffice convert result. + $outdir = $tempManager->getTemporaryFolder( + 'nextcloud-office-preview-' . \OC_Util::getInstanceId() . '-' . $file->getId() + ); - $defaultParameters = ' -env:UserInstallation=file://' . escapeshellarg($tmpDir . '/owncloud-' . \OC_Util::getInstanceId() . '/') . ' --headless --nologo --nofirststartwizard --invisible --norestore --convert-to png --outdir '; - $clParameters = \OC::$server->getConfig()->getSystemValue('preview_office_cl_parameters', $defaultParameters); + if ($profile === false || $outdir === false) { + $this->cleanTmpFiles(); + return null; + } - $cmd = $this->options['officeBinary'] . $clParameters . escapeshellarg($tmpDir) . ' ' . escapeshellarg($absPath); + $parameters = [ + $this->options['officeBinary'], + '-env:UserInstallation=file://' . escapeshellarg($profile), + '--headless', + '--nologo', + '--nofirststartwizard', + '--invisible', + '--norestore', + '--convert-to png', + '--outdir ' . escapeshellarg($outdir), + escapeshellarg($absPath), + ]; + $cmd = implode(' ', $parameters); exec($cmd, $output, $returnCode); if ($returnCode !== 0) { @@ -65,17 +93,13 @@ abstract class Office extends ProviderV2 { return null; } - //create imagick object from png - $pngPreview = null; try { - [$dirname, , , $filename] = array_values(pathinfo($absPath)); - $pngPreview = $tmpDir . '/' . $filename . '.png'; + $filename = $outdir . pathinfo($absPath, PATHINFO_FILENAME) . '.png'; - $png = new \Imagick($pngPreview . '[0]'); + $png = new \Imagick($filename . '[0]'); $png->setImageFormat('jpg'); } catch (\Exception $e) { $this->cleanTmpFiles(); - unlink($pngPreview); \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'core', @@ -87,7 +111,6 @@ abstract class Office extends ProviderV2 { $image->loadFromData((string) $png); $this->cleanTmpFiles(); - unlink($pngPreview); if ($image->valid()) { $image->scaleDownToFit($maxX, $maxY); -- cgit v1.2.3 From 475dd6035435e326b0ffab6e74f961757896b97d Mon Sep 17 00:00:00 2001 From: Daniel Kesselberg Date: Mon, 13 Nov 2023 21:35:22 +0100 Subject: fix: use png as preview right away The initial office preview implementation converted an office document with LibreOffice to PDF, used ImageMagick to extract the first page as JPEG, and passed it OC_Image. https://github.com/nextcloud/server/pull/10198 changed the implementation to use PNG rather than PDF. OC_Image can use a PNG as a preview right away, so the ImageMagick step is unnecessary. The registration code was updated to not ask ImageMagick if PDF is supported, as PDFs are no longer used to create office document previews. Signed-off-by: Daniel Kesselberg --- lib/private/Preview/Office.php | 19 +++---------- lib/private/PreviewManager.php | 61 +++++++++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/lib/private/Preview/Office.php b/lib/private/Preview/Office.php index bc0c554a192..68499a6fea6 100644 --- a/lib/private/Preview/Office.php +++ b/lib/private/Preview/Office.php @@ -33,7 +33,6 @@ use OCP\Files\FileInfo; use OCP\IImage; use OCP\ITempManager; use OCP\Server; -use Psr\Log\LoggerInterface; abstract class Office extends ProviderV2 { /** @@ -93,30 +92,18 @@ abstract class Office extends ProviderV2 { return null; } - try { - $filename = $outdir . pathinfo($absPath, PATHINFO_FILENAME) . '.png'; - - $png = new \Imagick($filename . '[0]'); - $png->setImageFormat('jpg'); - } catch (\Exception $e) { - $this->cleanTmpFiles(); - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ - 'exception' => $e, - 'app' => 'core', - ]); - return null; - } + $preview = $outdir . pathinfo($absPath, PATHINFO_FILENAME) . '.png'; $image = new \OCP\Image(); - $image->loadFromData((string) $png); + $image->loadFromFile($preview); $this->cleanTmpFiles(); if ($image->valid()) { $image->scaleDownToFit($maxX, $maxY); - return $image; } + return null; } } diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php index 8e41662262d..aedcbbce335 100644 --- a/lib/private/PreviewManager.php +++ b/lib/private/PreviewManager.php @@ -366,7 +366,7 @@ class PreviewManager implements IPreview { $this->registerCoreProvider(Preview\OpenDocument::class, '/application\/vnd.oasis.opendocument.*/'); $this->registerCoreProvider(Preview\Imaginary::class, Preview\Imaginary::supportedMimeTypes()); - // SVG, Office and Bitmap require imagick + // SVG and Bitmap require imagick if ($this->imagickSupport->hasExtension()) { $imagickProviders = [ 'SVG' => ['mimetype' => '/image\/svg\+xml/', 'class' => Preview\SVG::class], @@ -391,28 +391,10 @@ class PreviewManager implements IPreview { $this->registerCoreProvider($class, $provider['mimetype']); } } - - if ($this->imagickSupport->supportsFormat('PDF')) { - // Office requires openoffice or libreoffice - $officeBinary = $this->config->getSystemValue('preview_libreoffice_path', null); - if (!is_string($officeBinary)) { - $officeBinary = $this->binaryFinder->findBinaryPath('libreoffice'); - } - if (!is_string($officeBinary)) { - $officeBinary = $this->binaryFinder->findBinaryPath('openoffice'); - } - - if (is_string($officeBinary)) { - $this->registerCoreProvider(Preview\MSOfficeDoc::class, '/application\/msword/', ["officeBinary" => $officeBinary]); - $this->registerCoreProvider(Preview\MSOffice2003::class, '/application\/vnd.ms-.*/', ["officeBinary" => $officeBinary]); - $this->registerCoreProvider(Preview\MSOffice2007::class, '/application\/vnd.openxmlformats-officedocument.*/', ["officeBinary" => $officeBinary]); - $this->registerCoreProvider(Preview\OpenDocument::class, '/application\/vnd.oasis.opendocument.*/', ["officeBinary" => $officeBinary]); - $this->registerCoreProvider(Preview\StarOffice::class, '/application\/vnd.sun.xml.*/', ["officeBinary" => $officeBinary]); - $this->registerCoreProvider(Preview\EMF::class, '/image\/emf/', ['officeBinary' => $officeBinary]); - } - } } + $this->registerCoreProvidersOffice(); + // Video requires avconv or ffmpeg if (in_array(Preview\Movie::class, $this->getEnabledDefaultProvider())) { $movieBinary = $this->config->getSystemValue('preview_ffmpeg_path', null); @@ -430,6 +412,43 @@ class PreviewManager implements IPreview { } } + private function registerCoreProvidersOffice(): void { + $officeProviders = [ + ['mimetype' => '/application\/msword/', 'class' => Preview\MSOfficeDoc::class], + ['mimetype' => '/application\/vnd.ms-.*/', 'class' => Preview\MSOffice2003::class], + ['mimetype' => '/application\/vnd.openxmlformats-officedocument.*/', 'class' => Preview\MSOffice2007::class], + ['mimetype' => '/application\/vnd.oasis.opendocument.*/', 'class' => Preview\OpenDocument::class], + ['mimetype' => '/application\/vnd.sun.xml.*/', 'class' => Preview\StarOffice::class], + ['mimetype' => '/image\/emf/', 'class' => Preview\EMF::class], + ]; + + $findBinary = true; + $officeBinary = false; + + foreach ($officeProviders as $provider) { + $class = $provider['class']; + if (!in_array(trim($class, '\\'), $this->getEnabledDefaultProvider())) { + continue; + } + + if ($findBinary) { + // Office requires openoffice or libreoffice + $officeBinary = $this->config->getSystemValue('preview_libreoffice_path', false); + if ($officeBinary === false) { + $officeBinary = $this->binaryFinder->findBinaryPath('libreoffice'); + } + if ($officeBinary === false) { + $officeBinary = $this->binaryFinder->findBinaryPath('openoffice'); + } + $findBinary = false; + } + + if ($officeBinary) { + $this->registerCoreProvider($class, $provider['mimetype'], ['officeBinary' => $officeBinary]); + } + } + } + private function registerBootstrapProviders(): void { $context = $this->bootstrapCoordinator->getRegistrationContext(); -- cgit v1.2.3