Merge pull request #14857 from owncloud/preview-provider-registration-in-manager
Preview provider registration in manager
This commit is contained in:
commit
afa8872955
|
@ -170,6 +170,7 @@ class ShareController extends Controller {
|
|||
$shareTmpl['filename'] = $file;
|
||||
$shareTmpl['directory_path'] = $linkItem['file_target'];
|
||||
$shareTmpl['mimetype'] = Filesystem::getMimeType($originalSharePath);
|
||||
$shareTmpl['previewSupported'] = \OC::$server->getPreviewManager()->isMimeSupported($shareTmpl['mimetype']);
|
||||
$shareTmpl['dirToken'] = $linkItem['token'];
|
||||
$shareTmpl['sharingToken'] = $token;
|
||||
$shareTmpl['server2serversharing'] = Helper::isOutgoingServer2serverShareEnabled();
|
||||
|
|
|
@ -19,11 +19,10 @@ OCP\Util::addScript('files', 'files');
|
|||
OCP\Util::addScript('files', 'filelist');
|
||||
OCP\Util::addscript('files', 'keyboardshortcuts');
|
||||
|
||||
$thumbSize=1024;
|
||||
$previewSupported = OC\Preview::isMimeSupported($_['mimetype']) ? 'true' : 'false';
|
||||
$thumbSize = 1024;
|
||||
?>
|
||||
|
||||
<?php if ( \OC\Preview::isMimeSupported($_['mimetype'])): /* This enables preview images for links (e.g. on Facebook, Google+, ...)*/?>
|
||||
<?php if ($_['previewSupported']): /* This enables preview images for links (e.g. on Facebook, Google+, ...)*/?>
|
||||
<link rel="image_src" href="<?php p(OCP\Util::linkToRoute( 'core_ajax_public_preview', array('x' => $thumbSize, 'y' => $thumbSize, 'file' => $_['directory_path'], 't' => $_['dirToken']))); ?>" />
|
||||
<?php endif; ?>
|
||||
|
||||
|
@ -38,7 +37,7 @@ $previewSupported = OC\Preview::isMimeSupported($_['mimetype']) ? 'true' : 'fals
|
|||
<input type="hidden" name="sharingToken" value="<?php p($_['sharingToken']) ?>" id="sharingToken">
|
||||
<input type="hidden" name="filename" value="<?php p($_['filename']) ?>" id="filename">
|
||||
<input type="hidden" name="mimetype" value="<?php p($_['mimetype']) ?>" id="mimetype">
|
||||
<input type="hidden" name="previewSupported" value="<?php p($previewSupported); ?>" id="previewSupported">
|
||||
<input type="hidden" name="previewSupported" value="<?php p($_['previewSupported'] ? 'true' : 'false'); ?>" id="previewSupported">
|
||||
<input type="hidden" name="mimetypeIcon" value="<?php p(OC_Helper::mimetypeIcon($_['mimetype'])); ?>" id="mimetypeIcon">
|
||||
<input type="hidden" name="filesize" value="<?php p($_['nonHumanFileSize']); ?>" id="filesize">
|
||||
<input type="hidden" name="maxSizeAnimateGif" value="<?php p($_['maxSizeAnimateGif']); ?>" id="maxSizeAnimateGif">
|
||||
|
|
|
@ -158,6 +158,7 @@ class ShareControllerTest extends \Test\TestCase {
|
|||
'fileSize' => '33 B',
|
||||
'nonHumanFileSize' => 33,
|
||||
'maxSizeAnimateGif' => 10,
|
||||
'previewSupported' => true,
|
||||
);
|
||||
|
||||
$csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
|
||||
|
|
|
@ -29,13 +29,12 @@ if ($maxX === 0 || $maxY === 0) {
|
|||
exit;
|
||||
}
|
||||
|
||||
$preview = new \OC\Preview(\OC_User::getUser(), 'files');
|
||||
|
||||
$info = \OC\Files\Filesystem::getFileInfo($file);
|
||||
|
||||
if (!$info instanceof OCP\Files\FileInfo || !$always && !$preview->isAvailable($info)) {
|
||||
if (!$info instanceof OCP\Files\FileInfo || !$always && !\OC::$server->getPreviewManager()->isAvailable($info)) {
|
||||
\OC_Response::setStatus(404);
|
||||
} else {
|
||||
$preview = new \OC\Preview(\OC_User::getUser(), 'files');
|
||||
$preview->setFile($file);
|
||||
$preview->setMaxX($maxX);
|
||||
$preview->setMaxY($maxY);
|
||||
|
|
|
@ -95,7 +95,7 @@ class AvatarController extends Controller {
|
|||
$avatar = $this->avatarManager->getAvatar($userId);
|
||||
$image = $avatar->get($size);
|
||||
|
||||
if ($image instanceof \OC_Image) {
|
||||
if ($image instanceof \OCP\IImage) {
|
||||
$resp = new DataDisplayResponse($image->data(),
|
||||
Http::STATUS_OK,
|
||||
['Content-Type' => $image->mimeType()]);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
if (!($preview instanceof \OCP\IImage)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->preview = $preview;
|
||||
$this->resizeAndCrop();
|
||||
|
||||
$previewPath = $this->getPreviewPath($fileId);
|
||||
$cachePath = $this->buildCachePath($fileId);
|
||||
|
||||
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());
|
||||
|
||||
break 2;
|
||||
}
|
||||
|
||||
$this->preview = $preview;
|
||||
$this->resizeAndCrop();
|
||||
|
||||
$previewPath = $this->getPreviewPath($fileId);
|
||||
$cachePath = $this->buildCachePath($fileId);
|
||||
|
||||
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());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -685,146 +684,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
|
||||
*/
|
||||
|
@ -914,60 +773,6 @@ class Preview {
|
|||
$preview->deleteAllPreviews();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ class TXT extends Provider {
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isAvailable($file) {
|
||||
public function isAvailable(\OCP\Files\FileInfo $file) {
|
||||
return $file->getSize() > 5;
|
||||
}
|
||||
|
||||
|
|
|
@ -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\/.*/');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -31,20 +31,24 @@ class Test_Image extends \Test\TestCase {
|
|||
public function testConstructDestruct() {
|
||||
$img = new \OC_Image(OC::$SERVERROOT.'/tests/data/testimage.png');
|
||||
$this->assertInstanceOf('\OC_Image', $img);
|
||||
$this->assertInstanceOf('\OCP\IImage', $img);
|
||||
unset($img);
|
||||
|
||||
$imgcreate = imagecreatefromjpeg(OC::$SERVERROOT.'/tests/data/testimage.jpg');
|
||||
$img = new \OC_Image($imgcreate);
|
||||
$this->assertInstanceOf('\OC_Image', $img);
|
||||
$this->assertInstanceOf('\OCP\IImage', $img);
|
||||
unset($img);
|
||||
|
||||
$base64 = base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif'));
|
||||
$img = new \OC_Image($base64);
|
||||
$this->assertInstanceOf('\OC_Image', $img);
|
||||
$this->assertInstanceOf('\OCP\IImage', $img);
|
||||
unset($img);
|
||||
|
||||
$img = new \OC_Image(null);
|
||||
$this->assertInstanceOf('\OC_Image', $img);
|
||||
$this->assertInstanceOf('\OCP\IImage', $img);
|
||||
unset($img);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue