2012-11-13 18:11:02 +04:00
|
|
|
<?php
|
|
|
|
/**
|
2013-04-25 13:18:45 +04:00
|
|
|
* Copyright (c) 2013 Frank Karlitschek frank@owncloud.org
|
|
|
|
* Copyright (c) 2013 Georg Ehrke georg@ownCloud.com
|
2012-11-13 18:11:02 +04:00
|
|
|
* This file is licensed under the Affero General Public License version 3 or
|
|
|
|
* later.
|
|
|
|
* See the COPYING-README file.
|
2013-05-10 01:59:16 +04:00
|
|
|
*
|
2013-04-25 13:18:45 +04:00
|
|
|
* Thumbnails:
|
|
|
|
* structure of filename:
|
|
|
|
* /data/user/thumbnails/pathhash/x-y.png
|
|
|
|
*
|
|
|
|
*/
|
2013-05-29 14:33:24 +04:00
|
|
|
namespace OC;
|
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
require_once('preview/images.php');
|
|
|
|
require_once('preview/movies.php');
|
|
|
|
require_once('preview/mp3.php');
|
|
|
|
require_once('preview/pdf.php');
|
2013-05-21 14:23:31 +04:00
|
|
|
require_once('preview/svg.php');
|
2013-05-28 18:04:39 +04:00
|
|
|
require_once('preview/txt.php');
|
2013-05-10 01:59:16 +04:00
|
|
|
require_once('preview/unknown.php');
|
2013-06-05 12:55:57 +04:00
|
|
|
require_once('preview/office.php');
|
2012-11-13 18:11:02 +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
|
|
|
|
private $max_scale_factor;
|
|
|
|
private $max_x;
|
|
|
|
private $max_y;
|
2012-11-13 18:11:02 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
//fileview object
|
2013-05-10 01:59:16 +04:00
|
|
|
private $fileview = null;
|
|
|
|
private $userview = null;
|
|
|
|
|
|
|
|
//vars
|
|
|
|
private $file;
|
|
|
|
private $maxX;
|
|
|
|
private $maxY;
|
|
|
|
private $scalingup;
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-06-13 11:52:39 +04:00
|
|
|
//preview images object
|
2013-05-10 01:59:16 +04:00
|
|
|
private $preview;
|
2012-11-13 18:11:02 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
//preview providers
|
|
|
|
static private $providers = array();
|
|
|
|
static private $registeredProviders = array();
|
2012-11-13 18:11:02 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
/**
|
|
|
|
* @brief check if thumbnail or bigger version of thumbnail of file is cached
|
2013-07-10 19:57:04 +04:00
|
|
|
* @param $user userid - if no user is given, OC_User::getUser will be used
|
2013-05-10 01:59:16 +04:00
|
|
|
* @param $root path of root
|
2013-04-25 13:18:45 +04:00
|
|
|
* @param $file The path to the file where you want a thumbnail from
|
|
|
|
* @param $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image
|
|
|
|
* @param $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image
|
|
|
|
* @return mixed (bool / string)
|
|
|
|
* false if thumbnail does not exist
|
|
|
|
* path to thumbnail if thumbnail exists
|
|
|
|
*/
|
2013-07-10 19:57:04 +04:00
|
|
|
public function __construct($user='', $root='/', $file='', $maxX=1, $maxY=1, $scalingup=true) {
|
2013-05-10 01:59:16 +04:00
|
|
|
//set config
|
2013-05-29 14:33:24 +04:00
|
|
|
$this->max_x = \OC_Config::getValue('preview_max_x', null);
|
|
|
|
$this->max_y = \OC_Config::getValue('preview_max_y', null);
|
|
|
|
$this->max_scale_factor = \OC_Config::getValue('preview_max_scale_factor', 10);
|
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);
|
|
|
|
$this->setScalingUp($scalingup);
|
2013-05-10 01:59:16 +04:00
|
|
|
|
|
|
|
//init fileviews
|
2013-07-10 19:57:04 +04:00
|
|
|
if($user === ''){
|
|
|
|
$user = OC_User::getUser();
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
$this->fileview = new \OC\Files\View('/' . $user . '/' . $root);
|
|
|
|
$this->userview = new \OC\Files\View('/' . $user);
|
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
|
|
|
|
if(empty(self::$providers)) {
|
|
|
|
self::initProviders();
|
|
|
|
}
|
2013-06-13 11:52:39 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
if(empty(self::$providers)) {
|
|
|
|
\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
|
|
|
/**
|
|
|
|
* @brief returns the path of the file you want a thumbnail from
|
|
|
|
* @return string
|
|
|
|
*/
|
2013-05-29 15:03:33 +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
|
|
|
/**
|
|
|
|
* @brief returns the max width of the preview
|
|
|
|
* @return integer
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getMaxX() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return $this->maxX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief returns the max height of the preview
|
|
|
|
* @return integer
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* @brief returns whether or not scalingup is enabled
|
|
|
|
* @return bool
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getScalingup() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return $this->scalingup;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
|
|
|
* @brief returns the name of the thumbnailfolder
|
|
|
|
* @return string
|
|
|
|
*/
|
2013-07-10 19:57:04 +04:00
|
|
|
public function getThumbnailsFolder() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return self::THUMBNAILS_FOLDER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief returns the max scale factor
|
|
|
|
* @return integer
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getMaxScaleFactor() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return $this->max_scale_factor;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief returns the max width set in ownCloud's config
|
|
|
|
* @return integer
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getConfigMaxX() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return $this->max_x;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief returns the max height set in ownCloud's config
|
|
|
|
* @return integer
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getConfigMaxY() {
|
2013-05-10 01:59:16 +04:00
|
|
|
return $this->max_y;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
/**
|
|
|
|
* @brief set the path of the file you want a thumbnail from
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setFile($file) {
|
|
|
|
$this->file = $file;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief set the the max width of the preview
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setMaxX($maxX=1) {
|
|
|
|
if($maxX === 0) {
|
|
|
|
throw new \Exception('Cannot set width of 0!');
|
|
|
|
}
|
|
|
|
$configMaxX = $this->getConfigMaxX();
|
|
|
|
if(!is_null($configMaxX)) {
|
|
|
|
if($maxX > $configMaxX) {
|
|
|
|
\OC_Log::write('core', 'maxX reduced from ' . $maxX . ' to ' . $configMaxX, \OC_Log::DEBUG);
|
|
|
|
$maxX = $configMaxX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->maxX = $maxX;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief set the the max height of the preview
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setMaxY($maxY=1) {
|
|
|
|
if($maxY === 0) {
|
|
|
|
throw new \Exception('Cannot set height of 0!');
|
|
|
|
}
|
|
|
|
$configMaxY = $this->getConfigMaxY();
|
|
|
|
if(!is_null($configMaxY)) {
|
|
|
|
if($maxY > $configMaxY) {
|
|
|
|
\OC_Log::write('core', 'maxX reduced from ' . $maxY . ' to ' . $configMaxY, \OC_Log::DEBUG);
|
|
|
|
$maxY = $configMaxY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->maxY = $maxY;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief set whether or not scalingup is enabled
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setScalingup($scalingup) {
|
|
|
|
if($this->getMaxScaleFactor() === 1) {
|
|
|
|
$scalingup = false;
|
|
|
|
}
|
|
|
|
$this->scalingup = $scalingup;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief check if all parameters are valid
|
|
|
|
* @return integer
|
|
|
|
*/
|
|
|
|
public function isFileValid() {
|
|
|
|
$file = $this->getFile();
|
|
|
|
if($file === '') {
|
|
|
|
\OC_Log::write('core', 'No filename passed', \OC_Log::ERROR);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!$this->fileview->file_exists($file)) {
|
|
|
|
\OC_Log::write('core', 'File:"' . $file . '" not found', \OC_Log::ERROR);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
|
|
|
* @brief deletes previews of a file with specific x and y
|
|
|
|
* @return bool
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function deletePreview() {
|
2013-07-10 19:57:04 +04:00
|
|
|
$file = $this->getFile();
|
|
|
|
|
|
|
|
$fileinfo = $this->fileview->getFileInfo($file);
|
2013-05-10 01:59:16 +04:00
|
|
|
$fileid = $fileinfo['fileid'];
|
2013-05-29 14:01:43 +04:00
|
|
|
|
2013-07-10 20:04:13 +04:00
|
|
|
$previewpath = $this->getThumbnailsFolder() . '/' . $fileid . '/' . $this->getMaxX() . '-' . $this->getMaxY() . '.png';
|
|
|
|
$this->userview->unlink($previewpath);
|
|
|
|
return $this->userview->file_exists($previewpath);
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief deletes all previews of a file
|
|
|
|
* @return bool
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function deleteAllPreviews() {
|
2013-07-10 19:57:04 +04:00
|
|
|
$file = $this->getFile();
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
$fileinfo = $this->fileview->getFileInfo($file);
|
|
|
|
$fileid = $fileinfo['fileid'];
|
|
|
|
|
|
|
|
$previewpath = $this->getThumbnailsFolder() . '/' . $fileid . '/';
|
|
|
|
$this->userview->deleteAll($previewpath);
|
|
|
|
$this->userview->rmdir($previewpath);
|
2013-07-10 20:04:13 +04:00
|
|
|
return $this->userview->is_dir($previewpath);
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief check if thumbnail or bigger version of thumbnail of file is cached
|
|
|
|
* @return mixed (bool / string)
|
|
|
|
* false if thumbnail does not exist
|
|
|
|
* path to thumbnail if thumbnail exists
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
private function isCached() {
|
2013-07-10 19:57:04 +04:00
|
|
|
$file = $this->getFile();
|
|
|
|
$maxX = $this->getMaxX();
|
|
|
|
$maxY = $this->getMaxY();
|
|
|
|
$scalingup = $this->getScalingup();
|
|
|
|
$maxscalefactor = $this->getMaxScaleFactor();
|
2013-05-10 01:59:16 +04:00
|
|
|
|
|
|
|
$fileinfo = $this->fileview->getFileInfo($file);
|
|
|
|
$fileid = $fileinfo['fileid'];
|
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
$previewpath = $this->getThumbnailsFolder() . '/' . $fileid . '/';
|
|
|
|
if(!$this->userview->is_dir($previewpath)) {
|
2013-05-10 01:59:16 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
//does a preview with the wanted height and width already exist?
|
2013-07-10 19:57:04 +04:00
|
|
|
if($this->userview->file_exists($previewpath . $maxX . '-' . $maxY . '.png')) {
|
|
|
|
return $previewpath . $maxX . '-' . $maxY . '.png';
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
$wantedaspectratio = $maxX / $maxY;
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
//array for usable cached thumbnails
|
|
|
|
$possiblethumbnails = array();
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
$allthumbnails = $this->userview->getDirectoryContent($previewpath);
|
2013-05-29 15:03:33 +04:00
|
|
|
foreach($allthumbnails as $thumbnail) {
|
2013-04-25 13:18:45 +04:00
|
|
|
$size = explode('-', $thumbnail['name']);
|
|
|
|
$x = $size[0];
|
|
|
|
$y = $size[1];
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
$aspectratio = $x / $y;
|
2013-05-29 15:03:33 +04:00
|
|
|
if($aspectratio != $wantedaspectratio) {
|
2013-04-25 13:18:45 +04:00
|
|
|
continue;
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if($x < $maxX || $y < $maxY) {
|
|
|
|
if($scalingup) {
|
2013-04-25 13:18:45 +04:00
|
|
|
$scalefactor = $maxX / $x;
|
2013-07-10 19:57:04 +04:00
|
|
|
if($scalefactor > $maxscalefactor) {
|
2013-04-25 13:18:45 +04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$possiblethumbnails[$x] = $thumbnail['path'];
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if(count($possiblethumbnails) === 0) {
|
2013-04-25 13:18:45 +04:00
|
|
|
return false;
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if(count($possiblethumbnails) === 1) {
|
2013-04-25 13:18:45 +04:00
|
|
|
return current($possiblethumbnails);
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
ksort($possiblethumbnails);
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if(key(reset($possiblethumbnails)) > $maxX) {
|
2013-04-25 13:18:45 +04:00
|
|
|
return current(reset($possiblethumbnails));
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if(key(end($possiblethumbnails)) < $maxX) {
|
2013-04-25 13:18:45 +04:00
|
|
|
return current(end($possiblethumbnails));
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
foreach($possiblethumbnails as $width => $path) {
|
|
|
|
if($width < $maxX) {
|
2013-04-25 13:18:45 +04:00
|
|
|
continue;
|
|
|
|
}else{
|
|
|
|
return $path;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-11-13 19:14:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
/**
|
2013-05-10 01:59:16 +04:00
|
|
|
* @brief return a preview of a file
|
2013-04-25 13:18:45 +04:00
|
|
|
* @return image
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function getPreview() {
|
2013-07-10 19:57:04 +04:00
|
|
|
if(!is_null($this->preview) && $this->preview->valid()){
|
|
|
|
return $this->preview;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->preview = null;
|
|
|
|
$file = $this->getFile();
|
|
|
|
$maxX = $this->getMaxX();
|
|
|
|
$maxY = $this->getMaxY();
|
|
|
|
$scalingup = $this->getScalingup();
|
2013-04-25 13:18:45 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
$fileinfo = $this->fileview->getFileInfo($file);
|
|
|
|
$fileid = $fileinfo['fileid'];
|
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
$cached = $this->isCached();
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if($cached) {
|
2013-05-28 18:04:39 +04:00
|
|
|
$image = new \OC_Image($this->userview->file_get_contents($cached, 'r'));
|
2013-07-10 19:57:04 +04:00
|
|
|
$this->preview = $image->valid() ? $image : null;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
if(is_null($this->preview)) {
|
|
|
|
$mimetype = $this->fileview->getMimeType($file);
|
2013-06-26 12:57:37 +04:00
|
|
|
$preview = null;
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
foreach(self::$providers as $supportedmimetype => $provider) {
|
|
|
|
if(!preg_match($supportedmimetype, $mimetype)) {
|
2013-05-10 01:59:16 +04:00
|
|
|
continue;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
$preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingup, $this->fileview);
|
2013-05-28 18:04:39 +04:00
|
|
|
|
2013-07-10 15:38:42 +04:00
|
|
|
if(!($preview instanceof \OC_Image)) {
|
2013-05-10 01:59:16 +04:00
|
|
|
continue;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
$this->preview = $preview;
|
|
|
|
$this->resizeAndCrop();
|
|
|
|
|
|
|
|
$previewpath = $this->getThumbnailsFolder() . '/' . $fileid . '/';
|
|
|
|
$cachepath = $previewpath . $maxX . '-' . $maxY . '.png';
|
|
|
|
|
|
|
|
if($this->userview->is_dir($this->getThumbnailsFolder() . '/') === false) {
|
|
|
|
$this->userview->mkdir($this->getThumbnailsFolder() . '/');
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
if($this->userview->is_dir($previewpath) === false) {
|
|
|
|
$this->userview->mkdir($previewpath);
|
2013-05-28 18:04:39 +04:00
|
|
|
}
|
2013-07-10 15:38:42 +04:00
|
|
|
|
2013-05-28 18:04:39 +04:00
|
|
|
$this->userview->file_put_contents($cachepath, $preview->data());
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
break;
|
|
|
|
}
|
2013-07-10 19:57:04 +04:00
|
|
|
}
|
2013-06-26 12:57:37 +04:00
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
if(is_null($this->preview)) {
|
|
|
|
$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
|
|
|
|
|
|
|
/**
|
2013-07-10 19:57:04 +04:00
|
|
|
* @brief show preview
|
2013-05-10 01:59:16 +04:00
|
|
|
* @return void
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public function showPreview() {
|
2013-07-10 19:57:04 +04:00
|
|
|
\OCP\Response::enableCaching(3600 * 24); // 24 hours
|
|
|
|
if(is_null($this->preview)) {
|
|
|
|
$this->getPreview();
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2013-07-10 19:57:04 +04:00
|
|
|
$this->preview->show();
|
2013-07-10 20:01:04 +04:00
|
|
|
return;
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
2013-07-11 12:10:07 +04:00
|
|
|
/**
|
|
|
|
* @brief show preview
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function show() {
|
|
|
|
return $this->showPreview();
|
|
|
|
}
|
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
|
|
|
* @brief resize, crop and fix orientation
|
2012-11-13 18:11:02 +04:00
|
|
|
* @return image
|
|
|
|
*/
|
2013-07-10 19:57:04 +04:00
|
|
|
private function resizeAndCrop() {
|
2013-05-10 01:59:16 +04:00
|
|
|
$image = $this->preview;
|
2013-07-10 19:57:04 +04:00
|
|
|
$x = $this->getMaxX();
|
|
|
|
$y = $this->getMaxY();
|
|
|
|
$scalingup = $this->getScalingup();
|
|
|
|
$maxscalefactor = $this->getMaxScaleFactor();
|
2013-05-10 01:59:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if(!($image instanceof \OC_Image)) {
|
2013-07-10 19:57:04 +04:00
|
|
|
\OC_Log::write('core', '$this->preview is not an instance of OC_Image', \OC_Log::DEBUG);
|
2013-05-10 01:59:16 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
$image->fixOrientation();
|
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
$realx = (int) $image->width();
|
|
|
|
$realy = (int) $image->height();
|
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if($x === $realx && $y === $realy) {
|
2013-07-10 19:57:04 +04:00
|
|
|
$this->preview = $image;
|
|
|
|
return true;
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
$factorX = $x / $realx;
|
|
|
|
$factorY = $y / $realy;
|
2013-07-10 19:57:04 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if($factorX >= $factorY) {
|
2013-05-10 01:59:16 +04:00
|
|
|
$factor = $factorX;
|
|
|
|
}else{
|
|
|
|
$factor = $factorY;
|
|
|
|
}
|
2013-07-10 19:57:04 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
if($scalingup === false) {
|
2013-07-10 19:57:04 +04:00
|
|
|
if($factor > 1) {
|
|
|
|
$factor = 1;
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2013-07-10 19:57:04 +04:00
|
|
|
|
|
|
|
if(!is_null($maxscalefactor)) {
|
|
|
|
if($factor > $maxscalefactor) {
|
|
|
|
\OC_Log::write('core', 'scalefactor reduced from ' . $factor . ' to ' . $maxscalefactor, \OC_Log::DEBUG);
|
|
|
|
$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
|
|
|
|
2013-07-10 19:57:04 +04:00
|
|
|
$newXsize = (int) ($realx * $factor);
|
|
|
|
$newYsize = (int) ($realy * $factor);
|
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
$image->preciseResize($newXsize, $newYsize);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-07-10 20:01:04 +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
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if($newXsize >= $x && $newYsize >= $y) {
|
2013-05-10 01:59:16 +04:00
|
|
|
$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);
|
|
|
|
|
|
|
|
$this->preview = $image;
|
|
|
|
return;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if($newXsize < $x || $newYsize < $y) {
|
|
|
|
if($newXsize > $x) {
|
2013-05-10 01:59:16 +04:00
|
|
|
$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
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
if($newYsize > $y) {
|
2013-05-10 01:59:16 +04:00
|
|
|
$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
|
|
|
|
2013-05-10 01:59:16 +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
|
2013-05-17 13:28:49 +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
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
$mergeX = floor(abs($x - $newXsize) * 0.5);
|
|
|
|
$mergeY = floor(abs($y - $newYsize) * 0.5);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-17 13:28:49 +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
|
|
|
|
2013-05-17 13:28:49 +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;
|
|
|
|
return;
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
|
|
|
}
|
2012-11-13 18:11:02 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
/**
|
|
|
|
* @brief register a new preview provider to be used
|
2013-05-29 14:33:24 +04:00
|
|
|
* @param string $provider class name of a Preview_Provider
|
2013-04-25 13:18:45 +04:00
|
|
|
* @return void
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
public static function registerProvider($class, $options=array()) {
|
2013-04-25 13:18:45 +04:00
|
|
|
self::$registeredProviders[]=array('class'=>$class, 'options'=>$options);
|
|
|
|
}
|
2013-01-14 18:51:47 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
/**
|
|
|
|
* @brief create instances of all the registered preview providers
|
|
|
|
* @return void
|
|
|
|
*/
|
2013-05-29 15:03:33 +04:00
|
|
|
private static function initProviders() {
|
2013-04-25 13:18:45 +04:00
|
|
|
if(count(self::$providers)>0) {
|
|
|
|
return;
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
foreach(self::$registeredProviders as $provider) {
|
|
|
|
$class=$provider['class'];
|
|
|
|
$options=$provider['options'];
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
$object = new $class($options);
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
self::$providers[$object->getMimeType()] = $object;
|
2012-11-13 18:11:02 +04:00
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
$keys = array_map('strlen', array_keys(self::$providers));
|
|
|
|
array_multisort($keys, SORT_DESC, self::$providers);
|
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-04-25 13:18:45 +04:00
|
|
|
/**
|
2013-05-10 01:59:16 +04:00
|
|
|
* @brief method that handles preview requests from users that are logged in
|
2013-04-25 13:18:45 +04:00
|
|
|
* @return void
|
|
|
|
*/
|
2013-07-11 12:10:07 +04:00
|
|
|
public static function previewRouter() {
|
2013-05-29 14:33:24 +04:00
|
|
|
\OC_Util::checkLoggedIn();
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-07-11 12:10:07 +04:00
|
|
|
$file = array_key_exists('file', $_GET) ? (string) urldecode($_GET['file']) : '';
|
|
|
|
$maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : '44';
|
|
|
|
$maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : '44';
|
|
|
|
$scalingup = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true;
|
|
|
|
|
|
|
|
if($file === '') {
|
|
|
|
\OC_Response::setStatus(400); //400 Bad Request
|
|
|
|
\OC_Log::write('core-preview', 'No file parameter was passed', \OC_Log::DEBUG);
|
|
|
|
self::showErrorPreview();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($maxX === 0 || $maxY === 0) {
|
|
|
|
\OC_Response::setStatus(400); //400 Bad Request
|
|
|
|
\OC_Log::write('core-preview', 'x and/or y set to 0', \OC_Log::DEBUG);
|
|
|
|
self::showErrorPreview();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
try{
|
|
|
|
$preview = new Preview(\OC_User::getUser(), 'files');
|
|
|
|
$preview->setFile($file);
|
|
|
|
$preview->setMaxX($maxX);
|
|
|
|
$preview->setMaxY($maxY);
|
|
|
|
$preview->setScalingUp($scalingup);
|
|
|
|
|
|
|
|
$preview->show();
|
|
|
|
}catch(\Exception $e) {
|
|
|
|
\OC_Response::setStatus(500);
|
|
|
|
\OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR);
|
|
|
|
self::showErrorPreview();
|
2013-04-25 14:51:44 +04:00
|
|
|
exit;
|
|
|
|
}
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-05-10 01:59:16 +04:00
|
|
|
/**
|
|
|
|
* @brief method that handles preview requests from users that are not logged in / view shared folders that are public
|
|
|
|
* @return void
|
|
|
|
*/
|
2013-07-11 12:10:07 +04:00
|
|
|
public static function publicPreviewRouter() {
|
|
|
|
if(!\OC_App::isEnabled('files_sharing')){
|
|
|
|
exit;
|
|
|
|
}
|
2013-05-22 17:12:25 +04:00
|
|
|
|
2013-07-11 12:10:07 +04:00
|
|
|
$file = array_key_exists('file', $_GET) ? (string) urldecode($_GET['file']) : '';
|
|
|
|
$maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : '44';
|
|
|
|
$maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : '44';
|
|
|
|
$scalingup = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true;
|
|
|
|
$token = array_key_exists('t', $_GET) ? (string) $_GET['t'] : '';
|
|
|
|
|
|
|
|
if($token === ''){
|
|
|
|
\OC_Response::setStatus(400); //400 Bad Request
|
|
|
|
\OC_Log::write('core-preview', 'No token parameter was passed', \OC_Log::DEBUG);
|
|
|
|
self::showErrorPreview();
|
|
|
|
exit;
|
2013-05-10 01:59:16 +04:00
|
|
|
}
|
2013-05-17 21:08:16 +04:00
|
|
|
|
2013-07-11 12:10:07 +04:00
|
|
|
$linkedItem = \OCP\Share::getShareByToken($token);
|
|
|
|
if($linkedItem === false || ($linkedItem['item_type'] !== 'file' && $linkedItem['item_type'] !== 'folder')) {
|
|
|
|
\OC_Response::setStatus(404);
|
|
|
|
\OC_Log::write('core-preview', 'Passed token parameter is not valid', \OC_Log::DEBUG);
|
|
|
|
self::showErrorPreview();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!isset($linkedItem['uid_owner']) || !isset($linkedItem['file_source'])) {
|
|
|
|
\OC_Response::setStatus(500);
|
|
|
|
\OC_Log::write('core-preview', 'Passed token seems to be valid, but it does not contain all necessary information . ("' . $token . '")');
|
|
|
|
self::showErrorPreview();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
$userid = $linkedItem['uid_owner'];
|
|
|
|
\OC_Util::setupFS($userid);
|
|
|
|
|
|
|
|
$pathid = $linkedItem['file_source'];
|
|
|
|
$path = \OC\Files\Filesystem::getPath($pathid);
|
|
|
|
$pathinfo = \OC\Files\Filesystem::getFileInfo($path);
|
|
|
|
$sharedfile = null;
|
|
|
|
|
|
|
|
if($linkedItem['item_type'] === 'folder') {
|
2013-07-11 13:43:53 +04:00
|
|
|
$isvalid = \OC\Files\Filesystem::isValidPath($file);
|
2013-07-11 12:10:07 +04:00
|
|
|
if(!$isvalid) {
|
|
|
|
\OC_Response::setStatus(400); //400 Bad Request
|
|
|
|
\OC_Log::write('core-preview', 'Passed filename is not valid, might be malicious (file:"' . $file . '";ip:"' . $_SERVER['REMOTE_ADDR'] . '")', \OC_Log::WARN);
|
|
|
|
self::showErrorPreview();
|
2013-05-28 18:04:39 +04:00
|
|
|
exit;
|
|
|
|
}
|
2013-07-11 12:10:07 +04:00
|
|
|
$sharedfile = \OC\Files\Filesystem::normalizePath($file);
|
|
|
|
}
|
|
|
|
|
|
|
|
if($linkedItem['item_type'] === 'file') {
|
|
|
|
$parent = $pathinfo['parent'];
|
|
|
|
$path = \OC\Files\Filesystem::getPath($parent);
|
|
|
|
$sharedfile = $pathinfo['name'];
|
|
|
|
}
|
|
|
|
|
|
|
|
$path = \OC\Files\Filesystem::normalizePath($path, false);
|
|
|
|
if(substr($path, 0, 1) == '/') {
|
|
|
|
$path = substr($path, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if($maxX === 0 || $maxY === 0) {
|
|
|
|
\OC_Response::setStatus(400); //400 Bad Request
|
|
|
|
\OC_Log::write('core-preview', 'x and/or y set to 0', \OC_Log::DEBUG);
|
|
|
|
self::showErrorPreview();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
$root = 'files/' . $path;
|
|
|
|
|
|
|
|
try{
|
|
|
|
$preview = new Preview($userid, $path);
|
|
|
|
$preview->setFile($file);
|
|
|
|
$preview->setMaxX($maxX);
|
|
|
|
$preview->setMaxY($maxY);
|
|
|
|
$preview->setScalingUp($scalingup);
|
|
|
|
|
|
|
|
$preview->show();
|
|
|
|
}catch(\Exception $e) {
|
|
|
|
\OC_Response::setStatus(500);
|
|
|
|
\OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR);
|
|
|
|
self::showErrorPreview();
|
2013-05-10 01:59:16 +04:00
|
|
|
exit;
|
2013-04-25 14:51:44 +04:00
|
|
|
}
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|
2013-05-29 14:01:43 +04:00
|
|
|
|
2013-07-08 12:53:53 +04:00
|
|
|
public static function trashbinPreviewRouter() {
|
2013-07-11 12:10:07 +04:00
|
|
|
\OC_Util::checkLoggedIn();
|
|
|
|
|
2013-07-08 12:53:53 +04:00
|
|
|
if(!\OC_App::isEnabled('files_trashbin')){
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2013-07-11 12:10:07 +04:00
|
|
|
$file = array_key_exists('file', $_GET) ? (string) urldecode($_GET['file']) : '';
|
|
|
|
$maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : '44';
|
|
|
|
$maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : '44';
|
|
|
|
$scalingup = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true;
|
|
|
|
|
|
|
|
if($file === '') {
|
|
|
|
\OC_Response::setStatus(400); //400 Bad Request
|
|
|
|
\OC_Log::write('core-preview', 'No file parameter was passed', \OC_Log::DEBUG);
|
|
|
|
self::showErrorPreview();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($maxX === 0 || $maxY === 0) {
|
|
|
|
\OC_Response::setStatus(400); //400 Bad Request
|
|
|
|
\OC_Log::write('core-preview', 'x and/or y set to 0', \OC_Log::DEBUG);
|
|
|
|
self::showErrorPreview();
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
try{
|
|
|
|
$preview = new Preview(\OC_User::getUser(), 'files_trashbin/files');
|
|
|
|
$preview->setFile($file);
|
|
|
|
$preview->setMaxX($maxX);
|
|
|
|
$preview->setMaxY($maxY);
|
|
|
|
$preview->setScalingUp($scalingup);
|
|
|
|
|
|
|
|
$preview->showPreview();
|
|
|
|
}catch(\Exception $e) {
|
|
|
|
\OC_Response::setStatus(500);
|
|
|
|
\OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR);
|
|
|
|
self::showErrorPreview();
|
2013-07-08 12:53:53 +04:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
public static function post_write($args) {
|
2013-05-29 14:01:43 +04:00
|
|
|
self::post_delete($args);
|
|
|
|
}
|
|
|
|
|
2013-05-29 15:03:33 +04:00
|
|
|
public static function post_delete($args) {
|
2013-05-29 14:01:43 +04:00
|
|
|
$path = $args['path'];
|
2013-05-29 15:03:33 +04:00
|
|
|
if(substr($path, 0, 1) == '/') {
|
2013-05-29 14:01:43 +04:00
|
|
|
$path = substr($path, 1);
|
|
|
|
}
|
2013-05-29 14:33:24 +04:00
|
|
|
$preview = new Preview(\OC_User::getUser(), 'files/', $path, 0, 0, false, true);
|
2013-05-29 14:01:43 +04:00
|
|
|
$preview->deleteAllPreviews();
|
|
|
|
}
|
2013-07-11 12:10:07 +04:00
|
|
|
|
|
|
|
private static function showErrorPreview() {
|
|
|
|
$path = \OC::$SERVERROOT . '/core/img/actions/delete.png';
|
|
|
|
$preview = new \OC_Image($path);
|
|
|
|
$preview->preciseResize(44, 44);
|
|
|
|
$preview->show();
|
|
|
|
}
|
2013-04-25 13:18:45 +04:00
|
|
|
}
|