2012-11-13 18:11:02 +04:00
|
|
|
<?php
|
|
|
|
/**
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Björn Schießle <schiessle@owncloud.com>
|
|
|
|
* @author Frank Karlitschek <frank@owncloud.org>
|
|
|
|
* @author Georg Ehrke <georg@owncloud.com>
|
|
|
|
* @author Joas Schilling <nickvergessen@owncloud.com>
|
|
|
|
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
|
|
|
* @author Lukas Reschke <lukas@owncloud.com>
|
|
|
|
* @author Morris Jobke <hey@morrisjobke.de>
|
2015-04-07 17:45:16 +03:00
|
|
|
* @author Olivier Paroz <owncloud@interfasys.ch>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Robin Appelman <icewind@owncloud.com>
|
|
|
|
* @author Robin McCorkell <rmccorkell@karoshi.org.uk>
|
|
|
|
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
|
|
|
* @author Tobias Kaminsky <tobias@kaminsky.me>
|
2013-05-10 01:59:16 +04:00
|
|
|
*
|
2015-03-26 13:44:34 +03:00
|
|
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
|
|
|
* @license AGPL-3.0
|
|
|
|
*
|
|
|
|
* This code is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License, version 3,
|
|
|
|
* as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* 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, version 3,
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
2013-11-28 21:52:58 +04:00
|
|
|
*
|
2013-04-25 13:18:45 +04:00
|
|
|
*/
|
2013-05-29 14:33:24 +04:00
|
|
|
namespace OC;
|
|
|
|
|
2014-04-04 13:37:47 +04:00
|
|
|
use OC\Preview\Provider;
|
2015-03-05 18:07:42 +03:00
|
|
|
use OCP\Files\FileInfo;
|
2014-08-09 12:39:12 +04:00
|
|
|
use OCP\Files\NotFoundException;
|
2014-04-04 13:37:47 +04:00
|
|
|
|
2013-05-29 14:33:24 +04:00
|
|
|
class Preview {
|
2013-07-10 19:57:04 +04:00
|
|
|
//the thumbnail folder
|
2013-04-25 13:18:45 +04:00
|
|
|
const THUMBNAILS_FOLDER = 'thumbnails';
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
//config
|
2013-07-11 21:03:21 +04:00
|
|
|
private $maxScaleFactor;
|
|
|
|
private $configMaxX;
|
|
|
|
private $configMaxY;
|
2012-11-13 18:11:02 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
//fileview object
|
2013-08-19 14:16:55 +04:00
|
|
|
private $fileView = null;
|
|
|
|
private $userView = null;
|
2013-05-10 01:59:16 +04:00
|
|
|
|
|
|
|
//vars
|
|
|
|
private $file;
|
|
|
|
private $maxX;
|
|
|
|
private $maxY;
|
2014-04-04 18:21:50 +04:00
|
|
|
private $scalingUp;
|
|
|
|
private $mimeType;
|
2014-04-29 19:07:10 +04:00
|
|
|
private $keepAspect = false;
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2014-03-11 17:21:27 +04:00
|
|
|
//filemapper used for deleting previews
|
|
|
|
// index is path, value is fileinfo
|
|
|
|
static public $deleteFileMapper = array();
|
2014-08-26 14:41:03 +04:00
|
|
|
static public $deleteChildrenMapper = array();
|
2014-03-11 17:21:27 +04:00
|
|
|
|
2013-09-05 01:45:11 +04:00
|
|
|
/**
|
2014-04-04 13:37:47 +04:00
|
|
|
* preview images object
|
|
|
|
*
|
2015-03-13 12:10:11 +03:00
|
|
|
* @var \OCP\IImage
|
2013-09-05 01:45:11 +04:00
|
|
|
*/
|
2013-05-10 01:59:16 +04:00
|
|
|
private $preview;
|
2012-11-13 18:11:02 +04:00
|
|
|
|
2014-02-27 16:15:18 +04:00
|
|
|
/**
|
|
|
|
* @var \OCP\Files\FileInfo
|
|
|
|
*/
|
|
|
|
protected $info;
|
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* check if thumbnail or bigger version of thumbnail of file is cached
|
2013-07-11 21:21:37 +04:00
|
|
|
* @param string $user userid - if no user is given, OC_User::getUser will be used
|
|
|
|
* @param string $root path of root
|
|
|
|
* @param string $file The path to the file where you want a thumbnail from
|
|
|
|
* @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
|
2013-07-30 14:29:12 +04:00
|
|
|
* @param bool $scalingUp Disable/Enable upscaling of previews
|
2014-04-21 17:44:54 +04:00
|
|
|
* @throws \Exception
|
2013-11-28 21:52:58 +04:00
|
|
|
* @return mixed (bool / string)
|
2014-02-27 16:15:18 +04:00
|
|
|
* false if thumbnail does not exist
|
|
|
|
* path to thumbnail if thumbnail exists
|
|
|
|
*/
|
|
|
|
public function __construct($user = '', $root = '/', $file = '', $maxX = 1, $maxY = 1, $scalingUp = true) {
|
2013-11-28 21:52:58 +04:00
|
|
|
//init fileviews
|
2014-02-27 16:15:18 +04:00
|
|
|
if ($user === '') {
|
2013-11-28 21:52:58 +04:00
|
|
|
$user = \OC_User::getUser();
|
|
|
|
}
|
|
|
|
$this->fileView = new \OC\Files\View('/' . $user . '/' . $root);
|
|
|
|
$this->userView = new \OC\Files\View('/' . $user);
|
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
//set config
|
2015-04-07 17:45:16 +03:00
|
|
|
$this->configMaxX = \OC::$server->getConfig()->getSystemValue('preview_max_x', 2048);
|
|
|
|
$this->configMaxY = \OC::$server->getConfig()->getSystemValue('preview_max_y', 2048);
|
|
|
|
$this->maxScaleFactor = \OC::$server->getConfig()->getSystemValue('preview_max_scale_factor', 2);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
//save parameters
|
2013-07-10 19:57:04 +04:00
|
|
|
$this->setFile($file);
|
|
|
|
$this->setMaxX($maxX);
|
|
|
|
$this->setMaxY($maxY);
|
2013-07-30 14:29:12 +04:00
|
|
|
$this->setScalingUp($scalingUp);
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
$this->preview = null;
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
//check if there are preview backends
|
2015-03-12 12:48:52 +03:00
|
|
|
if (!\OC::$server->getPreviewManager()->hasProviders() && \OC::$server->getConfig()->getSystemValue('enable_previews', true)) {
|
2013-07-10 19:57:04 +04:00
|
|
|
\OC_Log::write('core', 'No preview providers exist', \OC_Log::ERROR);
|
|
|
|
throw new \Exception('No preview providers');
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* returns the path of the file you want a thumbnail from
|
2013-05-10 01:59:16 +04:00
|
|
|
* @return string
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2014-04-03 14:00:53 +04:00
|
|
|
public function getFile() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return $this->file;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* returns the max width of the preview
|
2013-05-10 01:59:16 +04:00
|
|
|
* @return integer
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getMaxX() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return $this->maxX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* returns the max height of the preview
|
2013-05-10 01:59:16 +04:00
|
|
|
* @return integer
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getMaxY() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return $this->maxY;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* returns whether or not scalingup is enabled
|
2013-05-10 01:59:16 +04:00
|
|
|
* @return bool
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-07-30 14:29:12 +04:00
|
|
|
public function getScalingUp() {
|
2014-04-04 18:21:50 +04:00
|
|
|
return $this->scalingUp;
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* returns the name of the thumbnailfolder
|
2013-05-10 01:59:16 +04:00
|
|
|
* @return string
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-07-10 19:57:04 +04:00
|
|
|
public function getThumbnailsFolder() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return self::THUMBNAILS_FOLDER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* returns the max scale factor
|
2014-02-06 19:30:58 +04:00
|
|
|
* @return string
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getMaxScaleFactor() {
|
2013-07-11 21:03:21 +04:00
|
|
|
return $this->maxScaleFactor;
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* returns the max width set in ownCloud's config
|
2014-02-06 19:30:58 +04:00
|
|
|
* @return string
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getConfigMaxX() {
|
2013-07-11 21:03:21 +04:00
|
|
|
return $this->configMaxX;
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* returns the max height set in ownCloud's config
|
2014-02-06 19:30:58 +04:00
|
|
|
* @return string
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getConfigMaxY() {
|
2013-07-11 21:03:21 +04:00
|
|
|
return $this->configMaxY;
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2014-04-21 17:44:54 +04:00
|
|
|
/**
|
|
|
|
* @return false|Files\FileInfo|\OCP\Files\FileInfo
|
|
|
|
*/
|
2014-02-27 16:15:18 +04:00
|
|
|
protected function getFileInfo() {
|
2014-03-11 17:21:27 +04:00
|
|
|
$absPath = $this->fileView->getAbsolutePath($this->file);
|
|
|
|
$absPath = Files\Filesystem::normalizePath($absPath);
|
|
|
|
if(array_key_exists($absPath, self::$deleteFileMapper)) {
|
|
|
|
$this->info = self::$deleteFileMapper[$absPath];
|
|
|
|
} else if (!$this->info) {
|
2014-02-27 16:15:18 +04:00
|
|
|
$this->info = $this->fileView->getFileInfo($this->file);
|
|
|
|
}
|
|
|
|
return $this->info;
|
|
|
|
}
|
|
|
|
|
2014-08-26 14:41:03 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array|null
|
|
|
|
*/
|
|
|
|
private function getChildren() {
|
|
|
|
$absPath = $this->fileView->getAbsolutePath($this->file);
|
|
|
|
$absPath = Files\Filesystem::normalizePath($absPath);
|
|
|
|
|
|
|
|
if (array_key_exists($absPath, self::$deleteChildrenMapper)) {
|
|
|
|
return self::$deleteChildrenMapper[$absPath];
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* set the path of the file you want a thumbnail from
|
2013-07-11 21:21:37 +04:00
|
|
|
* @param string $file
|
2015-01-08 20:33:35 +03:00
|
|
|
* @return $this
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-07-10 19:57:04 +04:00
|
|
|
public function setFile($file) {
|
|
|
|
$this->file = $file;
|
2014-02-27 16:15:18 +04:00
|
|
|
$this->info = null;
|
2015-01-08 20:33:35 +03:00
|
|
|
|
2013-11-28 21:52:58 +04:00
|
|
|
if ($file !== '') {
|
2014-03-13 15:32:02 +04:00
|
|
|
$this->getFileInfo();
|
2015-01-08 20:33:35 +03:00
|
|
|
if($this->info instanceof \OCP\Files\FileInfo) {
|
2014-04-04 18:21:50 +04:00
|
|
|
$this->mimeType = $this->info->getMimetype();
|
2014-03-13 15:32:02 +04:00
|
|
|
}
|
2013-11-28 21:52:58 +04:00
|
|
|
}
|
2013-07-10 19:57:04 +04:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2013-11-28 22:05:43 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* set mime type explicitly
|
2014-04-04 18:21:50 +04:00
|
|
|
* @param string $mimeType
|
2013-11-28 22:05:43 +04:00
|
|
|
*/
|
2014-04-04 18:21:50 +04:00
|
|
|
public function setMimetype($mimeType) {
|
|
|
|
$this->mimeType = $mimeType;
|
2013-11-28 21:52:58 +04:00
|
|
|
}
|
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* set the the max width of the preview
|
2013-07-11 21:21:37 +04:00
|
|
|
* @param int $maxX
|
2014-04-21 17:44:54 +04:00
|
|
|
* @throws \Exception
|
2014-05-12 00:51:30 +04:00
|
|
|
* @return \OC\Preview $this
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
|
|
|
public function setMaxX($maxX = 1) {
|
|
|
|
if ($maxX <= 0) {
|
2013-07-30 14:29:12 +04:00
|
|
|
throw new \Exception('Cannot set width of 0 or smaller!');
|
2013-07-10 19:57:04 +04:00
|
|
|
}
|
|
|
|
$configMaxX = $this->getConfigMaxX();
|
2014-02-27 16:15:18 +04:00
|
|
|
if (!is_null($configMaxX)) {
|
|
|
|
if ($maxX > $configMaxX) {
|
2015-04-07 17:45:16 +03:00
|
|
|
\OCP\Util::writeLog('core', 'maxX reduced from ' . $maxX . ' to ' . $configMaxX, \OCP\Util::DEBUG);
|
2013-07-10 19:57:04 +04:00
|
|
|
$maxX = $configMaxX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->maxX = $maxX;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* set the the max height of the preview
|
2013-07-11 21:21:37 +04:00
|
|
|
* @param int $maxY
|
2014-04-21 17:44:54 +04:00
|
|
|
* @throws \Exception
|
2014-05-12 00:51:30 +04:00
|
|
|
* @return \OC\Preview $this
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
|
|
|
public function setMaxY($maxY = 1) {
|
|
|
|
if ($maxY <= 0) {
|
2013-07-30 14:29:12 +04:00
|
|
|
throw new \Exception('Cannot set height of 0 or smaller!');
|
2013-07-10 19:57:04 +04:00
|
|
|
}
|
|
|
|
$configMaxY = $this->getConfigMaxY();
|
2014-02-27 16:15:18 +04:00
|
|
|
if (!is_null($configMaxY)) {
|
|
|
|
if ($maxY > $configMaxY) {
|
2015-04-07 17:45:16 +03:00
|
|
|
\OCP\Util::writeLog('core', 'maxX reduced from ' . $maxY . ' to ' . $configMaxY, \OCP\Util::DEBUG);
|
2013-07-10 19:57:04 +04:00
|
|
|
$maxY = $configMaxY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->maxY = $maxY;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* set whether or not scalingup is enabled
|
2013-07-30 14:29:12 +04:00
|
|
|
* @param bool $scalingUp
|
2014-05-12 00:51:30 +04:00
|
|
|
* @return \OC\Preview $this
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-07-30 14:29:12 +04:00
|
|
|
public function setScalingup($scalingUp) {
|
2014-02-27 16:15:18 +04:00
|
|
|
if ($this->getMaxScaleFactor() === 1) {
|
2013-07-30 14:29:12 +04:00
|
|
|
$scalingUp = false;
|
2013-07-10 19:57:04 +04:00
|
|
|
}
|
2014-04-04 18:21:50 +04:00
|
|
|
$this->scalingUp = $scalingUp;
|
2013-07-10 19:57:04 +04:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2014-08-26 14:41:03 +04:00
|
|
|
/**
|
|
|
|
* @param bool $keepAspect
|
|
|
|
* @return $this
|
|
|
|
*/
|
2014-04-29 19:07:10 +04:00
|
|
|
public function setKeepAspect($keepAspect) {
|
|
|
|
$this->keepAspect = $keepAspect;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* check if all parameters are valid
|
2013-07-11 21:21:37 +04:00
|
|
|
* @return bool
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-07-10 19:57:04 +04:00
|
|
|
public function isFileValid() {
|
|
|
|
$file = $this->getFile();
|
2014-02-27 16:15:18 +04:00
|
|
|
if ($file === '') {
|
2015-04-07 17:45:16 +03:00
|
|
|
\OCP\Util::writeLog('core', 'No filename passed', \OCP\Util::DEBUG);
|
2013-07-10 19:57:04 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-02-27 16:15:18 +04:00
|
|
|
if (!$this->fileView->file_exists($file)) {
|
2015-04-07 17:45:16 +03:00
|
|
|
\OCP\Util::writeLog('core', 'File:"' . $file . '" not found', \OCP\Util::DEBUG);
|
2013-07-10 19:57:04 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* deletes previews of a file with specific x and y
|
2013-05-10 01:59:16 +04:00
|
|
|
* @return bool
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function deletePreview() {
|
2015-04-07 17:45:16 +03:00
|
|
|
$fileInfo = $this->getFileInfo();
|
2014-03-13 15:32:02 +04:00
|
|
|
if($fileInfo !== null && $fileInfo !== false) {
|
|
|
|
$fileId = $fileInfo->getId();
|
2013-05-29 14:01:43 +04:00
|
|
|
|
2014-04-29 19:07:10 +04:00
|
|
|
$previewPath = $this->buildCachePath($fileId);
|
2014-03-13 15:32:02 +04:00
|
|
|
return $this->userView->unlink($previewPath);
|
|
|
|
}
|
|
|
|
return false;
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* deletes all previews of a file
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function deleteAllPreviews() {
|
2014-08-26 14:41:03 +04:00
|
|
|
$toDelete = $this->getChildren();
|
2015-03-05 18:07:42 +03:00
|
|
|
$toDelete[] = $this->getFileInfo();
|
2014-08-26 14:41:03 +04:00
|
|
|
|
|
|
|
foreach ($toDelete as $delete) {
|
2015-03-05 18:07:42 +03:00
|
|
|
if ($delete instanceof FileInfo) {
|
2014-08-26 14:41:03 +04:00
|
|
|
/** @var \OCP\Files\FileInfo $delete */
|
|
|
|
$fileId = $delete->getId();
|
|
|
|
|
2015-03-05 18:07:42 +03:00
|
|
|
// getId() might return null, e.g. when the file is a
|
|
|
|
// .ocTransferId*.part file from chunked file upload.
|
|
|
|
if (!empty($fileId)) {
|
|
|
|
$previewPath = $this->getPreviewPath($fileId);
|
|
|
|
$this->userView->deleteAll($previewPath);
|
|
|
|
$this->userView->rmdir($previewPath);
|
|
|
|
}
|
2014-08-26 14:41:03 +04:00
|
|
|
}
|
2014-03-13 15:32:02 +04:00
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-04-07 17:45:16 +03:00
|
|
|
* Checks if thumbnail or bigger version of thumbnail of file is already cached
|
|
|
|
*
|
2014-04-02 20:32:32 +04:00
|
|
|
* @param int $fileId fileId of the original image
|
2014-04-02 19:59:39 +04:00
|
|
|
* @return string|false path to thumbnail if it exists or false
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2014-04-04 18:21:50 +04:00
|
|
|
public function isCached($fileId) {
|
2014-02-27 16:15:18 +04:00
|
|
|
if (is_null($fileId)) {
|
2013-07-12 13:50:24 +04:00
|
|
|
return false;
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
// This gives us a calculated path to a preview of asked dimensions
|
|
|
|
// thumbnailFolder/fileId/my_image-<maxX>-<maxY>.png
|
2014-04-29 19:07:10 +04:00
|
|
|
$preview = $this->buildCachePath($fileId);
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
// This checks if a preview exists at that location
|
2014-04-29 19:07:10 +04:00
|
|
|
if ($this->userView->file_exists($preview)) {
|
|
|
|
return $preview;
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2014-04-02 20:32:32 +04:00
|
|
|
return $this->isCachedBigger($fileId);
|
2014-04-02 19:59:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-04-07 17:45:16 +03:00
|
|
|
* Checks if a bigger version of a file preview is cached and if not
|
|
|
|
* return the preview of max allowed dimensions
|
|
|
|
*
|
2014-04-02 20:32:32 +04:00
|
|
|
* @param int $fileId fileId of the original image
|
2015-04-07 17:45:16 +03:00
|
|
|
*
|
2014-04-02 19:59:39 +04:00
|
|
|
* @return string|false path to bigger thumbnail if it exists or false
|
2015-04-07 17:45:16 +03:00
|
|
|
*/
|
2014-04-02 20:32:32 +04:00
|
|
|
private function isCachedBigger($fileId) {
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2014-02-27 16:15:18 +04:00
|
|
|
if (is_null($fileId)) {
|
2013-07-12 13:50:24 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-04-02 19:59:39 +04:00
|
|
|
$maxX = $this->getMaxX();
|
|
|
|
|
2014-04-02 20:32:32 +04:00
|
|
|
//array for usable cached thumbnails
|
2015-04-07 17:45:16 +03:00
|
|
|
// FIXME: Checking only the width could lead to issues
|
2014-04-02 20:32:32 +04:00
|
|
|
$possibleThumbnails = $this->getPossibleThumbnails($fileId);
|
|
|
|
|
|
|
|
foreach ($possibleThumbnails as $width => $path) {
|
2015-04-07 17:45:16 +03:00
|
|
|
if ($width === 'max' || $width < $maxX) {
|
2014-04-02 20:32:32 +04:00
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
return $path;
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
// At this stage, we didn't find a preview, so if the folder is not empty,
|
|
|
|
// we return the max preview we generated on the first run
|
|
|
|
if ($possibleThumbnails) {
|
|
|
|
return $possibleThumbnails['max'];
|
|
|
|
}
|
|
|
|
|
2014-04-02 20:32:32 +04:00
|
|
|
return false;
|
|
|
|
}
|
2014-04-04 13:37:47 +04:00
|
|
|
|
2014-04-02 20:32:32 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* get possible bigger thumbnails of the given image
|
2014-04-02 20:32:32 +04:00
|
|
|
* @param int $fileId fileId of the original image
|
2014-05-11 21:13:51 +04:00
|
|
|
* @return array an array of paths to bigger thumbnails
|
2014-04-02 20:32:32 +04:00
|
|
|
*/
|
|
|
|
private function getPossibleThumbnails($fileId) {
|
2014-04-02 19:59:39 +04:00
|
|
|
|
|
|
|
if (is_null($fileId)) {
|
2014-04-02 20:32:32 +04:00
|
|
|
return array();
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2014-08-26 18:43:08 +04:00
|
|
|
$previewPath = $this->getPreviewPath($fileId);
|
2014-04-02 20:32:32 +04:00
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
$wantedAspectRatio = (float)($this->getMaxX() / $this->getMaxY());
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
//array for usable cached thumbnails
|
2013-07-30 14:29:12 +04:00
|
|
|
$possibleThumbnails = array();
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-08-19 14:16:55 +04:00
|
|
|
$allThumbnails = $this->userView->getDirectoryContent($previewPath);
|
2014-02-27 16:15:18 +04:00
|
|
|
foreach ($allThumbnails as $thumbnail) {
|
2013-07-12 13:50:24 +04:00
|
|
|
$name = rtrim($thumbnail['name'], '.png');
|
2015-04-07 17:45:16 +03:00
|
|
|
// Always add the max preview to the array
|
|
|
|
if (strpos($name, 'max')) {
|
|
|
|
$possibleThumbnails['max'] = $thumbnail['path'];
|
|
|
|
continue;
|
|
|
|
}
|
2014-04-02 20:32:32 +04:00
|
|
|
list($x, $y, $aspectRatio) = $this->getDimensionsFromFilename($name);
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2014-04-03 14:00:53 +04:00
|
|
|
if (abs($aspectRatio - $wantedAspectRatio) >= 0.000001
|
2014-04-02 20:32:32 +04:00
|
|
|
|| $this->unscalable($x, $y)
|
|
|
|
) {
|
2013-04-25 13:18:45 +04:00
|
|
|
continue;
|
|
|
|
}
|
2013-07-30 14:29:12 +04:00
|
|
|
$possibleThumbnails[$x] = $thumbnail['path'];
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-07-30 14:29:12 +04:00
|
|
|
ksort($possibleThumbnails);
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2014-04-02 20:32:32 +04:00
|
|
|
return $possibleThumbnails;
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2014-04-21 17:44:54 +04:00
|
|
|
/**
|
|
|
|
* @param string $name
|
|
|
|
* @return array
|
|
|
|
*/
|
2014-04-02 20:32:32 +04:00
|
|
|
private function getDimensionsFromFilename($name) {
|
|
|
|
$size = explode('-', $name);
|
|
|
|
$x = (int) $size[0];
|
|
|
|
$y = (int) $size[1];
|
|
|
|
$aspectRatio = (float) ($x / $y);
|
2014-04-04 18:21:50 +04:00
|
|
|
return array($x, $y, $aspectRatio);
|
2014-04-02 20:32:32 +04:00
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2014-04-21 17:44:54 +04:00
|
|
|
/**
|
|
|
|
* @param int $x
|
|
|
|
* @param int $y
|
|
|
|
* @return bool
|
|
|
|
*/
|
2014-04-02 20:32:32 +04:00
|
|
|
private function unscalable($x, $y) {
|
2014-05-19 19:50:53 +04:00
|
|
|
|
2014-04-02 20:32:32 +04:00
|
|
|
$maxX = $this->getMaxX();
|
|
|
|
$maxY = $this->getMaxY();
|
|
|
|
$scalingUp = $this->getScalingUp();
|
|
|
|
$maxScaleFactor = $this->getMaxScaleFactor();
|
2014-05-19 19:50:53 +04:00
|
|
|
|
2014-04-02 20:32:32 +04:00
|
|
|
if ($x < $maxX || $y < $maxY) {
|
|
|
|
if ($scalingUp) {
|
|
|
|
$scalefactor = $maxX / $x;
|
|
|
|
if ($scalefactor > $maxScaleFactor) {
|
|
|
|
return true;
|
|
|
|
}
|
2014-02-27 16:15:18 +04:00
|
|
|
} else {
|
2014-04-02 20:32:32 +04:00
|
|
|
return true;
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
|
|
|
}
|
2014-04-02 19:34:48 +04:00
|
|
|
return false;
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2012-11-13 19:14:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
/**
|
2015-04-07 17:45:16 +03:00
|
|
|
* Returns a preview of a file
|
|
|
|
*
|
|
|
|
* The cache is searched first and if nothing usable was found then a preview is
|
|
|
|
* generated by one of the providers
|
|
|
|
*
|
2015-03-13 12:10:11 +03:00
|
|
|
* @return \OCP\IImage
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getPreview() {
|
2014-02-27 16:15:18 +04:00
|
|
|
if (!is_null($this->preview) && $this->preview->valid()) {
|
2013-07-10 19:57:04 +04:00
|
|
|
return $this->preview;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->preview = null;
|
2015-04-07 17:45:16 +03:00
|
|
|
$fileInfo = $this->getFileInfo();
|
|
|
|
if ($fileInfo === null || $fileInfo === false) {
|
2014-03-13 15:32:02 +04:00
|
|
|
return new \OC_Image();
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
$fileId = $fileInfo->getId();
|
2014-04-02 20:32:32 +04:00
|
|
|
$cached = $this->isCached($fileId);
|
2014-02-27 16:15:18 +04:00
|
|
|
if ($cached) {
|
2015-04-07 17:45:16 +03:00
|
|
|
$this->getCachedPreview($fileId, $cached);
|
2013-07-10 19:57:04 +04:00
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2014-02-27 16:15:18 +04:00
|
|
|
if (is_null($this->preview)) {
|
2015-04-07 17:45:16 +03:00
|
|
|
$this->generatePreview($fileId);
|
2013-07-10 19:57:04 +04:00
|
|
|
}
|
2013-06-26 12:57:37 +04:00
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
// We still don't have a preview, so we generate an empty object which can't be displayed
|
2014-02-27 16:15:18 +04:00
|
|
|
if (is_null($this->preview)) {
|
2013-07-10 19:57:04 +04:00
|
|
|
$this->preview = new \OC_Image();
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2013-07-10 19:57:04 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
return $this->preview;
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2012-11-13 18:11:02 +04:00
|
|
|
|
|
|
|
/**
|
2014-09-19 15:26:41 +04:00
|
|
|
* @param null|string $mimeType
|
|
|
|
* @throws NotFoundException
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2014-04-29 19:07:10 +04:00
|
|
|
public function showPreview($mimeType = null) {
|
2014-09-19 15:26:41 +04:00
|
|
|
// Check if file is valid
|
|
|
|
if($this->isFileValid() === false) {
|
|
|
|
throw new NotFoundException('File not found.');
|
|
|
|
}
|
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
\OCP\Response::enableCaching(3600 * 24); // 24 hours
|
2014-02-27 16:15:18 +04:00
|
|
|
if (is_null($this->preview)) {
|
2013-07-10 19:57:04 +04:00
|
|
|
$this->getPreview();
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2015-03-13 12:10:11 +03:00
|
|
|
if ($this->preview instanceof \OCP\IImage) {
|
2014-09-21 19:30:29 +04:00
|
|
|
$this->preview->show($mimeType);
|
|
|
|
}
|
2013-07-11 12:10:07 +04:00
|
|
|
}
|
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
/**
|
|
|
|
* Retrieves the preview from the cache and resizes it if necessary
|
|
|
|
*
|
|
|
|
* @param int $fileId fileId of the original image
|
|
|
|
* @param string $cached the path to the cached preview
|
|
|
|
*/
|
|
|
|
private function getCachedPreview($fileId, $cached) {
|
|
|
|
$stream = $this->userView->fopen($cached, 'r');
|
|
|
|
$this->preview = null;
|
|
|
|
if ($stream) {
|
|
|
|
$image = new \OC_Image();
|
|
|
|
$image->loadFromFileHandle($stream);
|
|
|
|
|
|
|
|
$this->preview = $image->valid() ? $image : null;
|
|
|
|
|
|
|
|
$maxX = (int)$this->getMaxX();
|
|
|
|
$maxY = (int)$this->getMaxY();
|
|
|
|
$previewX = (int)$this->preview->width();
|
|
|
|
$previewY = (int)$this->preview->height();
|
|
|
|
|
|
|
|
if ($previewX !== $maxX && $previewY !== $maxY) {
|
|
|
|
$this->resizeAndStore($fileId);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose($stream);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resizes, crops, fixes orientation and stores in the cache
|
|
|
|
*
|
|
|
|
* @param int $fileId fileId of the original image
|
|
|
|
*/
|
|
|
|
private function resizeAndStore($fileId) {
|
|
|
|
// Resize and store
|
|
|
|
$this->resizeAndCrop();
|
|
|
|
// We save a copy in the cache to speed up future calls
|
|
|
|
$cachePath = $this->buildCachePath($fileId);
|
|
|
|
$this->userView->file_put_contents($cachePath, $this->preview->data());
|
|
|
|
}
|
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* resize, crop and fix orientation
|
2015-04-07 17:45:16 +03:00
|
|
|
*
|
|
|
|
* @param bool $max
|
2014-02-27 16:15:18 +04:00
|
|
|
*/
|
2015-04-07 17:45:16 +03:00
|
|
|
private function resizeAndCrop($max = false) {
|
2013-05-10 01:59:16 +04:00
|
|
|
$image = $this->preview;
|
2015-04-07 17:45:16 +03:00
|
|
|
|
|
|
|
list($x, $y, $scalingUp, $maxScaleFactor) = $this->getResizeData($max);
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2015-03-13 12:10:11 +03:00
|
|
|
if (!($image instanceof \OCP\IImage)) {
|
2015-04-07 17:45:16 +03:00
|
|
|
\OCP\Util::writeLog('core', '$this->preview is not an instance of OC_Image', \OCP\Util::DEBUG);
|
2013-05-10 01:59:16 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
$realX = (int)$image->width();
|
|
|
|
$realY = (int)$image->height();
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2014-07-29 19:23:44 +04:00
|
|
|
// compute $maxY and $maxX using the aspect of the generated preview
|
2014-04-29 19:07:10 +04:00
|
|
|
if ($this->keepAspect) {
|
2014-07-29 19:23:44 +04:00
|
|
|
$ratio = $realX / $realY;
|
|
|
|
if($x / $ratio < $y) {
|
|
|
|
// width restricted
|
|
|
|
$y = $x / $ratio;
|
|
|
|
} else {
|
|
|
|
$x = $y * $ratio;
|
|
|
|
}
|
2014-04-29 19:07:10 +04:00
|
|
|
}
|
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
// The preview already has the asked dimensions
|
2014-04-04 18:21:50 +04:00
|
|
|
if ($x === $realX && $y === $realY) {
|
2013-07-10 19:57:04 +04:00
|
|
|
$this->preview = $image;
|
2013-08-19 14:16:55 +04:00
|
|
|
return;
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
$factorX = $x / $realX;
|
|
|
|
$factorY = $y / $realY;
|
2013-07-10 19:57:04 +04:00
|
|
|
|
2014-02-27 16:15:18 +04:00
|
|
|
if ($factorX >= $factorY) {
|
2013-05-10 01:59:16 +04:00
|
|
|
$factor = $factorX;
|
2014-02-27 16:15:18 +04:00
|
|
|
} else {
|
2013-05-10 01:59:16 +04:00
|
|
|
$factor = $factorY;
|
|
|
|
}
|
2013-07-10 19:57:04 +04:00
|
|
|
|
2014-02-27 16:15:18 +04:00
|
|
|
if ($scalingUp === false) {
|
|
|
|
if ($factor > 1) {
|
2013-07-10 19:57:04 +04:00
|
|
|
$factor = 1;
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2013-07-10 19:57:04 +04:00
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
if (!is_null($maxScaleFactor)) {
|
|
|
|
if ($factor > $maxScaleFactor) {
|
2015-04-07 17:45:16 +03:00
|
|
|
\OCP\Util::writeLog('core', 'scale factor reduced from ' . $factor . ' to ' . $maxScaleFactor, \OCP\Util::DEBUG);
|
2014-04-04 18:21:50 +04:00
|
|
|
$factor = $maxScaleFactor;
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2012-11-13 18:11:02 +04:00
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
$newXSize = (int)($realX * $factor);
|
|
|
|
$newYSize = (int)($realY * $factor);
|
2013-07-10 19:57:04 +04:00
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
$image->preciseResize($newXSize, $newYSize);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
// The preview has been upscaled and now has the asked dimensions
|
2014-04-04 18:21:50 +04:00
|
|
|
if ($newXSize === $x && $newYSize === $y) {
|
2013-05-10 01:59:16 +04:00
|
|
|
$this->preview = $image;
|
|
|
|
return;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
// One dimension of the upscaled preview is too big
|
2014-04-04 18:21:50 +04:00
|
|
|
if ($newXSize >= $x && $newYSize >= $y) {
|
|
|
|
$cropX = floor(abs($x - $newXSize) * 0.5);
|
2013-07-10 19:57:04 +04:00
|
|
|
//don't crop previews on the Y axis, this sucks if it's a document.
|
2013-06-11 12:45:50 +04:00
|
|
|
//$cropY = floor(abs($y - $newYsize) * 0.5);
|
|
|
|
$cropY = 0;
|
2013-05-10 01:59:16 +04:00
|
|
|
|
|
|
|
$image->crop($cropX, $cropY, $x, $y);
|
2013-11-28 21:52:58 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
$this->preview = $image;
|
|
|
|
return;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
// One dimension of the upscaled preview is too small and we're allowed to scale up
|
2014-05-05 16:54:34 +04:00
|
|
|
if (($newXSize < $x || $newYSize < $y) && $scalingUp) {
|
2014-04-04 18:21:50 +04:00
|
|
|
if ($newXSize > $x) {
|
|
|
|
$cropX = floor(($newXSize - $x) * 0.5);
|
|
|
|
$image->crop($cropX, 0, $x, $newYSize);
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
if ($newYSize > $y) {
|
|
|
|
$cropY = floor(($newYSize - $y) * 0.5);
|
|
|
|
$image->crop(0, $cropY, $newXSize, $y);
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
$newXSize = (int)$image->width();
|
|
|
|
$newYSize = (int)$image->height();
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
//create transparent background layer
|
2014-04-04 18:21:50 +04:00
|
|
|
$backgroundLayer = imagecreatetruecolor($x, $y);
|
|
|
|
$white = imagecolorallocate($backgroundLayer, 255, 255, 255);
|
|
|
|
imagefill($backgroundLayer, 0, 0, $white);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
$image = $image->resource();
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
$mergeX = floor(abs($x - $newXSize) * 0.5);
|
|
|
|
$mergeY = floor(abs($y - $newYSize) * 0.5);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
imagecopy($backgroundLayer, $image, $mergeX, $mergeY, 0, 0, $newXSize, $newYSize);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-17 13:28:49 +04:00
|
|
|
//$black = imagecolorallocate(0,0,0);
|
|
|
|
//imagecolortransparent($transparentlayer, $black);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2014-04-04 18:21:50 +04:00
|
|
|
$image = new \OC_Image($backgroundLayer);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
$this->preview = $image;
|
2015-04-07 17:45:16 +03:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
return;
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
|
|
|
}
|
2012-11-13 18:11:02 +04:00
|
|
|
|
2015-04-07 17:45:16 +03:00
|
|
|
/**
|
|
|
|
* Returns data to be used to resize a preview
|
|
|
|
*
|
|
|
|
* @param $max
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
private function getResizeData($max) {
|
|
|
|
if (!$max) {
|
|
|
|
$x = $this->getMaxX();
|
|
|
|
$y = $this->getMaxY();
|
|
|
|
$scalingUp = $this->getScalingUp();
|
|
|
|
$maxScaleFactor = $this->getMaxScaleFactor();
|
|
|
|
} else {
|
|
|
|
$x = $this->configMaxX;
|
|
|
|
$y = $this->configMaxY;
|
|
|
|
$scalingUp = false;
|
|
|
|
$maxScaleFactor =1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return [$x, $y, $scalingUp, $maxScaleFactor];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the path to a preview based on its dimensions and aspect
|
|
|
|
*
|
|
|
|
* @param int $fileId
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
private function buildCachePath($fileId) {
|
|
|
|
$maxX = $this->getMaxX();
|
|
|
|
$maxY = $this->getMaxY();
|
|
|
|
|
|
|
|
$previewPath = $this->getPreviewPath($fileId);
|
|
|
|
$previewPath = $previewPath . strval($maxX) . '-' . strval($maxY);
|
|
|
|
if ($this->keepAspect) {
|
|
|
|
$previewPath .= '-with-aspect';
|
|
|
|
}
|
|
|
|
$previewPath .= '.png';
|
|
|
|
|
|
|
|
return $previewPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param int $fileId
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
private function getPreviewPath($fileId) {
|
|
|
|
return $this->getThumbnailsFolder() . '/' . $fileId . '/';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Asks the provider to send a preview of the file of maximum dimensions
|
|
|
|
* and after saving it in the cache, it is then resized to the asked dimensions
|
|
|
|
*
|
|
|
|
* This is only called once in order to generate a large PNG of dimensions defined in the
|
|
|
|
* configuration file. We'll be able to quickly resize it later on.
|
|
|
|
* We never upscale the original conversion as this will be done later by the resizing operation
|
|
|
|
*
|
|
|
|
* @param int $fileId fileId of the original image
|
|
|
|
*/
|
|
|
|
private function generatePreview($fileId) {
|
|
|
|
$file = $this->getFile();
|
|
|
|
$preview = null;
|
|
|
|
|
|
|
|
$previewProviders = \OC::$server->getPreviewManager()->getProviders();
|
|
|
|
foreach ($previewProviders as $supportedMimeType => $providers) {
|
|
|
|
if (!preg_match($supportedMimeType, $this->mimeType)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($providers as $closure) {
|
|
|
|
$provider = $closure();
|
|
|
|
if (!($provider instanceof \OCP\Preview\IProvider)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
\OCP\Util::writeLog(
|
|
|
|
'core', 'Generating preview for "' . $file . '" with "' . get_class($provider)
|
|
|
|
. '"', \OCP\Util::DEBUG
|
|
|
|
);
|
|
|
|
|
|
|
|
/** @var $provider Provider */
|
|
|
|
$preview = $provider->getThumbnail(
|
|
|
|
$file, $this->configMaxX, $this->configMaxY, $scalingUp = false, $this->fileView
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!($preview instanceof \OCP\IImage)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->preview = $preview;
|
|
|
|
$previewPath = $this->getPreviewPath($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 stores our large preview so that it can be used in subsequent resizing requests
|
|
|
|
$this->storeMaxPreview($previewPath);
|
|
|
|
|
|
|
|
break 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The providers have been kind enough to give us a preview
|
|
|
|
if ($preview) {
|
|
|
|
$this->resizeAndStore($fileId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stores the max preview in the cache
|
|
|
|
*
|
|
|
|
* @param string $previewPath path to the preview
|
|
|
|
*/
|
|
|
|
private function storeMaxPreview($previewPath) {
|
|
|
|
$maxPreview = false;
|
|
|
|
$preview = $this->preview;
|
|
|
|
|
|
|
|
$allThumbnails = $this->userView->getDirectoryContent($previewPath);
|
|
|
|
// This is so that the cache doesn't need emptying when upgrading
|
|
|
|
// Can be replaced by an upgrade script...
|
|
|
|
foreach ($allThumbnails as $thumbnail) {
|
|
|
|
$name = rtrim($thumbnail['name'], '.png');
|
|
|
|
if (strpos($name, 'max')) {
|
|
|
|
$maxPreview = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// We haven't found the max preview, so we create it
|
|
|
|
if (!$maxPreview) {
|
|
|
|
// Most providers don't resize their thumbnails yet
|
|
|
|
$this->resizeAndCrop(true);
|
|
|
|
|
|
|
|
$maxX = $preview->width();
|
|
|
|
$maxY = $preview->height();
|
|
|
|
$previewPath = $previewPath . strval($maxX) . '-' . strval($maxY);
|
|
|
|
$previewPath .= '-max.png';
|
|
|
|
$this->userView->file_put_contents($previewPath, $preview->data());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-26 14:41:03 +04:00
|
|
|
/**
|
|
|
|
* @param array $args
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public static function post_write($args) {
|
2014-04-04 17:02:08 +04:00
|
|
|
self::post_delete($args, 'files/');
|
2013-05-29 14:01:43 +04:00
|
|
|
}
|
2013-11-28 21:52:58 +04:00
|
|
|
|
2014-08-26 14:41:03 +04:00
|
|
|
/**
|
|
|
|
* @param array $args
|
|
|
|
*/
|
2014-03-11 17:21:27 +04:00
|
|
|
public static function prepare_delete_files($args) {
|
|
|
|
self::prepare_delete($args, 'files/');
|
|
|
|
}
|
|
|
|
|
2014-08-26 14:41:03 +04:00
|
|
|
/**
|
|
|
|
* @param array $args
|
|
|
|
* @param string $prefix
|
|
|
|
*/
|
2014-03-11 17:21:27 +04:00
|
|
|
public static function prepare_delete($args, $prefix='') {
|
2013-05-29 14:01:43 +04:00
|
|
|
$path = $args['path'];
|
2014-02-27 16:15:18 +04:00
|
|
|
if (substr($path, 0, 1) === '/') {
|
2013-05-29 14:01:43 +04:00
|
|
|
$path = substr($path, 1);
|
|
|
|
}
|
2014-03-11 17:21:27 +04:00
|
|
|
|
|
|
|
$view = new \OC\Files\View('/' . \OC_User::getUser() . '/' . $prefix);
|
|
|
|
|
2014-08-26 14:41:03 +04:00
|
|
|
$absPath = Files\Filesystem::normalizePath($view->getAbsolutePath($path));
|
|
|
|
self::addPathToDeleteFileMapper($absPath, $view->getFileInfo($path));
|
|
|
|
if ($view->is_dir($path)) {
|
|
|
|
$children = self::getAllChildren($view, $path);
|
|
|
|
self::$deleteChildrenMapper[$absPath] = $children;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $absolutePath
|
|
|
|
* @param \OCP\Files\FileInfo $info
|
|
|
|
*/
|
|
|
|
private static function addPathToDeleteFileMapper($absolutePath, $info) {
|
|
|
|
self::$deleteFileMapper[$absolutePath] = $info;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param \OC\Files\View $view
|
|
|
|
* @param string $path
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
private static function getAllChildren($view, $path) {
|
|
|
|
$children = $view->getDirectoryContent($path);
|
|
|
|
$childrensFiles = array();
|
|
|
|
|
|
|
|
$fakeRootLength = strlen($view->getRoot());
|
|
|
|
|
|
|
|
for ($i = 0; $i < count($children); $i++) {
|
|
|
|
$child = $children[$i];
|
|
|
|
|
|
|
|
$childsPath = substr($child->getPath(), $fakeRootLength);
|
|
|
|
|
|
|
|
if ($view->is_dir($childsPath)) {
|
|
|
|
$children = array_merge(
|
|
|
|
$children,
|
|
|
|
$view->getDirectoryContent($childsPath)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$childrensFiles[] = $child;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $childrensFiles;
|
2014-03-11 17:21:27 +04:00
|
|
|
}
|
|
|
|
|
2014-08-26 14:41:03 +04:00
|
|
|
/**
|
|
|
|
* @param array $args
|
|
|
|
*/
|
2014-03-11 17:21:27 +04:00
|
|
|
public static function post_delete_files($args) {
|
|
|
|
self::post_delete($args, 'files/');
|
|
|
|
}
|
|
|
|
|
2014-08-26 14:41:03 +04:00
|
|
|
/**
|
|
|
|
* @param array $args
|
|
|
|
* @param string $prefix
|
|
|
|
*/
|
2014-03-11 17:21:27 +04:00
|
|
|
public static function post_delete($args, $prefix='') {
|
|
|
|
$path = Files\Filesystem::normalizePath($args['path']);
|
|
|
|
|
|
|
|
$preview = new Preview(\OC_User::getUser(), $prefix, $path);
|
2013-05-29 14:01:43 +04:00
|
|
|
$preview->deleteAllPreviews();
|
|
|
|
}
|
2013-07-29 17:47:17 +04:00
|
|
|
|
2013-09-05 01:45:11 +04:00
|
|
|
}
|