diff options
author | Thomas Müller <thomas.mueller@tmit.eu> | 2015-03-20 16:34:22 +0100 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2015-03-20 16:34:22 +0100 |
commit | afa88729558b8dd26413ff49ada8678b1b6521c6 (patch) | |
tree | 86e6c662bef91e633816f2d72dac5115770c92ec /lib | |
parent | a45e45df1ec357f9b390463ed74100e6c8b07fe7 (diff) | |
parent | 8f06353882877c948e15e0340615cc7d25c44b83 (diff) | |
download | nextcloud-server-afa88729558b8dd26413ff49ada8678b1b6521c6.tar.gz nextcloud-server-afa88729558b8dd26413ff49ada8678b1b6521c6.zip |
Merge pull request #14857 from owncloud/preview-provider-registration-in-manager
Preview provider registration in manager
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/avatar.php | 6 | ||||
-rw-r--r-- | lib/private/image.php | 7 | ||||
-rw-r--r-- | lib/private/preview.php | 261 | ||||
-rw-r--r-- | lib/private/preview/movie.php | 2 | ||||
-rw-r--r-- | lib/private/preview/mp3.php | 3 | ||||
-rw-r--r-- | lib/private/preview/provider.php | 19 | ||||
-rw-r--r-- | lib/private/preview/txt.php | 2 | ||||
-rw-r--r-- | lib/private/previewmanager.php | 274 | ||||
-rw-r--r-- | lib/private/server.php | 4 | ||||
-rw-r--r-- | lib/public/iavatar.php | 4 | ||||
-rw-r--r-- | lib/public/iimage.php | 146 | ||||
-rw-r--r-- | lib/public/ipreview.php | 34 | ||||
-rw-r--r-- | lib/public/preview/iprovider.php | 39 |
13 files changed, 539 insertions, 262 deletions
diff --git a/lib/private/avatar.php b/lib/private/avatar.php index 23b3c82771a..da9c84d84a4 100644 --- a/lib/private/avatar.php +++ b/lib/private/avatar.php @@ -29,7 +29,7 @@ class Avatar implements \OCP\IAvatar { /** * get the users avatar * @param int $size size in px of the avatar, avatars are square, defaults to 64 - * @return boolean|\OC_Image containing the avatar or false if there's no image + * @return boolean|\OCP\IImage containing the avatar or false if there's no image */ public function get ($size = 64) { if ($this->view->file_exists('avatar.jpg')) { @@ -57,14 +57,14 @@ class Avatar implements \OCP\IAvatar { /** * sets the users avatar - * @param \OC_Image|resource|string $data OC_Image, imagedata or path to set a new avatar + * @param \OCP\IImage|resource|string $data An image object, imagedata or path to set a new avatar * @throws \Exception if the provided file is not a jpg or png image * @throws \Exception if the provided image is not valid * @throws \OC\NotSquareException if the image is not square * @return void */ public function set ($data) { - if($data instanceOf OC_Image) { + if($data instanceOf \OCP\IImage) { $img = $data; $data = $img->data(); } else { diff --git a/lib/private/image.php b/lib/private/image.php index 2484aeecc63..c8509c61286 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -15,7 +15,7 @@ /** * Class for basic image manipulation */ -class OC_Image { +class OC_Image implements \OCP\IImage { protected $resource = false; // tmp resource. protected $imageType = IMAGETYPE_PNG; // Default to png if file type isn't evident. protected $mimeType = "image/png"; // Default to png @@ -285,7 +285,7 @@ class OC_Image { /** * @return null|string Returns the raw image data. */ - function data() { + public function data() { if (!$this->valid()) { return null; } @@ -949,6 +949,9 @@ class OC_Image { return true; } + /** + * Destroys the current image and resets the object + */ public function destroy() { if ($this->valid()) { imagedestroy($this->resource); diff --git a/lib/private/preview.php b/lib/private/preview.php index 6af1586293f..f69b0d6c971 100644 --- a/lib/private/preview.php +++ b/lib/private/preview.php @@ -46,15 +46,10 @@ class Preview { /** * preview images object * - * @var \OC_Image + * @var \OCP\IImage */ private $preview; - //preview providers - static private $providers = array(); - static private $registeredProviders = array(); - static private $enabledProviders = array(); - /** * @var \OCP\Files\FileInfo */ @@ -95,11 +90,7 @@ class Preview { $this->preview = null; //check if there are preview backends - if (empty(self::$providers)) { - self::initProviders(); - } - - if (empty(self::$providers) && \OC::$server->getConfig()->getSystemValue('enable_previews', true)) { + if (!\OC::$server->getPreviewManager()->hasProviders() && \OC::$server->getConfig()->getSystemValue('enable_previews', true)) { \OC_Log::write('core', 'No preview providers exist', \OC_Log::ERROR); throw new \Exception('No preview providers'); } @@ -474,7 +465,7 @@ class Preview { /** * return a preview of a file - * @return \OC_Image + * @return \OCP\IImage */ public function getPreview() { if (!is_null($this->preview) && $this->preview->valid()) { @@ -510,37 +501,45 @@ class Preview { if (is_null($this->preview)) { $preview = null; - foreach (self::$providers as $supportedMimeType => $provider) { + $previewProviders = \OC::$server->getPreviewManager()->getProviders(); + foreach ($previewProviders as $supportedMimeType => $providers) { if (!preg_match($supportedMimeType, $this->mimeType)) { continue; } - \OC_Log::write('core', 'Generating preview for "' . $file . '" with "' . get_class($provider) . '"', \OC_Log::DEBUG); + foreach ($providers as $closure) { + $provider = $closure(); + if (!($provider instanceof \OCP\Preview\IProvider)) { + continue; + } - /** @var $provider Provider */ - $preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView); + \OC_Log::write('core', 'Generating preview for "' . $file . '" with "' . get_class($provider) . '"', \OC_Log::DEBUG); - if (!($preview instanceof \OC_Image)) { - continue; - } + /** @var $provider Provider */ + $preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView); - $this->preview = $preview; - $this->resizeAndCrop(); + if (!($preview instanceof \OCP\IImage)) { + continue; + } - $previewPath = $this->getPreviewPath($fileId); - $cachePath = $this->buildCachePath($fileId); + $this->preview = $preview; + $this->resizeAndCrop(); - if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) { - $this->userView->mkdir($this->getThumbnailsFolder() . '/'); - } + $previewPath = $this->getPreviewPath($fileId); + $cachePath = $this->buildCachePath($fileId); - if ($this->userView->is_dir($previewPath) === false) { - $this->userView->mkdir($previewPath); - } + if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) { + $this->userView->mkdir($this->getThumbnailsFolder() . '/'); + } + + if ($this->userView->is_dir($previewPath) === false) { + $this->userView->mkdir($previewPath); + } - $this->userView->file_put_contents($cachePath, $preview->data()); + $this->userView->file_put_contents($cachePath, $preview->data()); - break; + break 2; + } } } @@ -565,7 +564,7 @@ class Preview { if (is_null($this->preview)) { $this->getPreview(); } - if ($this->preview instanceof \OC_Image) { + if ($this->preview instanceof \OCP\IImage) { $this->preview->show($mimeType); } } @@ -581,8 +580,8 @@ class Preview { $scalingUp = $this->getScalingUp(); $maxScaleFactor = $this->getMaxScaleFactor(); - if (!($image instanceof \OC_Image)) { - \OC_Log::write('core', '$this->preview is not an instance of OC_Image', \OC_Log::DEBUG); + if (!($image instanceof \OCP\IImage)) { + \OC_Log::write('core', '$this->preview is not an instance of \OCP\IImage', \OC_Log::DEBUG); return; } @@ -686,146 +685,6 @@ class Preview { } /** - * register a new preview provider to be used - * @param string $class - * @param array $options - */ - public static function registerProvider($class, $options = array()) { - /** - * Only register providers that have been explicitly enabled - * - * The following providers are enabled by default: - * - OC\Preview\Image - * - OC\Preview\MP3 - * - OC\Preview\TXT - * - OC\Preview\MarkDown - * - * The following providers are disabled by default due to performance or privacy concerns: - * - OC\Preview\MSOfficeDoc - * - OC\Preview\MSOffice2003 - * - OC\Preview\MSOffice2007 - * - OC\Preview\OpenDocument - * - OC\Preview\StarOffice - * - OC\Preview\SVG - * - OC\Preview\Movie - * - OC\Preview\PDF - * - OC\Preview\TIFF - * - OC\Preview\Illustrator - * - OC\Preview\Postscript - * - OC\Preview\Photoshop - * - OC\Preview\Font - */ - if(empty(self::$enabledProviders)) { - self::$enabledProviders = \OC::$server->getConfig()->getSystemValue('enabledPreviewProviders', array( - 'OC\Preview\Image', - 'OC\Preview\MP3', - 'OC\Preview\TXT', - 'OC\Preview\MarkDown', - )); - } - - if(in_array($class, self::$enabledProviders)) { - self::$registeredProviders[] = array('class' => $class, 'options' => $options); - } - } - - /** - * create instances of all the registered preview providers - * @return void - */ - private static function initProviders() { - if (!\OC::$server->getConfig()->getSystemValue('enable_previews', true)) { - self::$providers = array(); - return; - } - - if (!empty(self::$providers)) { - return; - } - - self::registerCoreProviders(); - foreach (self::$registeredProviders as $provider) { - $class = $provider['class']; - $options = $provider['options']; - - /** @var $object Provider */ - $object = new $class($options); - self::$providers[$object->getMimeType()] = $object; - } - - $keys = array_map('strlen', array_keys(self::$providers)); - array_multisort($keys, SORT_DESC, self::$providers); - } - - protected static function registerCoreProviders() { - self::registerProvider('OC\Preview\TXT'); - self::registerProvider('OC\Preview\MarkDown'); - self::registerProvider('OC\Preview\Image'); - self::registerProvider('OC\Preview\MP3'); - - // SVG, Office and Bitmap require imagick - if (extension_loaded('imagick')) { - $checkImagick = new \Imagick(); - - $imagickProviders = array( - 'SVG' => 'OC\Preview\SVG', - 'TIFF' => 'OC\Preview\TIFF', - 'PDF' => 'OC\Preview\PDF', - 'AI' => 'OC\Preview\Illustrator', - 'PSD' => 'OC\Preview\Photoshop', - 'EPS' => 'OC\Preview\Postscript', - 'TTF' => 'OC\Preview\Font', - ); - - foreach ($imagickProviders as $queryFormat => $provider) { - if (count($checkImagick->queryFormats($queryFormat)) === 1) { - self::registerProvider($provider); - } - } - - if (count($checkImagick->queryFormats('PDF')) === 1) { - // Office previews are currently not supported on Windows - if (!\OC_Util::runningOnWindows() && \OC_Helper::is_function_enabled('shell_exec')) { - $officeFound = is_string(\OC::$server->getConfig()->getSystemValue('preview_libreoffice_path', null)); - - if (!$officeFound) { - //let's see if there is libreoffice or openoffice on this machine - $whichLibreOffice = shell_exec('command -v libreoffice'); - $officeFound = !empty($whichLibreOffice); - if (!$officeFound) { - $whichOpenOffice = shell_exec('command -v openoffice'); - $officeFound = !empty($whichOpenOffice); - } - } - - if ($officeFound) { - self::registerProvider('OC\Preview\MSOfficeDoc'); - self::registerProvider('OC\Preview\MSOffice2003'); - self::registerProvider('OC\Preview\MSOffice2007'); - self::registerProvider('OC\Preview\OpenDocument'); - self::registerProvider('OC\Preview\StarOffice'); - } - } - } - } - - // Video requires avconv or ffmpeg and is therefor - // currently not supported on Windows. - if (!\OC_Util::runningOnWindows()) { - $avconvBinary = \OC_Helper::findBinaryPath('avconv'); - $ffmpegBinary = ($avconvBinary) ? null : \OC_Helper::findBinaryPath('ffmpeg'); - - if ($avconvBinary || $ffmpegBinary) { - // FIXME // a bit hacky but didn't want to use subclasses - \OC\Preview\Movie::$avconvBinary = $avconvBinary; - \OC\Preview\Movie::$ffmpegBinary = $ffmpegBinary; - - self::registerProvider('OC\Preview\Movie'); - } - } - } - - /** * @param array $args */ public static function post_write($args) { @@ -915,60 +774,6 @@ class Preview { } /** - * Check if a preview can be generated for a file - * - * @param \OC\Files\FileInfo $file - * @return bool - */ - public static function isAvailable(\OC\Files\FileInfo $file) { - if (!\OC_Config::getValue('enable_previews', true)) { - return false; - } - - $mount = $file->getMountPoint(); - if ($mount and !$mount->getOption('previews', true)){ - return false; - } - - //check if there are preview backends - if (empty(self::$providers)) { - self::initProviders(); - } - - foreach (self::$providers as $supportedMimeType => $provider) { - /** - * @var \OC\Preview\Provider $provider - */ - if (preg_match($supportedMimeType, $file->getMimetype())) { - return $provider->isAvailable($file); - } - } - return false; - } - - /** - * @param string $mimeType - * @return bool - */ - public static function isMimeSupported($mimeType) { - if (!\OC_Config::getValue('enable_previews', true)) { - return false; - } - - //check if there are preview backends - if (empty(self::$providers)) { - self::initProviders(); - } - - foreach(self::$providers as $supportedMimetype => $provider) { - if(preg_match($supportedMimetype, $mimeType)) { - return true; - } - } - return false; - } - - /** * @param int $fileId * @return string */ diff --git a/lib/private/preview/movie.php b/lib/private/preview/movie.php index 06353ddebb7..85151f5dbaa 100644 --- a/lib/private/preview/movie.php +++ b/lib/private/preview/movie.php @@ -61,7 +61,7 @@ class Movie extends Provider { * @param int $maxY * @param string $absPath * @param int $second - * @return bool|\OC_Image + * @return bool|\OCP\IImage */ private function generateThumbNail($maxX, $maxY, $absPath, $second) { $tmpPath = \OC_Helper::tmpFile(); diff --git a/lib/private/preview/mp3.php b/lib/private/preview/mp3.php index f1a50d99e13..19360f4f036 100644 --- a/lib/private/preview/mp3.php +++ b/lib/private/preview/mp3.php @@ -39,8 +39,7 @@ class MP3 extends Provider { /** * Generates a default image when the file has no cover * - * @return false|\OC_Image False if the default image is missing or invalid, - * otherwise the image is returned as \OC_Image + * @return bool|\OCP\IImage false if the default image is missing or invalid */ private function getNoCoverThumbnail() { $icon = \OC::$SERVERROOT . '/core/img/filetypes/audio.png'; diff --git a/lib/private/preview/provider.php b/lib/private/preview/provider.php index ead67eaeef7..1d6fac13965 100644 --- a/lib/private/preview/provider.php +++ b/lib/private/preview/provider.php @@ -1,10 +1,17 @@ <?php namespace OC\Preview; -abstract class Provider { +use OCP\Preview\IProvider; + +abstract class Provider implements IProvider { private $options; - public function __construct($options) { + /** + * Constructor + * + * @param array $options + */ + public function __construct(array $options = []) { $this->options = $options; } @@ -16,10 +23,10 @@ abstract class Provider { /** * Check if a preview can be generated for $path * - * @param \OC\Files\FileInfo $file + * @param \OCP\Files\FileInfo $file * @return bool */ - public function isAvailable($file) { + public function isAvailable(\OCP\Files\FileInfo $file) { return true; } @@ -30,9 +37,7 @@ abstract class Provider { * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image * @param bool $scalingup Disable/Enable upscaling of previews * @param \OC\Files\View $fileview fileview object of user folder - * @return mixed - * false if no preview was generated - * OC_Image object of the preview + * @return bool|\OCP\IImage false if no preview was generated */ abstract public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview); } diff --git a/lib/private/preview/txt.php b/lib/private/preview/txt.php index 8b414dc5726..772b56c72cc 100644 --- a/lib/private/preview/txt.php +++ b/lib/private/preview/txt.php @@ -18,7 +18,7 @@ class TXT extends Provider { /** * {@inheritDoc} */ - public function isAvailable($file) { + public function isAvailable(\OCP\Files\FileInfo $file) { return $file->getSize() > 5; } diff --git a/lib/private/previewmanager.php b/lib/private/previewmanager.php index 85bf609743d..9f78379ba0f 100644 --- a/lib/private/previewmanager.php +++ b/lib/private/previewmanager.php @@ -8,10 +8,87 @@ */ namespace OC; -use OCP\image; use OCP\IPreview; +use OCP\Preview\IProvider; class PreviewManager implements IPreview { + /** @var \OCP\IConfig */ + protected $config; + + /** @var bool */ + protected $providerListDirty = false; + + /** @var bool */ + protected $registeredCoreProviders = false; + + /** @var array */ + protected $providers = []; + + /** @var array mime type => support status */ + protected $mimeTypeSupportMap = []; + + /** @var array */ + protected $defaultProviders; + + /** + * Constructor + * + * @param \OCP\IConfig $config + */ + public function __construct(\OCP\IConfig $config) { + $this->config = $config; + } + + /** + * In order to improve lazy loading a closure can be registered which will be + * called in case preview providers are actually requested + * + * $callable has to return an instance of \OCP\Preview\IProvider + * + * @param string $mimeTypeRegex Regex with the mime types that are supported by this provider + * @param \Closure $callable + * @return void + */ + public function registerProvider($mimeTypeRegex, \Closure $callable) { + if (!$this->config->getSystemValue('enable_previews', true)) { + return; + } + + if (!isset($this->providers[$mimeTypeRegex])) { + $this->providers[$mimeTypeRegex] = []; + } + $this->providers[$mimeTypeRegex][] = $callable; + $this->providerListDirty = true; + } + + /** + * Get all providers + * @return array + */ + public function getProviders() { + if (!$this->config->getSystemValue('enable_previews', true)) { + return []; + } + + $this->registerCoreProviders(); + if ($this->providerListDirty) { + $keys = array_map('strlen', array_keys($this->providers)); + array_multisort($keys, SORT_DESC, $this->providers); + $this->providerListDirty = false; + } + + return $this->providers; + } + + /** + * Does the manager have any providers + * @return bool + */ + public function hasProviders() { + $this->registerCoreProviders(); + return !empty($this->providers); + } + /** * return a preview of a file * @@ -19,9 +96,9 @@ class PreviewManager implements IPreview { * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image * @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly - * @return \OCP\Image + * @return \OCP\IImage */ - function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false) { + public function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false) { $preview = new \OC\Preview('', '/', $file, $maxX, $maxY, $scaleUp); return $preview->getPreview(); } @@ -32,17 +109,198 @@ class PreviewManager implements IPreview { * @param string $mimeType * @return boolean */ - function isMimeSupported($mimeType = '*') { - return \OC\Preview::isMimeSupported($mimeType); + public function isMimeSupported($mimeType = '*') { + if (!$this->config->getSystemValue('enable_previews', true)) { + return false; + } + + if (isset($this->mimeTypeSupportMap[$mimeType])) { + return $this->mimeTypeSupportMap[$mimeType]; + } + + $this->registerCoreProviders(); + $providerMimeTypes = array_keys($this->providers); + foreach ($providerMimeTypes as $supportedMimeType) { + if (preg_match($supportedMimeType, $mimeType)) { + $this->mimeTypeSupportMap[$mimeType] = true; + return true; + } + } + $this->mimeTypeSupportMap[$mimeType] = false; + return false; } /** * Check if a preview can be generated for a file * - * @param \OC\Files\FileInfo $file + * @param \OCP\Files\FileInfo $file * @return bool */ - function isAvailable($file) { - return \OC\Preview::isAvailable($file); + public function isAvailable(\OCP\Files\FileInfo $file) { + if (!$this->config->getSystemValue('enable_previews', true)) { + return false; + } + + $this->registerCoreProviders(); + if (!$this->isMimeSupported($file->getMimetype())) { + return false; + } + + $mount = $file->getMountPoint(); + if ($mount and !$mount->getOption('previews', true)){ + return false; + } + + foreach ($this->providers as $supportedMimeType => $providers) { + if (preg_match($supportedMimeType, $file->getMimetype())) { + foreach ($providers as $closure) { + $provider = $closure(); + if (!($provider instanceof IProvider)) { + continue; + } + + /** @var $provider IProvider */ + if ($provider->isAvailable($file)) { + return true; + } + } + } + } + return false; + } + + /** + * List of enabled default providers + * + * The following providers are enabled by default: + * - OC\Preview\Image + * - OC\Preview\MarkDown + * - OC\Preview\MP3 + * - OC\Preview\TXT + * + * The following providers are disabled by default due to performance or privacy concerns: + * - OC\Preview\Font + * - OC\Preview\Illustrator + * - OC\Preview\Movie + * - OC\Preview\MSOfficeDoc + * - OC\Preview\MSOffice2003 + * - OC\Preview\MSOffice2007 + * - OC\Preview\OpenDocument + * - OC\Preview\PDF + * - OC\Preview\Photoshop + * - OC\Preview\Postscript + * - OC\Preview\StarOffice + * - OC\Preview\SVG + * - OC\Preview\TIFF + * + * @return array + */ + protected function getEnabledDefaultProvider() { + if ($this->defaultProviders !== null) { + return $this->defaultProviders; + } + + $this->defaultProviders = $this->config->getSystemValue('enabledPreviewProviders', [ + 'OC\Preview\Image', + 'OC\Preview\MarkDown', + 'OC\Preview\MP3', + 'OC\Preview\TXT', + ]); + return $this->defaultProviders; + } + + /** + * Register the default providers (if enabled) + * + * @param string $class + * @param string $mimeType + */ + protected function registerCoreProvider($class, $mimeType, $options = []) { + if (in_array(trim($class, '\\'), $this->getEnabledDefaultProvider())) { + $this->registerProvider($mimeType, function () use ($class, $options) { + return new $class($options); + }); + } + } + + /** + * Register the default providers (if enabled) + */ + protected function registerCoreProviders() { + if ($this->registeredCoreProviders) { + return; + } + $this->registeredCoreProviders = true; + + $this->registerCoreProvider('OC\Preview\TXT', '/text\/plain/'); + $this->registerCoreProvider('OC\Preview\MarkDown', '/text\/(x-)?markdown/'); + $this->registerCoreProvider('OC\Preview\Image', '/image\/(?!tiff$)(?!svg.*).*/'); + $this->registerCoreProvider('OC\Preview\MP3', '/audio\/mpeg/'); + + // SVG, Office and Bitmap require imagick + if (extension_loaded('imagick')) { + $checkImagick = new \Imagick(); + + $imagickProviders = [ + 'SVG' => ['mimetype' => '/image\/svg\+xml/', 'class' => '\OC\Preview\SVG'], + 'TIFF' => ['mimetype' => '/image\/tiff/', 'class' => '\OC\Preview\TIFF'], + 'PDF' => ['mimetype' => '/application\/pdf/', 'class' => '\OC\Preview\PDF'], + 'AI' => ['mimetype' => '/application\/illustrator/', 'class' => '\OC\Preview\Illustrator'], + 'PSD' => ['mimetype' => '/application\/x-photoshop/', 'class' => '\OC\Preview\Photoshop'], + 'EPS' => ['mimetype' => '/application\/postscript/', 'class' => '\OC\Preview\Postscript'], + 'TTF' => ['mimetype' => '/application\/(?:font-sfnt|x-font$)/', 'class' => '\OC\Preview\Font'], + ]; + + foreach ($imagickProviders as $queryFormat => $provider) { + $class = $provider['class']; + if (!in_array(trim($class, '\\'), $this->getEnabledDefaultProvider())) { + continue; + } + + if (count($checkImagick->queryFormats($queryFormat)) === 1) { + $this->registerCoreProvider($class, $provider['mimetype']); + } + } + + if (count($checkImagick->queryFormats('PDF')) === 1) { + // Office previews are currently not supported on Windows + if (!\OC_Util::runningOnWindows() && \OC_Helper::is_function_enabled('shell_exec')) { + $officeFound = is_string($this->config->getSystemValue('preview_libreoffice_path', null)); + + if (!$officeFound) { + //let's see if there is libreoffice or openoffice on this machine + $whichLibreOffice = shell_exec('command -v libreoffice'); + $officeFound = !empty($whichLibreOffice); + if (!$officeFound) { + $whichOpenOffice = shell_exec('command -v openoffice'); + $officeFound = !empty($whichOpenOffice); + } + } + + if ($officeFound) { + $this->registerCoreProvider('\OC\Preview\MSOfficeDoc', '/application\/msword/'); + $this->registerCoreProvider('\OC\Preview\MSOffice2003', '/application\/vnd.ms-.*/'); + $this->registerCoreProvider('\OC\Preview\MSOffice2007', '/application\/vnd.openxmlformats-officedocument.*/'); + $this->registerCoreProvider('\OC\Preview\OpenDocument', '/application\/vnd.oasis.opendocument.*/'); + $this->registerCoreProvider('\OC\Preview\StarOffice', '/application\/vnd.sun.xml.*/'); + } + } + } + } + + // Video requires avconv or ffmpeg and is therefor + // currently not supported on Windows. + if (in_array('OC\Preview\Movie', $this->getEnabledDefaultProvider()) && !\OC_Util::runningOnWindows()) { + $avconvBinary = \OC_Helper::findBinaryPath('avconv'); + $ffmpegBinary = ($avconvBinary) ? null : \OC_Helper::findBinaryPath('ffmpeg'); + + if ($avconvBinary || $ffmpegBinary) { + // FIXME // a bit hacky but didn't want to use subclasses + \OC\Preview\Movie::$avconvBinary = $avconvBinary; + \OC\Preview\Movie::$ffmpegBinary = $ffmpegBinary; + + $this->registerCoreProvider('\OC\Preview\Movie', '/video\/.*/'); + } + } } } diff --git a/lib/private/server.php b/lib/private/server.php index 4264c70905c..fd7a2bea2d1 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -45,8 +45,8 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('ContactsManager', function ($c) { return new ContactsManager(); }); - $this->registerService('PreviewManager', function ($c) { - return new PreviewManager(); + $this->registerService('PreviewManager', function (Server $c) { + return new PreviewManager($c->getConfig()); }); $this->registerService('TagMapper', function(Server $c) { return new TagMapper($c->getDatabaseConnection()); diff --git a/lib/public/iavatar.php b/lib/public/iavatar.php index 8f432c23fb8..984fe1075b4 100644 --- a/lib/public/iavatar.php +++ b/lib/public/iavatar.php @@ -16,7 +16,7 @@ interface IAvatar { /** * get the users avatar * @param int $size size in px of the avatar, avatars are square, defaults to 64 - * @return boolean|\OC_Image containing the avatar or false if there's no image + * @return boolean|\OCP\IImage containing the avatar or false if there's no image */ function get($size = 64); @@ -29,7 +29,7 @@ interface IAvatar { /** * sets the users avatar - * @param \OC_Image|resource|string $data OC_Image, imagedata or path to set a new avatar + * @param \OCP\IImage|resource|string $data An image object, imagedata or path to set a new avatar * @throws \Exception if the provided file is not a jpg or png image * @throws \Exception if the provided image is not valid * @throws \OC\NotSquareException if the image is not square diff --git a/lib/public/iimage.php b/lib/public/iimage.php new file mode 100644 index 00000000000..01d8e101330 --- /dev/null +++ b/lib/public/iimage.php @@ -0,0 +1,146 @@ +<?php +/** + * ownCloud + * + * @author Joas Schilling + * @copyright 2015 Joas Schilling nickvergessen@owncloud.com + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP; + +/** + * Class for basic image manipulation + */ +interface IImage { + /** + * Determine whether the object contains an image resource. + * + * @return bool + */ + public function valid(); + + /** + * Returns the MIME type of the image or an empty string if no image is loaded. + * + * @return string + */ + public function mimeType(); + + /** + * Returns the width of the image or -1 if no image is loaded. + * + * @return int + */ + public function width(); + + /** + * Returns the height of the image or -1 if no image is loaded. + * + * @return int + */ + public function height(); + + /** + * Returns the width when the image orientation is top-left. + * + * @return int + */ + public function widthTopLeft(); + + /** + * Returns the height when the image orientation is top-left. + * + * @return int + */ + public function heightTopLeft(); + + /** + * Outputs the image. + * + * @param string $mimeType + * @return bool + */ + public function show($mimeType = null); + + /** + * Saves the image. + * + * @param string $filePath + * @param string $mimeType + * @return bool + */ + public function save($filePath = null, $mimeType = null); + + /** + * @return resource Returns the image resource in any. + */ + public function resource(); + + /** + * @return string Returns the raw image data. + */ + public function data(); + + /** + * (I'm open for suggestions on better method name ;) + * Get the orientation based on EXIF data. + * + * @return int The orientation or -1 if no EXIF data is available. + */ + public function getOrientation(); + + /** + * (I'm open for suggestions on better method name ;) + * Fixes orientation based on EXIF data. + * + * @return bool. + */ + public function fixOrientation(); + + /** + * Resizes the image preserving ratio. + * + * @param integer $maxSize The maximum size of either the width or height. + * @return bool + */ + public function resize($maxSize); + + /** + * @param int $width + * @param int $height + * @return bool + */ + public function preciseResize($width, $height); + + /** + * Crops the image to the middle square. If the image is already square it just returns. + * + * @param int $size maximum size for the result (optional) + * @return bool for success or failure + */ + public function centerCrop($size = 0); + + /** + * Crops the image from point $x$y with dimension $wx$h. + * + * @param int $x Horizontal position + * @param int $y Vertical position + * @param int $w Width + * @param int $h Height + * @return bool for success or failure + */ + public function crop($x, $y, $w, $h); + + /** + * Resizes the image to fit within a boundary while preserving ratio. + * + * @param integer $maxWidth + * @param integer $maxHeight + * @return bool + */ + public function fitIn($maxWidth, $maxHeight); +} diff --git a/lib/public/ipreview.php b/lib/public/ipreview.php index cc756ef80d3..202b0d03948 100644 --- a/lib/public/ipreview.php +++ b/lib/public/ipreview.php @@ -36,8 +36,30 @@ namespace OCP; /** * This class provides functions to render and show thumbnails and previews of files */ -interface IPreview -{ +interface IPreview { + /** + * In order to improve lazy loading a closure can be registered which will be + * called in case preview providers are actually requested + * + * $callable has to return an instance of \OCP\Preview\IProvider + * + * @param string $mimeTypeRegex Regex with the mime types that are supported by this provider + * @param \Closure $callable + * @return void + */ + public function registerProvider($mimeTypeRegex, \Closure $callable); + + /** + * Get all providers + * @return array + */ + public function getProviders(); + + /** + * Does the manager have any providers + * @return bool + */ + public function hasProviders(); /** * Return a preview of a file @@ -45,9 +67,9 @@ interface IPreview * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image * @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly - * @return \OCP\Image + * @return \OCP\IImage */ - function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false); + public function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false); /** @@ -55,7 +77,7 @@ interface IPreview * @param string $mimeType * @return boolean */ - function isMimeSupported($mimeType = '*'); + public function isMimeSupported($mimeType = '*'); /** * Check if a preview can be generated for a file @@ -63,5 +85,5 @@ interface IPreview * @param \OCP\Files\FileInfo $file * @return bool */ - function isAvailable($file); + public function isAvailable(\OCP\Files\FileInfo $file); } diff --git a/lib/public/preview/iprovider.php b/lib/public/preview/iprovider.php new file mode 100644 index 00000000000..4318ecd37ac --- /dev/null +++ b/lib/public/preview/iprovider.php @@ -0,0 +1,39 @@ +<?php +/** + * ownCloud + * + * @author Joas Schilling + * @copyright 2015 Joas Schilling nickvergessen@owncloud.com + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace OCP\Preview; + +interface IProvider { + /** + * @return string Regex with the mimetypes that are supported by this provider + */ + public function getMimeType(); + + /** + * Check if a preview can be generated for $path + * + * @param \OCP\Files\FileInfo $file + * @return bool + */ + public function isAvailable(\OCP\Files\FileInfo $file); + + /** + * get thumbnail for file at path $path + * + * @param string $path Path of file + * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image + * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image + * @param bool $scalingup Disable/Enable upscaling of previews + * @param \OC\Files\View $fileview fileview object of user folder + * @return bool|\OCP\IImage false if no preview was generated + */ + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview); +} |