Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
die_coolen_jungs
our_own_cloud_project
Commits
b3afc98f
Commit
b3afc98f
authored
Nov 28, 2014
by
Lukas Reschke
Browse files
Merge pull request #12483 from owncloud/issue/6101-preview-providers
Issue/6101 Autoload preview providers
parents
7c96cedd
ec7b55f5
Changes
21
Hide whitespace changes
Inline
Side-by-side
lib/private/preview.php
View file @
b3afc98f
...
...
@@ -16,14 +16,6 @@ namespace OC;
use
OC\Preview\Provider
;
use
OCP\Files\NotFoundException
;
require_once
'preview/image.php'
;
require_once
'preview/movie.php'
;
require_once
'preview/mp3.php'
;
require_once
'preview/svg.php'
;
require_once
'preview/txt.php'
;
require_once
'preview/office.php'
;
require_once
'preview/bitmap.php'
;
class
Preview
{
//the thumbnail folder
const
THUMBNAILS_FOLDER
=
'thumbnails'
;
...
...
@@ -744,10 +736,11 @@ class Preview {
return
;
}
if
(
count
(
self
::
$providers
)
>
0
)
{
if
(
!
empty
(
self
::
$providers
))
{
return
;
}
self
::
registerCoreProviders
();
foreach
(
self
::
$registeredProviders
as
$provider
)
{
$class
=
$provider
[
'class'
];
$options
=
$provider
[
'options'
];
...
...
@@ -759,7 +752,74 @@ class Preview {
$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'
,
// Requires adding 'eps' => array('application/postscript', null), to lib/private/mimetypes.list.php
'EPS'
=>
'OC\Preview\Postscript'
,
);
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'
);
}
}
}
/**
...
...
lib/private/preview/bitmap.php
View file @
b3afc98f
...
...
@@ -5,113 +5,33 @@
* later.
* See the COPYING-README file.
*/
namespace
OC\Preview
;
use
Imagick
;
if
(
extension_loaded
(
'imagick'
))
{
$checkImagick
=
new
Imagick
();
class
Bitmap
extends
Provider
{
public
function
getMimeType
()
{
return
null
;
}
public
function
getThumbnail
(
$path
,
$maxX
,
$maxY
,
$scalingup
,
$fileview
)
{
$tmpPath
=
$fileview
->
toTmpFile
(
$path
);
//create imagick object from bitmap or vector file
try
{
// Layer 0 contains either the bitmap or
// a flat representation of all vector layers
$bp
=
new
Imagick
(
$tmpPath
.
'[0]'
);
$bp
->
setImageFormat
(
'png'
);
}
catch
(
\
Exception
$e
)
{
\
OC_Log
::
write
(
'core'
,
$e
->
getmessage
(),
\
OC_Log
::
ERROR
);
return
false
;
}
unlink
(
$tmpPath
);
//new bitmap image object
$image
=
new
\
OC_Image
(
$bp
);
//check if image object is valid
return
$image
->
valid
()
?
$image
:
false
;
}
}
if
(
count
(
$checkImagick
->
queryFormats
(
'PDF'
))
===
1
)
{
//.pdf
class
PDF
extends
Bitmap
{
public
function
getMimeType
()
{
return
'/application\/pdf/'
;
}
}
\
OC\Preview
::
registerProvider
(
'OC\Preview\PDF'
);
}
if
(
count
(
$checkImagick
->
queryFormats
(
'TIFF'
))
===
1
)
{
//.tiff
class
TIFF
extends
Bitmap
{
public
function
getMimeType
()
{
return
'/image\/tiff/'
;
}
}
\
OC\Preview
::
registerProvider
(
'OC\Preview\TIFF'
);
}
if
(
count
(
$checkImagick
->
queryFormats
(
'AI'
))
===
1
)
{
//.ai
class
Illustrator
extends
Bitmap
{
public
function
getMimeType
()
{
return
'/application\/illustrator/'
;
}
}
\
OC\Preview
::
registerProvider
(
'OC\Preview\Illustrator'
);
}
// Requires adding 'eps' => array('application/postscript', null), to lib/private/mimetypes.list.php
if
(
count
(
$checkImagick
->
queryFormats
(
'EPS'
))
===
1
)
{
//.eps
class
Postscript
extends
Bitmap
{
public
function
getMimeType
()
{
return
'/application\/postscript/'
;
}
namespace
OC\Preview
;
abstract
class
Bitmap
extends
Provider
{
/**
* {@inheritDoc}
*/
public
function
getThumbnail
(
$path
,
$maxX
,
$maxY
,
$scalingup
,
$fileview
)
{
$tmpPath
=
$fileview
->
toTmpFile
(
$path
);
//create imagick object from bitmap or vector file
try
{
// Layer 0 contains either the bitmap or
// a flat representation of all vector layers
$bp
=
new
\
Imagick
(
$tmpPath
.
'[0]'
);
$bp
->
setImageFormat
(
'png'
);
}
catch
(
\
Exception
$e
)
{
\
OC_Log
::
write
(
'core'
,
$e
->
getmessage
(),
\
OC_Log
::
ERROR
);
return
false
;
}
\
OC\Preview
::
registerProvider
(
'OC\Preview\Postscript'
);
}
if
(
count
(
$checkImagick
->
queryFormats
(
'PSD'
))
===
1
)
{
//.psd
class
Photoshop
extends
Bitmap
{
public
function
getMimeType
()
{
return
'/application\/x-photoshop/'
;
}
unlink
(
$tmpPath
);
}
\
OC\Preview
::
registerProvider
(
'OC\Preview\Photoshop'
);
//new bitmap image object
$image
=
new
\
OC_Image
(
$bp
);
//check if image object is valid
return
$image
->
valid
()
?
$image
:
false
;
}
}
lib/private/preview/illustrator.php
0 → 100644
View file @
b3afc98f
<?php
/**
* Copyright (c) 2013-2014 Georg Ehrke georg@ownCloud.com
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace
OC\Preview
;
//.ai
class
Illustrator
extends
Bitmap
{
/**
* {@inheritDoc}
*/
public
function
getMimeType
()
{
return
'/application\/illustrator/'
;
}
}
lib/private/preview/image.php
View file @
b3afc98f
...
...
@@ -9,11 +9,16 @@
namespace
OC\Preview
;
class
Image
extends
Provider
{
/**
* {@inheritDoc}
*/
public
function
getMimeType
()
{
return
'/image\/(?!tiff$)(?!svg.*).*/'
;
}
/**
* {@inheritDoc}
*/
public
function
getThumbnail
(
$path
,
$maxX
,
$maxY
,
$scalingup
,
$fileview
)
{
//get fileinfo
$fileInfo
=
$fileview
->
getFileInfo
(
$path
);
...
...
@@ -35,5 +40,3 @@ class Image extends Provider {
}
}
\
OC\Preview
::
registerProvider
(
'OC\Preview\Image'
);
lib/private/preview/markdown.php
0 → 100644
View file @
b3afc98f
<?php
/**
* Copyright (c) 2013 Georg Ehrke georg@ownCloud.com
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace
OC\Preview
;
class
MarkDown
extends
TXT
{
/**
* {@inheritDoc}
*/
public
function
getMimeType
()
{
return
'/text\/(x-)?markdown/'
;
}
}
lib/private/preview/movie.php
View file @
b3afc98f
...
...
@@ -8,99 +8,87 @@
*/
namespace
OC\Preview
;
// movie preview is currently not supported on Windows
if
(
!
\
OC_Util
::
runningOnWindows
())
{
$avconvBinary
=
\
OC_Helper
::
findBinaryPath
(
'avconv'
);
$ffmpegBinary
=
(
$avconvBinary
)
?
null
:
\
OC_Helper
::
findBinaryPath
(
'ffmpeg'
);
if
(
$avconvBinary
||
$ffmpegBinary
)
{
class
Movie
extends
Provider
{
public
static
$avconvBinary
;
public
static
$ffmpegBinary
;
public
function
getMimeType
()
{
return
'/video\/.*/'
;
}
public
function
getThumbnail
(
$path
,
$maxX
,
$maxY
,
$scalingup
,
$fileview
)
{
// TODO: use proc_open() and stream the source file ?
$fileInfo
=
$fileview
->
getFileInfo
(
$path
);
$useFileDirectly
=
(
!
$fileInfo
->
isEncrypted
()
&&
!
$fileInfo
->
isMounted
());
class
Movie
extends
Provider
{
public
static
$avconvBinary
;
public
static
$ffmpegBinary
;
/**
* {@inheritDoc}
*/
public
function
getMimeType
()
{
return
'/video\/.*/'
;
}
if
(
$useFileDirectly
)
{
$absPath
=
$fileview
->
getLocalFile
(
$path
);
}
else
{
$absPath
=
\
OC_Helper
::
tmpFile
();
/**
* {@inheritDoc}
*/
public
function
getThumbnail
(
$path
,
$maxX
,
$maxY
,
$scalingup
,
$fileview
)
{
// TODO: use proc_open() and stream the source file ?
$handle
=
$fileview
->
fopen
(
$path
,
'rb'
);
$fileInfo
=
$fileview
->
getFileInfo
(
$path
);
$useFileDirectly
=
(
!
$fileInfo
->
isEncrypted
()
&&
!
$fileInfo
->
isMounted
());
// we better use 5MB (1024 * 1024 * 5 = 5242880) instead of 1MB.
// in some cases 1MB was no enough to generate thumbnail
$firstmb
=
stream_get_contents
(
$handle
,
5242880
);
file_put_contents
(
$absPath
,
$firstmb
);
}
if
(
$useFileDirectly
)
{
$absPath
=
$fileview
->
getLocalFile
(
$path
);
}
else
{
$absPath
=
\
OC_Helper
::
tmpFile
();
$result
=
$this
->
generateThumbNail
(
$maxX
,
$maxY
,
$absPath
,
5
);
if
(
$result
===
false
)
{
$result
=
$this
->
generateThumbNail
(
$maxX
,
$maxY
,
$absPath
,
1
);
if
(
$result
===
false
)
{
$result
=
$this
->
generateThumbNail
(
$maxX
,
$maxY
,
$absPath
,
0
);
}
}
$handle
=
$fileview
->
fopen
(
$path
,
'rb'
);
if
(
!
$useFileDirectly
)
{
unlink
(
$absPath
);
}
// we better use 5MB (1024 * 1024 * 5 = 5242880) instead of 1MB.
// in some cases 1MB was no enough to generate thumbnail
$firstmb
=
stream_get_contents
(
$handle
,
5242880
);
file_put_contents
(
$absPath
,
$firstmb
);
}
return
$result
;
$result
=
$this
->
generateThumbNail
(
$maxX
,
$maxY
,
$absPath
,
5
);
if
(
$result
===
false
)
{
$result
=
$this
->
generateThumbNail
(
$maxX
,
$maxY
,
$absPath
,
1
);
if
(
$result
===
false
)
{
$result
=
$this
->
generateThumbNail
(
$maxX
,
$maxY
,
$absPath
,
0
);
}
}
/**
* @param int $maxX
* @param int $maxY
* @param string $absPath
* @param string $tmpPath
* @param int $second
* @return bool|\OC_Image
*/
private
function
generateThumbNail
(
$maxX
,
$maxY
,
$absPath
,
$second
)
{
$tmpPath
=
\
OC_Helper
::
tmpFile
();
if
(
self
::
$avconvBinary
)
{
$cmd
=
self
::
$avconvBinary
.
' -an -y -ss '
.
escapeshellarg
(
$second
)
.
' -i '
.
escapeshellarg
(
$absPath
)
.
' -f mjpeg -vframes 1 -vsync 1 '
.
escapeshellarg
(
$tmpPath
)
.
' > /dev/null 2>&1'
;
}
else
{
$cmd
=
self
::
$ffmpegBinary
.
' -y -ss '
.
escapeshellarg
(
$second
)
.
' -i '
.
escapeshellarg
(
$absPath
)
.
' -f mjpeg -vframes 1'
.
' -s '
.
escapeshellarg
(
$maxX
)
.
'x'
.
escapeshellarg
(
$maxY
)
.
' '
.
escapeshellarg
(
$tmpPath
)
.
' > /dev/null 2>&1'
;
}
if
(
!
$useFileDirectly
)
{
unlink
(
$absPath
);
}
exec
(
$cmd
,
$output
,
$returnCode
);
return
$result
;
}
if
(
$returnCode
===
0
)
{
$image
=
new
\
OC_Image
();
$image
->
loadFromFile
(
$tmpPath
);
unlink
(
$tmpPath
);
return
$image
->
valid
()
?
$image
:
false
;
}
unlink
(
$tmpPath
);
return
false
;
}
/**
* @param int $maxX
* @param int $maxY
* @param string $absPath
* @param int $second
* @return bool|\OC_Image
*/
private
function
generateThumbNail
(
$maxX
,
$maxY
,
$absPath
,
$second
)
{
$tmpPath
=
\
OC_Helper
::
tmpFile
();
if
(
self
::
$avconvBinary
)
{
$cmd
=
self
::
$avconvBinary
.
' -an -y -ss '
.
escapeshellarg
(
$second
)
.
' -i '
.
escapeshellarg
(
$absPath
)
.
' -f mjpeg -vframes 1 -vsync 1 '
.
escapeshellarg
(
$tmpPath
)
.
' > /dev/null 2>&1'
;
}
else
{
$cmd
=
self
::
$ffmpegBinary
.
' -y -ss '
.
escapeshellarg
(
$second
)
.
' -i '
.
escapeshellarg
(
$absPath
)
.
' -f mjpeg -vframes 1'
.
' -s '
.
escapeshellarg
(
$maxX
)
.
'x'
.
escapeshellarg
(
$maxY
)
.
' '
.
escapeshellarg
(
$tmpPath
)
.
' > /dev/null 2>&1'
;
}
// a bit hacky but didn't want to use subclasses
Movie
::
$avconvBinary
=
$avconvBinary
;
Movie
::
$ffmpegBinary
=
$ffmpegBinary
;
exec
(
$cmd
,
$output
,
$returnCode
);
\
OC\Preview
::
registerProvider
(
'OC\Preview\Movie'
);
if
(
$returnCode
===
0
)
{
$image
=
new
\
OC_Image
();
$image
->
loadFromFile
(
$tmpPath
);
unlink
(
$tmpPath
);
return
$image
->
valid
()
?
$image
:
false
;
}
unlink
(
$tmpPath
);
return
false
;
}
}
lib/private/preview/mp3.php
View file @
b3afc98f
...
...
@@ -8,11 +8,16 @@
namespace
OC\Preview
;
class
MP3
extends
Provider
{
/**
* {@inheritDoc}
*/
public
function
getMimeType
()
{
return
'/audio\/mpeg/'
;
}
/**
* {@inheritDoc}
*/
public
function
getThumbnail
(
$path
,
$maxX
,
$maxY
,
$scalingup
,
$fileview
)
{
$getID3
=
new
\
getID3
();
...
...
@@ -31,6 +36,12 @@ class MP3 extends Provider {
return
$this
->
getNoCoverThumbnail
();
}
/**
* 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
*/
private
function
getNoCoverThumbnail
()
{
$icon
=
\
OC
::
$SERVERROOT
.
'/core/img/filetypes/audio.png'
;
...
...
@@ -44,5 +55,3 @@ class MP3 extends Provider {
}
}
\
OC\Preview
::
registerProvider
(
'OC\Preview\MP3'
);
lib/private/preview/msoffice2003.php
0 → 100644
View file @
b3afc98f
<?php
/**
* Copyright (c) 2013 Georg Ehrke georg@ownCloud.com
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace
OC\Preview
;
//.docm, .dotm, .xls(m), .xlt(m), .xla(m), .ppt(m), .pot(m), .pps(m), .ppa(m)
class
MSOffice2003
extends
Office
{
/**
* {@inheritDoc}
*/
public
function
getMimeType
()
{
return
'/application\/vnd.ms-.*/'
;
}
}
lib/private/preview/msoffice2007.php
0 → 100644
View file @
b3afc98f
<?php
/**
* Copyright (c) 2013 Georg Ehrke georg@ownCloud.com
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace
OC\Preview
;
//.docx, .dotx, .xlsx, .xltx, .pptx, .potx, .ppsx
class
MSOffice2007
extends
Office
{
/**
* {@inheritDoc}
*/
public
function
getMimeType
()
{
return
'/application\/vnd.openxmlformats-officedocument.*/'
;
}
}
lib/private/preview/msofficedoc.php
0 → 100644
View file @
b3afc98f
<?php
/**
* Copyright (c) 2013 Georg Ehrke georg@ownCloud.com
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace
OC\Preview
;
//.doc, .dot
class
MSOfficeDoc
extends
Office
{
/**
* {@inheritDoc}
*/
public
function
getMimeType
()
{
return
'/application\/msword/'
;
}
}
lib/private/preview/office-cl.php
deleted
100644 → 0
View file @
7c96cedd
<?php
/**
* Copyright (c) 2013 Georg Ehrke georg@ownCloud.com
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace
OC\Preview
;
// office preview is currently not supported on Windows
if
(
!
\
OC_Util
::
runningOnWindows
())
{
//we need imagick to convert
class
Office
extends
Provider
{
private
$cmd
;
public
function
getMimeType
()
{
return
null
;
}
public
function
getThumbnail
(
$path
,
$maxX
,
$maxY
,
$scalingup
,
$fileview
)
{
$this
->
initCmd
();
if
(
is_null
(
$this
->
cmd
))
{
return
false
;
}
$absPath
=
$fileview
->
toTmpFile
(
$path
);
$tmpDir
=
get_temp_dir
();
$defaultParameters
=
' -env:UserInstallation=file://'
.
escapeshellarg
(
$tmpDir
.
'/owncloud-'
.
\
OC_Util
::
getInstanceId
()
.
'/'
)
.
' --headless --nologo --nofirststartwizard --invisible --norestore --convert-to pdf --outdir '
;
$clParameters
=
\
OCP\Config
::
getSystemValue
(
'preview_office_cl_parameters'
,
$defaultParameters
);
$exec
=
$this
->
cmd
.
$clParameters
.
escapeshellarg
(
$tmpDir
)
.
' '
.
escapeshellarg
(
$absPath
);
shell_exec
(
$exec
);
//create imagick object from pdf
try
{
$pdf
=
new
\
imagick
(
$absPath
.
'.pdf'
.
'[0]'
);
$pdf
->
setImageFormat
(
'jpg'
);
}
catch
(
\
Exception
$e
)
{
unlink
(
$absPath
);
unlink
(
$absPath
.
'.pdf'
);
\
OC_Log
::
write
(
'core'
,
$e
->
getmessage
(),
\
OC_Log
::
ERROR
);
return
false
;
}
$image
=
new
\
OC_Image
();
$image
->
loadFromData
(
$pdf
);