diff options
author | kondou <kondou@ts.unde.re> | 2013-09-02 07:58:06 +0200 |
---|---|---|
committer | kondou <kondou@ts.unde.re> | 2013-09-02 07:58:06 +0200 |
commit | e5fc7b9dbeb01ac116bb132903c562c8f7d3c5b3 (patch) | |
tree | b7d8d913cdf7f4d1ce42f3027918ad0f5fbe5c3b /lib | |
parent | 8dd93c8c0288a11f04816bea2a58aee661ef9e97 (diff) | |
parent | f038cb9aea7c9a1513ab14d0df002773b17d5333 (diff) | |
download | nextcloud-server-e5fc7b9dbeb01ac116bb132903c562c8f7d3c5b3.tar.gz nextcloud-server-e5fc7b9dbeb01ac116bb132903c562c8f7d3c5b3.zip |
Merge branch 'master' into clean_up_util
Conflicts:
lib/base.php
Diffstat (limited to 'lib')
55 files changed, 2197 insertions, 337 deletions
diff --git a/lib/app.php b/lib/app.php index 1b5979107db..1a0a7e6f9a9 100644 --- a/lib/app.php +++ b/lib/app.php @@ -210,7 +210,8 @@ class OC_App{ /** * @brief enables an app * @param mixed $app app - * @return bool + * @throws \Exception + * @return void * * This function set an app as enabled in appconfig. */ @@ -228,25 +229,25 @@ class OC_App{ } } } + $l = OC_L10N::get('core'); if($app!==false) { // check if the app is compatible with this version of ownCloud $info=OC_App::getAppInfo($app); $version=OC_Util::getVersion(); if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) { - OC_Log::write('core', - 'App "'.$info['name'].'" can\'t be installed because it is' - .' not compatible with this version of ownCloud', - OC_Log::ERROR); - return false; + throw new \Exception( + $l->t("App \"%s\" can't be installed because it is not compatible with this version of ownCloud.", + array($info['name']) + ) + ); }else{ OC_Appconfig::setValue( $app, 'enabled', 'yes' ); if(isset($appdata['id'])) { OC_Appconfig::setValue( $app, 'ocsid', $appdata['id'] ); } - return true; } }else{ - return false; + throw new \Exception($l->t("No app name specified")); } } diff --git a/lib/base.php b/lib/base.php index a59fe8b7a48..fe160f73652 100644 --- a/lib/base.php +++ b/lib/base.php @@ -257,20 +257,22 @@ class OC { OC_Util::addScript("compatibility"); OC_Util::addScript("jquery.ocdialog"); OC_Util::addScript("oc-dialogs"); - OC_Util::addScript("octemplate"); OC_Util::addScript("js"); + OC_Util::addScript("octemplate"); OC_Util::addScript("eventsource"); OC_Util::addScript("config"); //OC_Util::addScript( "multiselect" ); OC_Util::addScript('search', 'result'); OC_Util::addScript('router'); + OC_Util::addScript("oc-requesttoken"); OC_Util::addStyle("styles"); + OC_Util::addStyle("apps"); + OC_Util::addStyle("fixes"); OC_Util::addStyle("multiselect"); OC_Util::addStyle("jquery-ui-1.10.0.custom"); OC_Util::addStyle("jquery-tipsy"); OC_Util::addStyle("jquery.ocdialog"); - OC_Util::addScript("oc-requesttoken"); } public static function initSession() { @@ -490,7 +492,9 @@ class OC { self::registerCacheHooks(); self::registerFilesystemHooks(); + self::registerPreviewHooks(); self::registerShareHooks(); + self::registerLogRotate(); //make sure temporary files are cleaned up register_shutdown_function(array('OC_Helper', 'cleanTmp')); @@ -553,6 +557,21 @@ class OC { } /** + * register hooks for the cache + */ + public static function registerLogRotate() { + if (OC_Config::getValue('installed', false) && OC_Config::getValue('log_rotate_size', false)) { + //don't try to do this before we are properly setup + // register cache cleanup jobs + try { //if this is executed before the upgrade to the new backgroundjob system is completed it will throw an exception + \OCP\BackgroundJob::registerJob('OC\Log\Rotate', OC_Config::getValue("datadirectory", OC::$SERVERROOT.'/data').'/owncloud.log'); + } catch (Exception $e) { + + } + } + } + + /** * register hooks for the filesystem */ public static function registerFilesystemHooks() { @@ -562,6 +581,14 @@ class OC { } /** + * register hooks for previews + */ + public static function registerPreviewHooks() { + OC_Hook::connect('OC_Filesystem', 'post_write', 'OC\Preview', 'post_write'); + OC_Hook::connect('OC_Filesystem', 'delete', 'OC\Preview', 'post_delete'); + } + + /** * register hooks for sharing */ public static function registerShareHooks() { @@ -669,12 +696,15 @@ class OC { $app = $param['app']; $file = $param['file']; $app_path = OC_App::getAppPath($app); - $file = $app_path . '/' . $file; - unset($app, $app_path); - if (file_exists($file)) { - require_once $file; - return true; + if (OC_App::isEnabled($app) && $app_path !== false) { + $file = $app_path . '/' . $file; + unset($app, $app_path); + if (file_exists($file)) { + require_once $file; + return true; + } } + header('HTTP/1.0 404 Not Found'); return false; } @@ -772,14 +802,15 @@ class OC { self::$session->set('timezone', $_POST['timezone-offset']); } - self::cleanupLoginTokens($_POST['user']); + $userid = OC_User::getUser(); + self::cleanupLoginTokens($userid); if (!empty($_POST["remember_login"])) { if (defined("DEBUG") && DEBUG) { OC_Log::write('core', 'Setting remember login to cookie', OC_Log::DEBUG); } $token = OC_Util::generateRandomBytes(32); - OC_Preferences::setValue($_POST['user'], 'login_token', $token, time()); - OC_User::setMagicInCookie($_POST["user"], $token); + OC_Preferences::setValue($userid, 'login_token', $token, time()); + OC_User::setMagicInCookie($userid, $token); } else { OC_User::unsetMagicInCookie(); } @@ -795,11 +826,16 @@ class OC { ) { return false; } - OC_App::loadApps(array('authentication')); - if (OC_User::login($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"])) { - //OC_Log::write('core',"Logged in with HTTP Authentication", OC_Log::DEBUG); - OC_User::unsetMagicInCookie(); - $_SERVER['HTTP_REQUESTTOKEN'] = OC_Util::callRegister(); + // don't redo authentication if user is already logged in + // otherwise session would be invalidated in OC_User::login with + // session_regenerate_id at every page load + if (!OC_User::isLoggedIn()) { + OC_App::loadApps(array('authentication')); + if (OC_User::login($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"])) { + //OC_Log::write('core',"Logged in with HTTP Authentication", OC_Log::DEBUG); + OC_User::unsetMagicInCookie(); + $_SERVER['HTTP_REQUESTTOKEN'] = OC_Util::callRegister(); + } } return true; } diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index ed8d085462d..3181a4b310f 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -233,10 +233,10 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * @return array */ public function getQuotaInfo() { - $rootInfo=\OC\Files\Filesystem::getFileInfo(''); + $storageInfo = OC_Helper::getStorageInfo($this->path); return array( - $rootInfo['size'], - \OC\Files\Filesystem::free_space() + $storageInfo['used'], + $storageInfo['free'] ); } diff --git a/lib/connector/sabre/quotaplugin.php b/lib/connector/sabre/quotaplugin.php index 34d4b676157..ea2cb81d1f7 100644 --- a/lib/connector/sabre/quotaplugin.php +++ b/lib/connector/sabre/quotaplugin.php @@ -3,58 +3,95 @@ /** * This plugin check user quota and deny creating files when they exceeds the quota. * - * @copyright Copyright (C) 2012 entreCables S.L. All rights reserved. * @author Sergio Cambra + * @copyright Copyright (C) 2012 entreCables S.L. All rights reserved. * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin { /** - * Reference to main server object - * - * @var Sabre_DAV_Server - */ + * Reference to main server object + * + * @var Sabre_DAV_Server + */ private $server; /** - * This initializes the plugin. - * - * This function is called by Sabre_DAV_Server, after - * addPlugin is called. - * - * This method should set up the requires event subscriptions. - * - * @param Sabre_DAV_Server $server - * @return void - */ + * is kept public to allow overwrite for unit testing + * + * @var \OC\Files\View + */ + public $fileView; + + /** + * This initializes the plugin. + * + * This function is called by Sabre_DAV_Server, after + * addPlugin is called. + * + * This method should set up the requires event subscriptions. + * + * @param Sabre_DAV_Server $server + * @return void + */ public function initialize(Sabre_DAV_Server $server) { - $this->server = $server; - $this->server->subscribeEvent('beforeWriteContent', array($this, 'checkQuota'), 10); - $this->server->subscribeEvent('beforeCreateFile', array($this, 'checkQuota'), 10); + $this->server = $server; + $server->subscribeEvent('beforeWriteContent', array($this, 'checkQuota'), 10); + $server->subscribeEvent('beforeCreateFile', array($this, 'checkQuota'), 10); } /** - * This method is called before any HTTP method and forces users to be authenticated - * - * @param string $method - * @throws Sabre_DAV_Exception - * @return bool - */ + * This method is called before any HTTP method and validates there is enough free space to store the file + * + * @param string $method + * @throws Sabre_DAV_Exception + * @return bool + */ public function checkQuota($uri, $data = null) { - $expected = $this->server->httpRequest->getHeader('X-Expected-Entity-Length'); - $length = $expected ? $expected : $this->server->httpRequest->getHeader('Content-Length'); + $length = $this->getLength(); if ($length) { if (substr($uri, 0, 1)!=='/') { $uri='/'.$uri; } list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri); - $freeSpace = \OC\Files\Filesystem::free_space($parentUri); + $freeSpace = $this->getFreeSpace($parentUri); if ($freeSpace !== \OC\Files\SPACE_UNKNOWN && $length > $freeSpace) { throw new Sabre_DAV_Exception_InsufficientStorage(); } } return true; } + + public function getLength() + { + $req = $this->server->httpRequest; + $length = $req->getHeader('X-Expected-Entity-Length'); + if (!$length) { + $length = $req->getHeader('Content-Length'); + } + + $ocLength = $req->getHeader('OC-Total-Length'); + if ($length && $ocLength) { + return max($length, $ocLength); + } + + return $length; + } + + /** + * @param $parentUri + * @return mixed + */ + public function getFreeSpace($parentUri) + { + if (is_null($this->fileView)) { + // initialize fileView + $this->fileView = \OC\Files\Filesystem::getView(); + } + + $freeSpace = $this->fileView->free_space($parentUri); + return $freeSpace; + } } diff --git a/lib/files/storage/mappedlocal.php b/lib/files/storage/mappedlocal.php index cf5d9b3ef4f..fbf1b4ebf96 100644 --- a/lib/files/storage/mappedlocal.php +++ b/lib/files/storage/mappedlocal.php @@ -65,7 +65,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ $logicalPath = $this->mapper->physicalToLogic($physicalPath); $dh = opendir($physicalPath); - while ($file = readdir($dh)) { + while (($file = readdir($dh)) !== false) { if ($file === '.' or $file === '..') { continue; } diff --git a/lib/files/view.php b/lib/files/view.php index bb737f19ef8..8aee12bf6fe 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -249,6 +249,7 @@ class View { $hooks = array('touch'); if (!$this->file_exists($path)) { + $hooks[] = 'create'; $hooks[] = 'write'; } $result = $this->basicOperation('touch', $path, $hooks, $mtime); diff --git a/lib/group/group.php b/lib/group/group.php index a752c4311c1..bcd2419b309 100644 --- a/lib/group/group.php +++ b/lib/group/group.php @@ -62,7 +62,6 @@ class Group { return $this->users; } - $users = array(); $userIds = array(); foreach ($this->backends as $backend) { $diff = array_diff( @@ -74,11 +73,8 @@ class Group { } } - foreach ($userIds as $userId) { - $users[] = $this->userManager->get($userId); - } - $this->users = $users; - return $users; + $this->users = $this->getVerifiedUsers($userIds); + return $this->users; } /** @@ -113,7 +109,7 @@ class Group { if ($backend->implementsActions(OC_GROUP_BACKEND_ADD_TO_GROUP)) { $backend->addToGroup($user->getUID(), $this->gid); if ($this->users) { - $this->users[] = $user; + $this->users[$user->getUID()] = $user; } if ($this->emitter) { $this->emitter->emit('\OC\Group', 'postAddUser', array($this, $user)); @@ -172,9 +168,7 @@ class Group { if (!is_null($offset)) { $offset -= count($userIds); } - foreach ($userIds as $userId) { - $users[$userId] = $this->userManager->get($userId); - } + $users += $this->getVerifiedUsers($userIds); if (!is_null($limit) and $limit <= 0) { return array_values($users); } @@ -191,7 +185,6 @@ class Group { * @return \OC\User\User[] */ public function searchDisplayName($search, $limit = null, $offset = null) { - $users = array(); foreach ($this->backends as $backend) { if ($backend->implementsActions(OC_GROUP_BACKEND_GET_DISPLAYNAME)) { $userIds = array_keys($backend->displayNamesInGroup($this->gid, $search, $limit, $offset)); @@ -204,9 +197,7 @@ class Group { if (!is_null($offset)) { $offset -= count($userIds); } - foreach ($userIds as $userId) { - $users[$userId] = $this->userManager->get($userId); - } + $users = $this->getVerifiedUsers($userIds); if (!is_null($limit) and $limit <= 0) { return array_values($users); } @@ -235,4 +226,23 @@ class Group { } return $result; } + + /** + * @brief returns all the Users from an array that really exists + * @param $userIds an array containing user IDs + * @return an Array with the userId as Key and \OC\User\User as value + */ + private function getVerifiedUsers($userIds) { + if(!is_array($userIds)) { + return array(); + } + $users = array(); + foreach ($userIds as $userId) { + $user = $this->userManager->get($userId); + if(!is_null($user)) { + $users[$userId] = $user; + } + } + return $users; + } } diff --git a/lib/helper.php b/lib/helper.php index 1024a570e36..5fb8fed3459 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -185,7 +185,38 @@ class OC_Helper { * Returns the path to the image of this file type. */ public static function mimetypeIcon($mimetype) { - $alias = array('application/xml' => 'code/xml'); + $alias = array( + 'application/xml' => 'code/xml', + 'application/msword' => 'x-office/document', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'x-office/document', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'x-office/document', + 'application/vnd.ms-word.document.macroEnabled.12' => 'x-office/document', + 'application/vnd.ms-word.template.macroEnabled.12' => 'x-office/document', + 'application/vnd.oasis.opendocument.text' => 'x-office/document', + 'application/vnd.oasis.opendocument.text-template' => 'x-office/document', + 'application/vnd.oasis.opendocument.text-web' => 'x-office/document', + 'application/vnd.oasis.opendocument.text-master' => 'x-office/document', + 'application/vnd.ms-powerpoint' => 'x-office/presentation', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'x-office/presentation', + 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'x-office/presentation', + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'x-office/presentation', + 'application/vnd.ms-powerpoint.addin.macroEnabled.12' => 'x-office/presentation', + 'application/vnd.ms-powerpoint.presentation.macroEnabled.12' => 'x-office/presentation', + 'application/vnd.ms-powerpoint.template.macroEnabled.12' => 'x-office/presentation', + 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => 'x-office/presentation', + 'application/vnd.oasis.opendocument.presentation' => 'x-office/presentation', + 'application/vnd.oasis.opendocument.presentation-template' => 'x-office/presentation', + 'application/vnd.ms-excel' => 'x-office/spreadsheet', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'x-office/spreadsheet', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'x-office/spreadsheet', + 'application/vnd.ms-excel.sheet.macroEnabled.12' => 'x-office/spreadsheet', + 'application/vnd.ms-excel.template.macroEnabled.12' => 'x-office/spreadsheet', + 'application/vnd.ms-excel.addin.macroEnabled.12' => 'x-office/spreadsheet', + 'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => 'x-office/spreadsheet', + 'application/vnd.oasis.opendocument.spreadsheet' => 'x-office/spreadsheet', + 'application/vnd.oasis.opendocument.spreadsheet-template' => 'x-office/spreadsheet', + ); + if (isset($alias[$mimetype])) { $mimetype = $alias[$mimetype]; } @@ -220,6 +251,21 @@ class OC_Helper { } /** + * @brief get path to preview of file + * @param string $path path + * @return string the url + * + * Returns the path to the preview of the file. + */ + public static function previewIcon($path) { + return self::linkToRoute( 'core_ajax_preview', array('x' => 36, 'y' => 36, 'file' => urlencode($path) )); + } + + public static function publicPreviewIcon( $path, $token ) { + return self::linkToRoute( 'core_ajax_public_preview', array('x' => 36, 'y' => 36, 'file' => urlencode($path), 't' => $token)); + } + + /** * @brief Make a human file size * @param int $bytes file size in bytes * @return string a human readable file size @@ -591,9 +637,26 @@ class OC_Helper { * remove all files in PHP /oc-noclean temp dir */ public static function cleanTmpNoClean() { - $tmpDirNoCleanFile = get_temp_dir() . '/oc-noclean/'; - if (file_exists($tmpDirNoCleanFile)) { - self::rmdirr($tmpDirNoCleanFile); + $tmpDirNoCleanName=get_temp_dir() . '/oc-noclean/'; + if(file_exists($tmpDirNoCleanName) && is_dir($tmpDirNoCleanName)) { + $files=scandir($tmpDirNoCleanName); + foreach($files as $file) { + $fileName = $tmpDirNoCleanName . $file; + if (!\OC\Files\Filesystem::isIgnoredDir($file) && filemtime($fileName) + 600 < time()) { + unlink($fileName); + } + } + // if oc-noclean is empty delete it + $isTmpDirNoCleanEmpty = true; + $tmpDirNoClean = opendir($tmpDirNoCleanName); + while (false !== ($file = readdir($tmpDirNoClean))) { + if (!\OC\Files\Filesystem::isIgnoredDir($file)) { + $isTmpDirNoCleanEmpty = false; + } + } + if ($isTmpDirNoCleanEmpty) { + rmdir($tmpDirNoCleanName); + } } } @@ -824,24 +887,25 @@ class OC_Helper { } /** - * Calculate the disc space + * Calculate the disc space for the given path + * + * @param string $path + * @return array */ - public static function getStorageInfo() { - $rootInfo = \OC\Files\Filesystem::getFileInfo('/'); + public static function getStorageInfo($path) { + $rootInfo = \OC\Files\Filesystem::getFileInfo($path); $used = $rootInfo['size']; if ($used < 0) { $used = 0; } - $free = \OC\Files\Filesystem::free_space(); + $free = \OC\Files\Filesystem::free_space($path); if ($free >= 0) { $total = $free + $used; } else { $total = $free; //either unknown or unlimited } - if ($total == 0) { - $total = 1; // prevent division by zero - } - if ($total >= 0) { + if ($total > 0) { + // prevent division by zero or error codes (negative values) $relative = round(($used / $total) * 10000) / 100; } else { $relative = 0; diff --git a/lib/image.php b/lib/image.php index 4bc38e20e56..7761a3c7737 100644 --- a/lib/image.php +++ b/lib/image.php @@ -25,24 +25,27 @@ */ class OC_Image { protected $resource = false; // tmp resource. - protected $imagetype = IMAGETYPE_PNG; // Default to png if file type isn't evident. - protected $bit_depth = 24; - protected $filepath = null; + protected $imageType = IMAGETYPE_PNG; // Default to png if file type isn't evident. + protected $mimeType = "image/png"; // Default to png + protected $bitDepth = 24; + protected $filePath = null; + + private $fileInfo; /** * @brief Get mime type for an image file. * @param $filepath The path to a local image file. * @returns string The mime type if the it could be determined, otherwise an empty string. */ - static public function getMimeTypeForFile($filepath) { + static public function getMimeTypeForFile($filePath) { // exif_imagetype throws "read error!" if file is less than 12 byte - if (filesize($filepath) > 11) { - $imagetype = exif_imagetype($filepath); + if (filesize($filePath) > 11) { + $imageType = exif_imagetype($filePath); } else { - $imagetype = false; + $imageType = false; } - return $imagetype ? image_type_to_mime_type($imagetype) : ''; + return $imageType ? image_type_to_mime_type($imageType) : ''; } /** @@ -50,14 +53,19 @@ class OC_Image { * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function. * @returns bool False on error */ - public function __construct($imageref = null) { + public function __construct($imageRef = null) { //OC_Log::write('core',__METHOD__.'(): start', OC_Log::DEBUG); if(!extension_loaded('gd') || !function_exists('gd_info')) { OC_Log::write('core', __METHOD__.'(): GD module not installed', OC_Log::ERROR); return false; } - if(!is_null($imageref)) { - $this->load($imageref); + + if (\OC_Util::fileInfoLoaded()) { + $this->fileInfo = new finfo(FILEINFO_MIME_TYPE); + } + + if(!is_null($imageRef)) { + $this->load($imageRef); } } @@ -74,7 +82,7 @@ class OC_Image { * @returns int */ public function mimeType() { - return $this->valid() ? image_type_to_mime_type($this->imagetype) : ''; + return $this->valid() ? $this->mimeType : ''; } /** @@ -157,30 +165,30 @@ class OC_Image { * @returns bool */ - public function save($filepath=null) { - if($filepath === null && $this->filepath === null) { + public function save($filePath=null) { + if($filePath === null && $this->filePath === null) { OC_Log::write('core', __METHOD__.'(): called with no path.', OC_Log::ERROR); return false; - } elseif($filepath === null && $this->filepath !== null) { - $filepath = $this->filepath; + } elseif($filePath === null && $this->filePath !== null) { + $filePath = $this->filePath; } - return $this->_output($filepath); + return $this->_output($filePath); } /** * @brief Outputs/saves the image. */ - private function _output($filepath=null) { - if($filepath) { - if (!file_exists(dirname($filepath))) - mkdir(dirname($filepath), 0777, true); - if(!is_writable(dirname($filepath))) { + private function _output($filePath=null) { + if($filePath) { + if (!file_exists(dirname($filePath))) + mkdir(dirname($filePath), 0777, true); + if(!is_writable(dirname($filePath))) { OC_Log::write('core', - __METHOD__.'(): Directory \''.dirname($filepath).'\' is not writable.', + __METHOD__.'(): Directory \''.dirname($filePath).'\' is not writable.', OC_Log::ERROR); return false; - } elseif(is_writable(dirname($filepath)) && file_exists($filepath) && !is_writable($filepath)) { - OC_Log::write('core', __METHOD__.'(): File \''.$filepath.'\' is not writable.', OC_Log::ERROR); + } elseif(is_writable(dirname($filePath)) && file_exists($filePath) && !is_writable($filePath)) { + OC_Log::write('core', __METHOD__.'(): File \''.$filePath.'\' is not writable.', OC_Log::ERROR); return false; } } @@ -188,30 +196,30 @@ class OC_Image { return false; } - $retval = false; - switch($this->imagetype) { + $retVal = false; + switch($this->imageType) { case IMAGETYPE_GIF: - $retval = imagegif($this->resource, $filepath); + $retVal = imagegif($this->resource, $filePath); break; case IMAGETYPE_JPEG: - $retval = imagejpeg($this->resource, $filepath); + $retVal = imagejpeg($this->resource, $filePath); break; case IMAGETYPE_PNG: - $retval = imagepng($this->resource, $filepath); + $retVal = imagepng($this->resource, $filePath); break; case IMAGETYPE_XBM: - $retval = imagexbm($this->resource, $filepath); + $retVal = imagexbm($this->resource, $filePath); break; case IMAGETYPE_WBMP: - $retval = imagewbmp($this->resource, $filepath); + $retVal = imagewbmp($this->resource, $filePath); break; case IMAGETYPE_BMP: - $retval = imagebmp($this->resource, $filepath, $this->bit_depth); + $retVal = imagebmp($this->resource, $filePath, $this->bitDepth); break; default: - $retval = imagepng($this->resource, $filepath); + $retVal = imagepng($this->resource, $filePath); } - return $retval; + return $retVal; } /** @@ -233,7 +241,21 @@ class OC_Image { */ function data() { ob_start(); - $res = imagepng($this->resource); + switch ($this->mimeType) { + case "image/png": + $res = imagepng($this->resource); + break; + case "image/jpeg": + $res = imagejpeg($this->resource); + break; + case "image/gif": + $res = imagegif($this->resource); + break; + default: + $res = imagepng($this->resource); + OC_Log::write('core', 'OC_Image->data. Couldn\'t guess mimetype, defaulting to png', OC_Log::INFO); + break; + } if (!$res) { OC_Log::write('core', 'OC_Image->data. Error getting image data.', OC_Log::ERROR); } @@ -261,11 +283,11 @@ class OC_Image { OC_Log::write('core', 'OC_Image->fixOrientation() No image loaded.', OC_Log::DEBUG); return -1; } - if(is_null($this->filepath) || !is_readable($this->filepath)) { + if(is_null($this->filePath) || !is_readable($this->filePath)) { OC_Log::write('core', 'OC_Image->fixOrientation() No readable file path set.', OC_Log::DEBUG); return -1; } - $exif = @exif_read_data($this->filepath, 'IFD0'); + $exif = @exif_read_data($this->filePath, 'IFD0'); if(!$exif) { return -1; } @@ -351,19 +373,19 @@ class OC_Image { * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function or a file resource (file handle ). * @returns An image resource or false on error */ - public function load($imageref) { - if(is_resource($imageref)) { - if(get_resource_type($imageref) == 'gd') { - $this->resource = $imageref; + public function load($imageRef) { + if(is_resource($imageRef)) { + if(get_resource_type($imageRef) == 'gd') { + $this->resource = $imageRef; return $this->resource; - } elseif(in_array(get_resource_type($imageref), array('file', 'stream'))) { - return $this->loadFromFileHandle($imageref); + } elseif(in_array(get_resource_type($imageRef), array('file', 'stream'))) { + return $this->loadFromFileHandle($imageRef); } - } elseif($this->loadFromFile($imageref) !== false) { + } elseif($this->loadFromFile($imageRef) !== false) { return $this->resource; - } elseif($this->loadFromBase64($imageref) !== false) { + } elseif($this->loadFromBase64($imageRef) !== false) { return $this->resource; - } elseif($this->loadFromData($imageref) !== false) { + } elseif($this->loadFromData($imageRef) !== false) { return $this->resource; } else { OC_Log::write('core', __METHOD__.'(): couldn\'t load anything. Giving up!', OC_Log::DEBUG); @@ -390,62 +412,62 @@ class OC_Image { * @param $imageref The path to a local file. * @returns An image resource or false on error */ - public function loadFromFile($imagepath=false) { + public function loadFromFile($imagePath=false) { // exif_imagetype throws "read error!" if file is less than 12 byte - if(!@is_file($imagepath) || !file_exists($imagepath) || filesize($imagepath) < 12 || !is_readable($imagepath)) { + if(!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) { // Debug output disabled because this method is tried before loadFromBase64? - OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: '.$imagepath, OC_Log::DEBUG); + OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: '.$imagePath, OC_Log::DEBUG); return false; } - $itype = exif_imagetype($imagepath); - switch($itype) { + $iType = exif_imagetype($imagePath); + switch ($iType) { case IMAGETYPE_GIF: if (imagetypes() & IMG_GIF) { - $this->resource = imagecreatefromgif($imagepath); + $this->resource = imagecreatefromgif($imagePath); } else { OC_Log::write('core', - 'OC_Image->loadFromFile, GIF images not supported: '.$imagepath, + 'OC_Image->loadFromFile, GIF images not supported: '.$imagePath, OC_Log::DEBUG); } break; case IMAGETYPE_JPEG: if (imagetypes() & IMG_JPG) { - $this->resource = imagecreatefromjpeg($imagepath); + $this->resource = imagecreatefromjpeg($imagePath); } else { OC_Log::write('core', - 'OC_Image->loadFromFile, JPG images not supported: '.$imagepath, + 'OC_Image->loadFromFile, JPG images not supported: '.$imagePath, OC_Log::DEBUG); } break; case IMAGETYPE_PNG: if (imagetypes() & IMG_PNG) { - $this->resource = imagecreatefrompng($imagepath); + $this->resource = imagecreatefrompng($imagePath); } else { OC_Log::write('core', - 'OC_Image->loadFromFile, PNG images not supported: '.$imagepath, + 'OC_Image->loadFromFile, PNG images not supported: '.$imagePath, OC_Log::DEBUG); } break; case IMAGETYPE_XBM: if (imagetypes() & IMG_XPM) { - $this->resource = imagecreatefromxbm($imagepath); + $this->resource = imagecreatefromxbm($imagePath); } else { OC_Log::write('core', - 'OC_Image->loadFromFile, XBM/XPM images not supported: '.$imagepath, + 'OC_Image->loadFromFile, XBM/XPM images not supported: '.$imagePath, OC_Log::DEBUG); } break; case IMAGETYPE_WBMP: if (imagetypes() & IMG_WBMP) { - $this->resource = imagecreatefromwbmp($imagepath); + $this->resource = imagecreatefromwbmp($imagePath); } else { OC_Log::write('core', - 'OC_Image->loadFromFile, WBMP images not supported: '.$imagepath, + 'OC_Image->loadFromFile, WBMP images not supported: '.$imagePath, OC_Log::DEBUG); } break; case IMAGETYPE_BMP: - $this->resource = $this->imagecreatefrombmp($imagepath); + $this->resource = $this->imagecreatefrombmp($imagePath); break; /* case IMAGETYPE_TIFF_II: // (intel byte order) @@ -474,14 +496,15 @@ class OC_Image { default: // this is mostly file created from encrypted file - $this->resource = imagecreatefromstring(\OC\Files\Filesystem::file_get_contents(\OC\Files\Filesystem::getLocalPath($imagepath))); - $itype = IMAGETYPE_PNG; + $this->resource = imagecreatefromstring(\OC\Files\Filesystem::file_get_contents(\OC\Files\Filesystem::getLocalPath($imagePath))); + $iType = IMAGETYPE_PNG; OC_Log::write('core', 'OC_Image->loadFromFile, Default', OC_Log::DEBUG); break; } if($this->valid()) { - $this->imagetype = $itype; - $this->filepath = $imagepath; + $this->imageType = $iType; + $this->mimeType = image_type_to_mime_type($iType); + $this->filePath = $imagePath; } return $this->resource; } @@ -496,6 +519,14 @@ class OC_Image { return false; } $this->resource = @imagecreatefromstring($str); + if ($this->fileInfo) { + $this->mimeType = $this->fileInfo->buffer($str); + } + if(is_resource($this->resource)) { + imagealphablending($this->resource, false); + imagesavealpha($this->resource, true); + } + if(!$this->resource) { OC_Log::write('core', 'OC_Image->loadFromData, couldn\'t load', OC_Log::DEBUG); return false; @@ -515,6 +546,9 @@ class OC_Image { $data = base64_decode($str); if($data) { // try to load from string data $this->resource = @imagecreatefromstring($data); + if ($this->fileInfo) { + $this->mimeType = $this->fileInfo->buffer($data); + } if(!$this->resource) { OC_Log::write('core', 'OC_Image->loadFromBase64, couldn\'t load', OC_Log::DEBUG); return false; @@ -534,16 +568,16 @@ class OC_Image { * </p> * @return resource an image resource identifier on success, <b>FALSE</b> on errors. */ - private function imagecreatefrombmp($filename) { - if (!($fh = fopen($filename, 'rb'))) { - trigger_error('imagecreatefrombmp: Can not open ' . $filename, E_USER_WARNING); + private function imagecreatefrombmp($fileName) { + if (!($fh = fopen($fileName, 'rb'))) { + trigger_error('imagecreatefrombmp: Can not open ' . $fileName, E_USER_WARNING); return false; } // read file header $meta = unpack('vtype/Vfilesize/Vreserved/Voffset', fread($fh, 14)); // check for bitmap if ($meta['type'] != 19778) { - trigger_error('imagecreatefrombmp: ' . $filename . ' is not a bitmap!', E_USER_WARNING); + trigger_error('imagecreatefrombmp: ' . $fileName . ' is not a bitmap!', E_USER_WARNING); return false; } // read image header @@ -554,7 +588,7 @@ class OC_Image { } // set bytes and padding $meta['bytes'] = $meta['bits'] / 8; - $this->bit_depth = $meta['bits']; //remember the bit depth for the imagebmp call + $this->bitDepth = $meta['bits']; //remember the bit depth for the imagebmp call $meta['decal'] = 4 - (4 * (($meta['width'] * $meta['bytes'] / 4)- floor($meta['width'] * $meta['bytes'] / 4))); if ($meta['decal'] == 4) { $meta['decal'] = 0; @@ -590,7 +624,7 @@ class OC_Image { $p = 0; $vide = chr(0); $y = $meta['height'] - 1; - $error = 'imagecreatefrombmp: ' . $filename . ' has not enough data!'; + $error = 'imagecreatefrombmp: ' . $fileName . ' has not enough data!'; // loop through the image data beginning with the lower left corner while ($y >= 0) { $x = 0; @@ -653,7 +687,7 @@ class OC_Image { break; default: trigger_error('imagecreatefrombmp: ' - . $filename . ' has ' . $meta['bits'] . ' bits and this is not supported!', + . $fileName . ' has ' . $meta['bits'] . ' bits and this is not supported!', E_USER_WARNING); return false; } @@ -673,24 +707,24 @@ class OC_Image { * @param $maxsize The maximum size of either the width or height. * @returns bool */ - public function resize($maxsize) { + public function resize($maxSize) { if(!$this->valid()) { OC_Log::write('core', __METHOD__.'(): No image loaded', OC_Log::ERROR); return false; } - $width_orig=imageSX($this->resource); - $height_orig=imageSY($this->resource); - $ratio_orig = $width_orig/$height_orig; + $widthOrig=imageSX($this->resource); + $heightOrig=imageSY($this->resource); + $ratioOrig = $widthOrig/$heightOrig; - if ($ratio_orig > 1) { - $new_height = round($maxsize/$ratio_orig); - $new_width = $maxsize; + if ($ratioOrig > 1) { + $newHeight = round($maxSize/$ratioOrig); + $newWidth = $maxSize; } else { - $new_width = round($maxsize*$ratio_orig); - $new_height = $maxsize; + $newWidth = round($maxSize*$ratioOrig); + $newHeight = $maxSize; } - $this->preciseResize(round($new_width), round($new_height)); + $this->preciseResize(round($newWidth), round($newHeight)); return true; } @@ -699,8 +733,8 @@ class OC_Image { OC_Log::write('core', __METHOD__.'(): No image loaded', OC_Log::ERROR); return false; } - $width_orig=imageSX($this->resource); - $height_orig=imageSY($this->resource); + $widthOrig=imageSX($this->resource); + $heightOrig=imageSY($this->resource); $process = imagecreatetruecolor($width, $height); if ($process == false) { @@ -710,13 +744,13 @@ class OC_Image { } // preserve transparency - if($this->imagetype == IMAGETYPE_GIF or $this->imagetype == IMAGETYPE_PNG) { + if($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) { imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127)); imagealphablending($process, false); imagesavealpha($process, true); } - imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); + imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $widthOrig, $heightOrig); if ($process == false) { OC_Log::write('core', __METHOD__.'(): Error resampling process image '.$width.'x'.$height, OC_Log::ERROR); imagedestroy($process); @@ -737,19 +771,19 @@ class OC_Image { OC_Log::write('core', 'OC_Image->centerCrop, No image loaded', OC_Log::ERROR); return false; } - $width_orig=imageSX($this->resource); - $height_orig=imageSY($this->resource); - if($width_orig === $height_orig and $size==0) { + $widthOrig=imageSX($this->resource); + $heightOrig=imageSY($this->resource); + if($widthOrig === $heightOrig and $size==0) { return true; } - $ratio_orig = $width_orig/$height_orig; - $width = $height = min($width_orig, $height_orig); + $ratioOrig = $widthOrig/$heightOrig; + $width = $height = min($widthOrig, $heightOrig); - if ($ratio_orig > 1) { - $x = ($width_orig/2) - ($width/2); + if ($ratioOrig > 1) { + $x = ($widthOrig/2) - ($width/2); $y = 0; } else { - $y = ($height_orig/2) - ($height/2); + $y = ($heightOrig/2) - ($height/2); $x = 0; } if($size>0) { @@ -767,7 +801,7 @@ class OC_Image { } // preserve transparency - if($this->imagetype == IMAGETYPE_GIF or $this->imagetype == IMAGETYPE_PNG) { + if($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) { imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127)); imagealphablending($process, false); imagesavealpha($process, true); @@ -827,9 +861,9 @@ class OC_Image { OC_Log::write('core', __METHOD__.'(): No image loaded', OC_Log::ERROR); return false; } - $width_orig=imageSX($this->resource); - $height_orig=imageSY($this->resource); - $ratio = $width_orig/$height_orig; + $widthOrig=imageSX($this->resource); + $heightOrig=imageSY($this->resource); + $ratio = $widthOrig/$heightOrig; $newWidth = min($maxWidth, $ratio*$maxHeight); $newHeight = min($maxHeight, $maxWidth/$ratio); @@ -863,7 +897,7 @@ if ( ! function_exists( 'imagebmp') ) { * @param int $compression [optional] * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure. */ - function imagebmp($im, $filename='', $bit=24, $compression=0) { + function imagebmp($im, $fileName='', $bit=24, $compression=0) { if (!in_array($bit, array(1, 4, 8, 16, 24, 32))) { $bit = 24; } @@ -874,14 +908,14 @@ if ( ! function_exists( 'imagebmp') ) { imagetruecolortopalette($im, true, $bits); $width = imagesx($im); $height = imagesy($im); - $colors_num = imagecolorstotal($im); - $rgb_quad = ''; + $colorsNum = imagecolorstotal($im); + $rgbQuad = ''; if ($bit <= 8) { - for ($i = 0; $i < $colors_num; $i++) { + for ($i = 0; $i < $colorsNum; $i++) { $colors = imagecolorsforindex($im, $i); - $rgb_quad .= chr($colors['blue']) . chr($colors['green']) . chr($colors['red']) . "\0"; + $rgbQuad .= chr($colors['blue']) . chr($colors['green']) . chr($colors['red']) . "\0"; } - $bmp_data = ''; + $bmpData = ''; if ($compression == 0 || $bit < 8) { $compression = 0; $extra = ''; @@ -899,35 +933,35 @@ if ( ! function_exists( 'imagebmp') ) { $bin |= $index << $k; $i++; } - $bmp_data .= chr($bin); + $bmpData .= chr($bin); } - $bmp_data .= $extra; + $bmpData .= $extra; } } // RLE8 else if ($compression == 1 && $bit == 8) { for ($j = $height - 1; $j >= 0; $j--) { - $last_index = "\0"; - $same_num = 0; + $lastIndex = "\0"; + $sameNum = 0; for ($i = 0; $i <= $width; $i++) { $index = imagecolorat($im, $i, $j); - if ($index !== $last_index || $same_num > 255) { - if ($same_num != 0) { - $bmp_data .= chr($same_num) . chr($last_index); + if ($index !== $lastIndex || $sameNum > 255) { + if ($sameNum != 0) { + $bmpData .= chr($same_num) . chr($lastIndex); } - $last_index = $index; - $same_num = 1; + $lastIndex = $index; + $sameNum = 1; } else { - $same_num++; + $sameNum++; } } - $bmp_data .= "\0\0"; + $bmpData .= "\0\0"; } - $bmp_data .= "\0\1"; + $bmpData .= "\0\1"; } - $size_quad = strlen($rgb_quad); - $size_data = strlen($bmp_data); + $sizeQuad = strlen($rgbQuad); + $sizeData = strlen($bmpData); } else { $extra = ''; @@ -935,7 +969,7 @@ if ( ! function_exists( 'imagebmp') ) { if ($padding % 4 != 0) { $extra = str_repeat("\0", $padding); } - $bmp_data = ''; + $bmpData = ''; for ($j = $height - 1; $j >= 0; $j--) { for ($i = 0; $i < $width; $i++) { $index = imagecolorat($im, $i, $j); @@ -945,27 +979,27 @@ if ( ! function_exists( 'imagebmp') ) { $bin |= ($colors['red'] >> 3) << 10; $bin |= ($colors['green'] >> 3) << 5; $bin |= $colors['blue'] >> 3; - $bmp_data .= pack("v", $bin); + $bmpData .= pack("v", $bin); } else { - $bmp_data .= pack("c*", $colors['blue'], $colors['green'], $colors['red']); + $bmpData .= pack("c*", $colors['blue'], $colors['green'], $colors['red']); } } - $bmp_data .= $extra; + $bmpData .= $extra; } - $size_quad = 0; - $size_data = strlen($bmp_data); - $colors_num = 0; - } - $file_header = 'BM' . pack('V3', 54 + $size_quad + $size_data, 0, 54 + $size_quad); - $info_header = pack('V3v2V*', 0x28, $width, $height, 1, $bit, $compression, $size_data, 0, 0, $colors_num, 0); - if ($filename != '') { - $fp = fopen($filename, 'wb'); - fwrite($fp, $file_header . $info_header . $rgb_quad . $bmp_data); + $sizeQuad = 0; + $sizeData = strlen($bmpData); + $colorsNum = 0; + } + $fileHeader = 'BM' . pack('V3', 54 + $sizeQuad + $sizeData, 0, 54 + $sizeQuad); + $infoHeader = pack('V3v2V*', 0x28, $width, $height, 1, $bit, $compression, $sizeData, 0, 0, $colorsNum, 0); + if ($fileName != '') { + $fp = fopen($fileName, 'wb'); + fwrite($fp, $fileHeader . $infoHeader . $rgbQuad . $bmpData); fclose($fp); return true; } - echo $file_header . $info_header. $rgb_quad . $bmp_data; + echo $fileHeader . $infoHeader. $rgbQuad . $bmpData; return true; } } @@ -977,8 +1011,8 @@ if ( ! function_exists( 'exif_imagetype' ) ) { * @param string $filename * @return string|boolean */ - function exif_imagetype ( $filename ) { - if ( ( $info = getimagesize( $filename ) ) !== false ) { + function exif_imagetype ( $fileName ) { + if ( ( $info = getimagesize( $fileName ) ) !== false ) { return $info[2]; } return false; diff --git a/lib/installer.php b/lib/installer.php index c29f9ec8982..b9684eaeea0 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -27,6 +27,7 @@ class OC_Installer{ /** * @brief Installs an app * @param $data array with all information + * @throws \Exception * @returns integer * * This function installs an app. All information needed are passed in the @@ -56,23 +57,22 @@ class OC_Installer{ * needed to get the app working. */ public static function installApp( $data = array()) { + $l = \OC_L10N::get('lib'); + if(!isset($data['source'])) { - OC_Log::write('core', 'No source specified when installing app', OC_Log::ERROR); - return false; + throw new \Exception($l->t("No source specified when installing app")); } //download the file if necesary if($data['source']=='http') { $path=OC_Helper::tmpFile(); if(!isset($data['href'])) { - OC_Log::write('core', 'No href specified when installing app from http', OC_Log::ERROR); - return false; + throw new \Exception($l->t("No href specified when installing app from http")); } copy($data['href'], $path); }else{ if(!isset($data['path'])) { - OC_Log::write('core', 'No path specified when installing app from local file', OC_Log::ERROR); - return false; + throw new \Exception($l->t("No path specified when installing app from local file")); } $path=$data['path']; } @@ -86,8 +86,7 @@ class OC_Installer{ rename($path, $path.'.tgz'); $path.='.tgz'; }else{ - OC_Log::write('core', 'Archives of type '.$mime.' are not supported', OC_Log::ERROR); - return false; + throw new \Exception($l->t("Archives of type %s are not supported", array($mime))); } //extract the archive in a temporary folder @@ -97,12 +96,11 @@ class OC_Installer{ if($archive=OC_Archive::open($path)) { $archive->extract($extractDir); } else { - OC_Log::write('core', 'Failed to open archive when installing app', OC_Log::ERROR); OC_Helper::rmdirr($extractDir); if($data['source']=='http') { unlink($path); } - return false; + throw new \Exception($l->t("Failed to open archive when installing app")); } //load the info.xml file of the app @@ -118,62 +116,48 @@ class OC_Installer{ } } if(!is_file($extractDir.'/appinfo/info.xml')) { - OC_Log::write('core', 'App does not provide an info.xml file', OC_Log::ERROR); OC_Helper::rmdirr($extractDir); if($data['source']=='http') { unlink($path); } - return false; + throw new \Exception($l->t("App does not provide an info.xml file")); } $info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml', true); // check the code for not allowed calls if(!OC_Installer::checkCode($info['id'], $extractDir)) { - OC_Log::write('core', 'App can\'t be installed because of not allowed code in the App', OC_Log::ERROR); OC_Helper::rmdirr($extractDir); - return false; + throw new \Exception($l->t("App can't be installed because of not allowed code in the App")); } // check if the app is compatible with this version of ownCloud if( - !isset($info['require']) - or !OC_App::isAppVersionCompatible(OC_Util::getVersion(), $info['require']) - ) { - OC_Log::write('core', - 'App can\'t be installed because it is not compatible with this version of ownCloud', - OC_Log::ERROR); + !isset($info['require']) + or !OC_App::isAppVersionCompatible(OC_Util::getVersion(), $info['require']) + ) { OC_Helper::rmdirr($extractDir); - return false; + throw new \Exception($l->t("App can't be installed because it is not compatible with this version of ownCloud")); } // check if shipped tag is set which is only allowed for apps that are shipped with ownCloud if(isset($info['shipped']) and ($info['shipped']=='true')) { - OC_Log::write('core', - 'App can\'t be installed because it contains the <shipped>true</shippe>' - .' tag which is not allowed for non shipped apps', - OC_Log::ERROR); OC_Helper::rmdirr($extractDir); - return false; + throw new \Exception($l->t("App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps")); } // check if the ocs version is the same as the version in info.xml/version if(!isset($info['version']) or ($info['version']<>$data['appdata']['version'])) { - OC_Log::write('core', - 'App can\'t be installed because the version in info.xml/version is not the same' - .' as the version reported from the app store', - OC_Log::ERROR); OC_Helper::rmdirr($extractDir); - return false; + throw new \Exception($l->t("App can't be installed because the version in info.xml/version is not the same as the version reported from the app store")); } $basedir=OC_App::getInstallPath().'/'.$info['id']; //check if the destination directory already exists if(is_dir($basedir)) { - OC_Log::write('core', 'App directory already exists', OC_Log::WARN); OC_Helper::rmdirr($extractDir); if($data['source']=='http') { unlink($path); } - return false; + throw new \Exception($l->t("App directory already exists")); } if(isset($data['pretent']) and $data['pretent']==true) { @@ -182,12 +166,11 @@ class OC_Installer{ //copy the app to the correct place if(@!mkdir($basedir)) { - OC_Log::write('core', 'Can\'t create app folder. Please fix permissions. ('.$basedir.')', OC_Log::ERROR); OC_Helper::rmdirr($extractDir); if($data['source']=='http') { unlink($path); } - return false; + throw new \Exception($l->t("Can't create app folder. Please fix permissions. %s", array($basedir))); } OC_Helper::copyr($extractDir, $basedir); diff --git a/lib/l10n/ca.php b/lib/l10n/ca.php index 67ccdabc636..166455e652c 100644 --- a/lib/l10n/ca.php +++ b/lib/l10n/ca.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "L'aplicació \"%s\" no es pot instal·lar perquè no és compatible amb aquesta versió d'ownCloud.", +"No app name specified" => "No heu especificat cap nom d'aplicació", "Help" => "Ajuda", "Personal" => "Personal", "Settings" => "Configuració", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Torna a Fitxers", "Selected files too large to generate zip file." => "Els fitxers seleccionats son massa grans per generar un fitxer zip.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Baixeu els fitxers en trossos petits, de forma separada, o pregunteu a l'administrador.", +"No source specified when installing app" => "No heu especificat la font en instal·lar l'aplicació", +"No href specified when installing app from http" => "No heu especificat href en instal·lar l'aplicació des de http", +"No path specified when installing app from local file" => "No heu seleccionat el camí en instal·lar una aplicació des d'un fitxer local", +"Archives of type %s are not supported" => "Els fitxers del tipus %s no són compatibles", +"Failed to open archive when installing app" => "Ha fallat l'obertura del fitxer en instal·lar l'aplicació", +"App does not provide an info.xml file" => "L'aplicació no proporciona un fitxer info.xml", +"App can't be installed because of not allowed code in the App" => "L'aplicació no es pot instal·lar perquè hi ha codi no autoritzat en l'aplicació", +"App can't be installed because it is not compatible with this version of ownCloud" => "L'aplicació no es pot instal·lar perquè no és compatible amb aquesta versió d'ownCloud", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "L'aplicació no es pot instal·lar perquè conté l'etiqueta <shipped>vertader</shipped> que no es permet per aplicacions no enviades", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "L'aplicació no es pot instal·lar perquè la versió a info.xml/version no és la mateixa que la versió indicada des de la botiga d'aplicacions", +"App directory already exists" => "La carpeta de l'aplicació ja existeix", +"Can't create app folder. Please fix permissions. %s" => "No es pot crear la carpeta de l'aplicació. Arregleu els permisos. %s", "Application is not enabled" => "L'aplicació no està habilitada", "Authentication error" => "Error d'autenticació", "Token expired. Please reload page." => "El testimoni ha expirat. Torneu a carregar la pàgina.", @@ -40,13 +54,13 @@ $TRANSLATIONS = array( "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "El servidor web no està configurat correctament per permetre la sincronització de fitxers perquè la interfície WebDAV sembla no funcionar correctament.", "Please double check the <a href='%s'>installation guides</a>." => "Comproveu les <a href='%s'>guies d'instal·lació</a>.", "seconds ago" => "segons enrere", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), +"_%n minute ago_::_%n minutes ago_" => array("fa %n minut","fa %n minuts"), +"_%n hour ago_::_%n hours ago_" => array("fa %n hora","fa %n hores"), "today" => "avui", "yesterday" => "ahir", -"_%n day go_::_%n days ago_" => array("",""), +"_%n day go_::_%n days ago_" => array("fa %n dia","fa %n dies"), "last month" => "el mes passat", -"_%n month ago_::_%n months ago_" => array("",""), +"_%n month ago_::_%n months ago_" => array("fa %n mes","fa %n mesos"), "last year" => "l'any passat", "years ago" => "anys enrere", "Caused by:" => "Provocat per:", diff --git a/lib/l10n/cs_CZ.php b/lib/l10n/cs_CZ.php index 1a80fc78bb6..fed9ad03c01 100644 --- a/lib/l10n/cs_CZ.php +++ b/lib/l10n/cs_CZ.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Aplikace \"%s\" nemůže být nainstalována, protože není kompatibilní s touto verzí ownCloud.", +"No app name specified" => "Nebyl zadan název aplikace", "Help" => "Nápověda", "Personal" => "Osobní", "Settings" => "Nastavení", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Zpět k souborům", "Selected files too large to generate zip file." => "Vybrané soubory jsou příliš velké pro vytvoření ZIP souboru.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Stáhněte soubory po menších částech, samostatně, nebo se obraťte na správce.", +"No source specified when installing app" => "Nebyl zadán zdroj při instalaci aplikace", +"No href specified when installing app from http" => "Nebyl zadán odkaz pro instalaci aplikace z HTTP", +"No path specified when installing app from local file" => "Nebyla zadána cesta pro instalaci aplikace z místního souboru", +"Archives of type %s are not supported" => "Archivy typu %s nejsou podporovány", +"Failed to open archive when installing app" => "Chyba při otevírání archivu během instalace aplikace", +"App does not provide an info.xml file" => "Aplikace neposkytuje soubor info.xml", +"App can't be installed because of not allowed code in the App" => "Aplikace nemůže být nainstalována, protože obsahuje nepovolený kód", +"App can't be installed because it is not compatible with this version of ownCloud" => "Aplikace nemůže být nainstalována, protože není kompatibilní s touto verzí ownCloud", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Aplikace nemůže být nainstalována, protože obsahuje značku\n<shipped>\n\ntrue\n</shipped>\n\ncož není povoleno pro nedodávané aplikace", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Aplikace nemůže být nainstalována, protože verze uvedená v info.xml/version nesouhlasí s verzí oznámenou z úložiště aplikací.", +"App directory already exists" => "Adresář aplikace již existuje", +"Can't create app folder. Please fix permissions. %s" => "Nelze vytvořit složku aplikace. Opravte práva souborů. %s", "Application is not enabled" => "Aplikace není povolena", "Authentication error" => "Chyba ověření", "Token expired. Please reload page." => "Token vypršel. Obnovte prosím stránku.", diff --git a/lib/l10n/da.php b/lib/l10n/da.php index 78859b08745..26903142763 100644 --- a/lib/l10n/da.php +++ b/lib/l10n/da.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "App'en \"%s\" kan ikke blive installeret, da den ikke er kompatibel med denne version af ownCloud.", +"No app name specified" => "Intet app-navn angivet", "Help" => "Hjælp", "Personal" => "Personligt", "Settings" => "Indstillinger", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Tilbage til Filer", "Selected files too large to generate zip file." => "De markerede filer er for store til at generere en ZIP-fil.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Download filerne i små bider, seperat, eller kontakt venligst din administrator.", +"No source specified when installing app" => "Ingen kilde angivet under installation af app", +"No href specified when installing app from http" => "Ingen href angivet under installation af app via http", +"No path specified when installing app from local file" => "Ingen sti angivet under installation af app fra lokal fil", +"Archives of type %s are not supported" => "Arkiver af type %s understøttes ikke", +"Failed to open archive when installing app" => "Kunne ikke åbne arkiv under installation af appen", +"App does not provide an info.xml file" => "Der følger ingen info.xml-fil med appen", +"App can't be installed because of not allowed code in the App" => "Appen kan ikke installeres, da den indeholder ikke-tilladt kode", +"App can't be installed because it is not compatible with this version of ownCloud" => "Appen kan ikke installeres, da den ikke er kompatibel med denne version af ownCloud.", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Appen kan ikke installeres, da den indeholder taget\n<shipped>\n\ntrue\n</shipped>\n\nhvilket ikke er tilladt for ikke-medfølgende apps", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "App kan ikke installeres, da versionen i info.xml/version ikke er den samme som versionen rapporteret fra app-storen", +"App directory already exists" => "App-mappe findes allerede", +"Can't create app folder. Please fix permissions. %s" => "Kan ikke oprette app-mappe. Ret tilladelser. %s", "Application is not enabled" => "Programmet er ikke aktiveret", "Authentication error" => "Adgangsfejl", "Token expired. Please reload page." => "Adgang er udløbet. Genindlæs siden.", diff --git a/lib/l10n/de.php b/lib/l10n/de.php index 01fe5ee0583..7a3e2c43e6b 100644 --- a/lib/l10n/de.php +++ b/lib/l10n/de.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Applikation \"%s\" kann nicht installiert werden, da sie mit dieser ownCloud Version nicht kompatibel ist.", +"No app name specified" => "Es wurde kein Applikation-Name angegeben", "Help" => "Hilfe", "Personal" => "Persönlich", "Settings" => "Einstellungen", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Zurück zu \"Dateien\"", "Selected files too large to generate zip file." => "Die gewählten Dateien sind zu groß, um eine ZIP-Datei zu erstellen.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Lade die Dateien in kleineren, separaten, Stücken herunter oder bitte deinen Administrator.", +"No source specified when installing app" => "Für die Installation der Applikation wurde keine Quelle angegeben", +"No href specified when installing app from http" => "Der Link (href) wurde nicht angegeben um die Applikation per http zu installieren", +"No path specified when installing app from local file" => "Bei der Installation der Applikation aus einer lokalen Datei wurde kein Pfad angegeben", +"Archives of type %s are not supported" => "Archive vom Typ %s werden nicht unterstützt", +"Failed to open archive when installing app" => "Das Archiv konnte bei der Installation der Applikation nicht geöffnet werden", +"App does not provide an info.xml file" => "Die Applikation enthält keine info,xml Datei", +"App can't be installed because of not allowed code in the App" => "Die Applikation kann auf Grund von unerlaubten Code nicht installiert werden", +"App can't be installed because it is not compatible with this version of ownCloud" => "Die Anwendung konnte nicht installiert werden, weil Sie nicht mit dieser Version von ownCloud kompatibel ist.", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Die Applikation konnte nicht installiert werden, da diese das <shipped>true</shipped> Tag beinhaltet und dieses, bei nicht mitausgelieferten Applikationen, nicht erlaubt ist ist", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Die Applikation konnte nicht installiert werden, da die Version in der info.xml nicht die gleiche Version wie im App-Store ist", +"App directory already exists" => "Das Applikationsverzeichnis existiert bereits", +"Can't create app folder. Please fix permissions. %s" => "Es kann kein Applikationsordner erstellt werden. Bitte passen sie die Berechtigungen an. %s", "Application is not enabled" => "Die Anwendung ist nicht aktiviert", "Authentication error" => "Fehler bei der Anmeldung", "Token expired. Please reload page." => "Token abgelaufen. Bitte lade die Seite neu.", diff --git a/lib/l10n/de_CH.php b/lib/l10n/de_CH.php index 188ea4e2fc0..33f3446a693 100644 --- a/lib/l10n/de_CH.php +++ b/lib/l10n/de_CH.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Anwendung \"%s\" kann nicht installiert werden, da sie mit dieser Version von ownCloud nicht kompatibel ist.", +"No app name specified" => "Kein App-Name spezifiziert", "Help" => "Hilfe", "Personal" => "Persönlich", "Settings" => "Einstellungen", @@ -13,6 +15,8 @@ $TRANSLATIONS = array( "Back to Files" => "Zurück zu \"Dateien\"", "Selected files too large to generate zip file." => "Die gewählten Dateien sind zu gross, um eine ZIP-Datei zu erstellen.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Laden Sie die Dateien in kleineren, separaten, Stücken herunter oder bitten Sie Ihren Administrator.", +"App can't be installed because of not allowed code in the App" => "Anwendung kann wegen nicht erlaubten Codes nicht installiert werden", +"App directory already exists" => "Anwendungsverzeichnis existiert bereits", "Application is not enabled" => "Die Anwendung ist nicht aktiviert", "Authentication error" => "Authentifizierungs-Fehler", "Token expired. Please reload page." => "Token abgelaufen. Bitte laden Sie die Seite neu.", @@ -40,13 +44,13 @@ $TRANSLATIONS = array( "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Ihr Web-Server ist noch nicht für eine Datei-Synchronisation konfiguriert, weil die WebDAV-Schnittstelle vermutlich defekt ist.", "Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfen Sie die <a href='%s'>Installationsanleitungen</a>.", "seconds ago" => "Gerade eben", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), +"_%n minute ago_::_%n minutes ago_" => array("","Vor %n Minuten"), +"_%n hour ago_::_%n hours ago_" => array("","Vor %n Stunden"), "today" => "Heute", "yesterday" => "Gestern", -"_%n day go_::_%n days ago_" => array("",""), +"_%n day go_::_%n days ago_" => array("","Vor %n Tagen"), "last month" => "Letzten Monat", -"_%n month ago_::_%n months ago_" => array("",""), +"_%n month ago_::_%n months ago_" => array("","Vor %n Monaten"), "last year" => "Letztes Jahr", "years ago" => "Vor Jahren", "Caused by:" => "Verursacht durch:", diff --git a/lib/l10n/de_DE.php b/lib/l10n/de_DE.php index 9fd319b7e1b..0a72f443e4d 100644 --- a/lib/l10n/de_DE.php +++ b/lib/l10n/de_DE.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Applikation \"%s\" kann nicht installiert werden, da sie mit dieser ownCloud Version nicht kompatibel ist.", +"No app name specified" => "Es wurde kein Applikation-Name angegeben", "Help" => "Hilfe", "Personal" => "Persönlich", "Settings" => "Einstellungen", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Zurück zu \"Dateien\"", "Selected files too large to generate zip file." => "Die gewählten Dateien sind zu groß, um eine ZIP-Datei zu erstellen.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Laden Sie die Dateien in kleineren, separaten, Stücken herunter oder bitten Sie Ihren Administrator.", +"No source specified when installing app" => "Für die Installation der Applikation wurde keine Quelle angegeben", +"No href specified when installing app from http" => "Der Link (href) wurde nicht angegeben um die Applikation per http zu installieren", +"No path specified when installing app from local file" => "Bei der Installation der Applikation aus einer lokalen Datei wurde kein Pfad angegeben", +"Archives of type %s are not supported" => "Archive des Typs %s werden nicht unterstützt.", +"Failed to open archive when installing app" => "Das Archiv konnte bei der Installation der Applikation nicht geöffnet werden", +"App does not provide an info.xml file" => "Die Applikation enthält keine info,xml Datei", +"App can't be installed because of not allowed code in the App" => "Die Applikation kann auf Grund von unerlaubten Code nicht installiert werden", +"App can't be installed because it is not compatible with this version of ownCloud" => "Die Anwendung konnte nicht installiert werden, weil Sie nicht mit dieser Version von ownCloud kompatibel ist.", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Die Applikation konnte nicht installiert werden, da diese das <shipped>true</shipped> Tag beinhaltet und dieses, bei nicht mitausgelieferten Applikationen, nicht erlaubt ist ist", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Die Applikation konnte nicht installiert werden, da die Version in der info.xml nicht die gleiche Version wie im App-Store ist", +"App directory already exists" => "Der Ordner für die Anwendung existiert bereits.", +"Can't create app folder. Please fix permissions. %s" => "Der Ordner für die Anwendung konnte nicht angelegt werden. Bitte überprüfen Sie die Ordner- und Dateirechte und passen Sie diese entsprechend an. %s", "Application is not enabled" => "Die Anwendung ist nicht aktiviert", "Authentication error" => "Authentifizierungs-Fehler", "Token expired. Please reload page." => "Token abgelaufen. Bitte laden Sie die Seite neu.", diff --git a/lib/l10n/en_GB.php b/lib/l10n/en_GB.php new file mode 100644 index 00000000000..f799c071c76 --- /dev/null +++ b/lib/l10n/en_GB.php @@ -0,0 +1,69 @@ +<?php +$TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "App \"%s\" can't be installed because it is not compatible with this version of ownCloud.", +"No app name specified" => "No app name specified", +"Help" => "Help", +"Personal" => "Personal", +"Settings" => "Settings", +"Users" => "Users", +"Admin" => "Admin", +"Failed to upgrade \"%s\"." => "Failed to upgrade \"%s\".", +"web services under your control" => "web services under your control", +"cannot open \"%s\"" => "cannot open \"%s\"", +"ZIP download is turned off." => "ZIP download is turned off.", +"Files need to be downloaded one by one." => "Files need to be downloaded one by one.", +"Back to Files" => "Back to Files", +"Selected files too large to generate zip file." => "Selected files too large to generate zip file.", +"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Download the files in smaller chunks, seperately or kindly ask your administrator.", +"No source specified when installing app" => "No source specified when installing app", +"No href specified when installing app from http" => "No href specified when installing app from http", +"No path specified when installing app from local file" => "No path specified when installing app from local file", +"Archives of type %s are not supported" => "Archives of type %s are not supported", +"Failed to open archive when installing app" => "Failed to open archive when installing app", +"App does not provide an info.xml file" => "App does not provide an info.xml file", +"App can't be installed because of not allowed code in the App" => "App can't be installed because of unallowed code in the App", +"App can't be installed because it is not compatible with this version of ownCloud" => "App can't be installed because it is not compatible with this version of ownCloud", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "App can't be installed because the version in info.xml/version is not the same as the version reported from the app store", +"App directory already exists" => "App directory already exists", +"Can't create app folder. Please fix permissions. %s" => "Can't create app folder. Please fix permissions. %s", +"Application is not enabled" => "Application is not enabled", +"Authentication error" => "Authentication error", +"Token expired. Please reload page." => "Token expired. Please reload page.", +"Files" => "Files", +"Text" => "Text", +"Images" => "Images", +"%s enter the database username." => "%s enter the database username.", +"%s enter the database name." => "%s enter the database name.", +"%s you may not use dots in the database name" => "%s you may not use dots in the database name", +"MS SQL username and/or password not valid: %s" => "MS SQL username and/or password not valid: %s", +"You need to enter either an existing account or the administrator." => "You need to enter either an existing account or the administrator.", +"MySQL username and/or password not valid" => "MySQL username and/or password not valid", +"DB Error: \"%s\"" => "DB Error: \"%s\"", +"Offending command was: \"%s\"" => "Offending command was: \"%s\"", +"MySQL user '%s'@'localhost' exists already." => "MySQL user '%s'@'localhost' exists already.", +"Drop this user from MySQL" => "Drop this user from MySQL", +"MySQL user '%s'@'%%' already exists" => "MySQL user '%s'@'%%' already exists", +"Drop this user from MySQL." => "Drop this user from MySQL.", +"Oracle connection could not be established" => "Oracle connection could not be established", +"Oracle username and/or password not valid" => "Oracle username and/or password not valid", +"Offending command was: \"%s\", name: %s, password: %s" => "Offending command was: \"%s\", name: %s, password: %s", +"PostgreSQL username and/or password not valid" => "PostgreSQL username and/or password not valid", +"Set an admin username." => "Set an admin username.", +"Set an admin password." => "Set an admin password.", +"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Your web server is not yet properly setup to allow files synchronisation because the WebDAV interface seems to be broken.", +"Please double check the <a href='%s'>installation guides</a>." => "Please double check the <a href='%s'>installation guides</a>.", +"seconds ago" => "seconds ago", +"_%n minute ago_::_%n minutes ago_" => array("","%n minutes ago"), +"_%n hour ago_::_%n hours ago_" => array("","%n hours ago"), +"today" => "today", +"yesterday" => "yesterday", +"_%n day go_::_%n days ago_" => array("","%n days ago"), +"last month" => "last month", +"_%n month ago_::_%n months ago_" => array("","%n months ago"), +"last year" => "last year", +"years ago" => "years ago", +"Caused by:" => "Caused by:", +"Could not find category \"%s\"" => "Could not find category \"%s\"" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/l10n/es.php b/lib/l10n/es.php index 14bbf6f6a13..7a82f8f6a19 100644 --- a/lib/l10n/es.php +++ b/lib/l10n/es.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "La aplicación \"%s\" no puede ser instalada porque no es compatible con esta versión de ownCloud", +"No app name specified" => "No se ha especificado nombre de la aplicación", "Help" => "Ayuda", "Personal" => "Personal", "Settings" => "Ajustes", @@ -13,6 +15,15 @@ $TRANSLATIONS = array( "Back to Files" => "Volver a Archivos", "Selected files too large to generate zip file." => "Los archivos seleccionados son demasiado grandes para generar el archivo zip.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Descargue los archivos en trozos más pequeños, por separado o solicítelos amablemente su administrador.", +"No source specified when installing app" => "No se ha especificado origen cuando se ha instalado la aplicación", +"No href specified when installing app from http" => "No href especificado cuando se ha instalado la aplicación", +"No path specified when installing app from local file" => "Sin path especificado cuando se ha instalado la aplicación desde el fichero local", +"Archives of type %s are not supported" => "Ficheros de tipo %s no son soportados", +"Failed to open archive when installing app" => "Fallo de apertura de fichero mientras se instala la aplicación", +"App does not provide an info.xml file" => "La aplicación no suministra un fichero info.xml", +"App can't be installed because of not allowed code in the App" => "La aplicación no puede ser instalada por tener código no autorizado en la aplicación", +"App can't be installed because it is not compatible with this version of ownCloud" => "La aplicación no se puede instalar porque no es compatible con esta versión de ownCloud", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "La aplicación no se puede instalar porque contiene la etiqueta\n<shipped>\ntrue\n</shipped>\nque no está permitida para aplicaciones no distribuidas", "Application is not enabled" => "La aplicación no está habilitada", "Authentication error" => "Error de autenticación", "Token expired. Please reload page." => "Token expirado. Por favor, recarga la página.", diff --git a/lib/l10n/et_EE.php b/lib/l10n/et_EE.php index 912ef37a935..8e3aa55c4ed 100644 --- a/lib/l10n/et_EE.php +++ b/lib/l10n/et_EE.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Rakendit \"%s\" ei saa paigaldada, kuna see pole ühilduv selle ownCloud versiooniga.", +"No app name specified" => "Ühegi rakendi nime pole määratletud", "Help" => "Abiinfo", "Personal" => "Isiklik", "Settings" => "Seaded", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Tagasi failide juurde", "Selected files too large to generate zip file." => "Valitud failid on ZIP-faili loomiseks liiga suured.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Laadi failid alla eraldi väiksemate osadena või küsi nõu oma süsteemiadminstraatorilt.", +"No source specified when installing app" => "Ühegi lähteallikat pole rakendi paigalduseks määratletud", +"No href specified when installing app from http" => "Ühtegi aadressi pole määratletud rakendi paigalduseks veebist", +"No path specified when installing app from local file" => "Ühtegi teed pole määratletud paigaldamaks rakendit kohalikust failist", +"Archives of type %s are not supported" => "%s tüüpi arhiivid pole toetatud", +"Failed to open archive when installing app" => "Arhiivi avamine ebaõnnestus rakendi paigalduse käigus", +"App does not provide an info.xml file" => "Rakend ei paku ühtegi info.xml faili", +"App can't be installed because of not allowed code in the App" => "Rakendit ei saa paigaldada, kuna sisaldab lubamatud koodi", +"App can't be installed because it is not compatible with this version of ownCloud" => "Rakendit ei saa paigaldada, kuna see pole ühilduv selle ownCloud versiooniga.", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Rakendit ei saa paigaldada, kuna see sisaldab \n<shipped>\n\ntrue\n</shipped>\nmärgendit, mis pole lubatud mitte veetud (non shipped) rakendites", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Rakendit ei saa paigaldada, kuna selle versioon info.xml/version pole sama, mis on märgitud rakendite laos.", +"App directory already exists" => "Rakendi kataloog on juba olemas", +"Can't create app folder. Please fix permissions. %s" => "Ei saa luua rakendi kataloogi. Palun korrigeeri õigusi. %s", "Application is not enabled" => "Rakendus pole sisse lülitatud", "Authentication error" => "Autentimise viga", "Token expired. Please reload page." => "Kontrollkood aegus. Paelun lae leht uuesti.", @@ -40,13 +54,13 @@ $TRANSLATIONS = array( "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Veebiserveri ei ole veel korralikult seadistatud võimaldamaks failide sünkroniseerimist, kuna WebDAV liides näib olevat mittetoimiv.", "Please double check the <a href='%s'>installation guides</a>." => "Palun tutvu veelkord <a href='%s'>paigalduse juhenditega</a>.", "seconds ago" => "sekundit tagasi", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), +"_%n minute ago_::_%n minutes ago_" => array("","%n minutit tagasi"), +"_%n hour ago_::_%n hours ago_" => array("","%n tundi tagasi"), "today" => "täna", "yesterday" => "eile", -"_%n day go_::_%n days ago_" => array("",""), +"_%n day go_::_%n days ago_" => array("","%n päeva tagasi"), "last month" => "viimasel kuul", -"_%n month ago_::_%n months ago_" => array("",""), +"_%n month ago_::_%n months ago_" => array("","%n kuud tagasi"), "last year" => "viimasel aastal", "years ago" => "aastat tagasi", "Caused by:" => "Põhjustaja:", diff --git a/lib/l10n/eu.php b/lib/l10n/eu.php index 8f967314f4b..413819f4f94 100644 --- a/lib/l10n/eu.php +++ b/lib/l10n/eu.php @@ -40,13 +40,13 @@ $TRANSLATIONS = array( "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Zure web zerbitzaria ez dago oraindik ongi konfiguratuta fitxategien sinkronizazioa egiteko, WebDAV interfazea ongi ez dagoela dirudi.", "Please double check the <a href='%s'>installation guides</a>." => "Mesedez begiratu <a href='%s'>instalazio gidak</a>.", "seconds ago" => "segundu", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), +"_%n minute ago_::_%n minutes ago_" => array("orain dela minutu %n","orain dela %n minutu"), +"_%n hour ago_::_%n hours ago_" => array("orain dela ordu %n","orain dela %n ordu"), "today" => "gaur", "yesterday" => "atzo", -"_%n day go_::_%n days ago_" => array("",""), +"_%n day go_::_%n days ago_" => array("orain dela egun %n","orain dela %n egun"), "last month" => "joan den hilabetean", -"_%n month ago_::_%n months ago_" => array("",""), +"_%n month ago_::_%n months ago_" => array("orain dela hilabete %n","orain dela %n hilabete"), "last year" => "joan den urtean", "years ago" => "urte", "Caused by:" => "Honek eraginda:", diff --git a/lib/l10n/fi_FI.php b/lib/l10n/fi_FI.php index 4552d4627c0..2e69df43ad2 100644 --- a/lib/l10n/fi_FI.php +++ b/lib/l10n/fi_FI.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Sovellusta \"%s\" ei voi asentaa, koska se ei ole yhteensopiva käytössä olevan ownCloud-version kanssa.", "Help" => "Ohje", "Personal" => "Henkilökohtainen", "Settings" => "Asetukset", @@ -10,6 +11,12 @@ $TRANSLATIONS = array( "Files need to be downloaded one by one." => "Tiedostot on ladattava yksittäin.", "Back to Files" => "Takaisin tiedostoihin", "Selected files too large to generate zip file." => "Valitut tiedostot ovat liian suurikokoisia mahtuakseen zip-tiedostoon.", +"No source specified when installing app" => "Lähdettä ei määritelty sovellusta asennettaessa", +"No path specified when installing app from local file" => "Polkua ei määritelty sovellusta asennettaessa paikallisesta tiedostosta", +"Archives of type %s are not supported" => "Tyypin %s arkistot eivät ole tuettuja", +"App does not provide an info.xml file" => "Sovellus ei sisällä info.xml-tiedostoa", +"App directory already exists" => "Sovelluskansio on jo olemassa", +"Can't create app folder. Please fix permissions. %s" => "Sovelluskansion luominen ei onnistu. Korjaa käyttöoikeudet. %s", "Application is not enabled" => "Sovellusta ei ole otettu käyttöön", "Authentication error" => "Tunnistautumisvirhe", "Token expired. Please reload page." => "Valtuutus vanheni. Lataa sivu uudelleen.", diff --git a/lib/l10n/gl.php b/lib/l10n/gl.php index 4d92e89ebba..a8fee3b1bc1 100644 --- a/lib/l10n/gl.php +++ b/lib/l10n/gl.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Non é posíbel instalar o aplicativo «%s» por non seren compatíbel con esta versión do ownCloud.", +"No app name specified" => "Non se especificou o nome do aplicativo", "Help" => "Axuda", "Personal" => "Persoal", "Settings" => "Axustes", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Volver aos ficheiros", "Selected files too large to generate zip file." => "Os ficheiros seleccionados son demasiado grandes como para xerar un ficheiro zip.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Descargue os ficheiros en cachos máis pequenos e por separado, ou pídallos amabelmente ao seu administrador.", +"No source specified when installing app" => "Non foi especificada ningunha orixe ao instalar aplicativos", +"No href specified when installing app from http" => "Non foi especificada ningunha href ao instalar aplicativos", +"No path specified when installing app from local file" => "Non foi especificada ningunha ruta ao instalar aplicativos desde un ficheiro local", +"Archives of type %s are not supported" => "Os arquivos do tipo %s non están admitidos", +"Failed to open archive when installing app" => "Non foi posíbel abrir o arquivo ao instalar aplicativos", +"App does not provide an info.xml file" => "O aplicativo non fornece un ficheiro info.xml", +"App can't be installed because of not allowed code in the App" => "Non é posíbel instalar o aplicativo por mor de conter código non permitido", +"App can't be installed because it is not compatible with this version of ownCloud" => "Non é posíbel instalar o aplicativo por non seren compatíbel con esta versión do ownCloud.", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Non é posíbel instalar o aplicativo por conter a etiqueta\n<shipped>\n\ntrue\n</shipped>\nque non está permitida para os aplicativos non enviados", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Non é posíbel instalar o aplicativo xa que a versión en info.xml/version non é a mesma que a versión informada desde a App Store", +"App directory already exists" => "Xa existe o directorio do aplicativo", +"Can't create app folder. Please fix permissions. %s" => "Non é posíbel crear o cartafol de aplicativos. Corrixa os permisos. %s", "Application is not enabled" => "O aplicativo non está activado", "Authentication error" => "Produciuse un erro de autenticación", "Token expired. Please reload page." => "Testemuña caducada. Recargue a páxina.", diff --git a/lib/l10n/he.php b/lib/l10n/he.php index bab1a6ff424..ced6244ee91 100644 --- a/lib/l10n/he.php +++ b/lib/l10n/he.php @@ -19,13 +19,13 @@ $TRANSLATIONS = array( "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "שרת האינטרנט שלך אינו מוגדר לצורכי סנכרון קבצים עדיין כיוון שמנשק ה־WebDAV כנראה אינו תקין.", "Please double check the <a href='%s'>installation guides</a>." => "נא לעיין שוב ב<a href='%s'>מדריכי ההתקנה</a>.", "seconds ago" => "שניות", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), +"_%n minute ago_::_%n minutes ago_" => array("","לפני %n דקות"), +"_%n hour ago_::_%n hours ago_" => array("","לפני %n שעות"), "today" => "היום", "yesterday" => "אתמול", -"_%n day go_::_%n days ago_" => array("",""), +"_%n day go_::_%n days ago_" => array("","לפני %n ימים"), "last month" => "חודש שעבר", -"_%n month ago_::_%n months ago_" => array("",""), +"_%n month ago_::_%n months ago_" => array("","לפני %n חודשים"), "last year" => "שנה שעברה", "years ago" => "שנים", "Could not find category \"%s\"" => "לא ניתן למצוא את הקטגוריה „%s“" diff --git a/lib/l10n/it.php b/lib/l10n/it.php index e734fbdbb9b..c3a040048ec 100644 --- a/lib/l10n/it.php +++ b/lib/l10n/it.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "L'applicazione \"%s\" non può essere installata poiché non è compatibile con questa versione di ownCloud.", +"No app name specified" => "Il nome dell'applicazione non è specificato", "Help" => "Aiuto", "Personal" => "Personale", "Settings" => "Impostazioni", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Torna ai file", "Selected files too large to generate zip file." => "I file selezionati sono troppo grandi per generare un file zip.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Scarica i file in blocchi più piccoli, separatamente o chiedi al tuo amministratore.", +"No source specified when installing app" => "Nessuna fonte specificata durante l'installazione dell'applicazione", +"No href specified when installing app from http" => "Nessun href specificato durante l'installazione dell'applicazione da http", +"No path specified when installing app from local file" => "Nessun percorso specificato durante l'installazione dell'applicazione da file locale", +"Archives of type %s are not supported" => "Gli archivi di tipo %s non sono supportati", +"Failed to open archive when installing app" => "Apertura archivio non riuscita durante l'installazione dell'applicazione", +"App does not provide an info.xml file" => "L'applicazione non fornisce un file info.xml", +"App can't be installed because of not allowed code in the App" => "L'applicazione non può essere installata a causa di codice non consentito al suo interno", +"App can't be installed because it is not compatible with this version of ownCloud" => "L'applicazione non può essere installata poiché non è compatibile con questa versione di ownCloud", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "L'applicazione non può essere installata poiché contiene il tag <shipped>true<shipped> che non è permesso alle applicazioni non shipped", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "L'applicazione non può essere installata poiché la versione in info.xml/version non è la stessa riportata dall'app store", +"App directory already exists" => "La cartella dell'applicazione esiste già", +"Can't create app folder. Please fix permissions. %s" => "Impossibile creare la cartella dell'applicazione. Correggi i permessi. %s", "Application is not enabled" => "L'applicazione non è abilitata", "Authentication error" => "Errore di autenticazione", "Token expired. Please reload page." => "Token scaduto. Ricarica la pagina.", @@ -40,13 +54,13 @@ $TRANSLATIONS = array( "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Il tuo server web non è configurato correttamente per consentire la sincronizzazione dei file poiché l'interfaccia WebDAV sembra essere danneggiata.", "Please double check the <a href='%s'>installation guides</a>." => "Leggi attentamente le <a href='%s'>guide d'installazione</a>.", "seconds ago" => "secondi fa", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), +"_%n minute ago_::_%n minutes ago_" => array("%n minuto fa","%n minuti fa"), +"_%n hour ago_::_%n hours ago_" => array("%n ora fa","%n ore fa"), "today" => "oggi", "yesterday" => "ieri", -"_%n day go_::_%n days ago_" => array("",""), +"_%n day go_::_%n days ago_" => array("%n giorno fa","%n giorni fa"), "last month" => "mese scorso", -"_%n month ago_::_%n months ago_" => array("",""), +"_%n month ago_::_%n months ago_" => array("%n mese fa","%n mesi fa"), "last year" => "anno scorso", "years ago" => "anni fa", "Caused by:" => "Causato da:", diff --git a/lib/l10n/ja_JP.php b/lib/l10n/ja_JP.php index 902170524b9..e2b67e76187 100644 --- a/lib/l10n/ja_JP.php +++ b/lib/l10n/ja_JP.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => " \"%s\" アプリは、このバージョンのownCloudと互換性がない為、インストールできません。", +"No app name specified" => "アプリ名が未指定", "Help" => "ヘルプ", "Personal" => "個人", "Settings" => "設定", @@ -13,6 +15,17 @@ $TRANSLATIONS = array( "Back to Files" => "ファイルに戻る", "Selected files too large to generate zip file." => "選択したファイルはZIPファイルの生成には大きすぎます。", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "ファイルは、小さいファイルに分割されてダウンロードされます。もしくは、管理者にお尋ねください。", +"No source specified when installing app" => "アプリインストール時のソースが未指定", +"No href specified when installing app from http" => "アプリインストール時のhttpの URL が未指定", +"No path specified when installing app from local file" => "アプリインストール時のローカルファイルのパスが未指定", +"Archives of type %s are not supported" => "\"%s\"タイプのアーカイブ形式は未サポート", +"Failed to open archive when installing app" => "アプリをインストール中にアーカイブファイルを開けませんでした。", +"App does not provide an info.xml file" => "アプリにinfo.xmlファイルが入っていません", +"App can't be installed because of not allowed code in the App" => "アプリで許可されないコードが入っているのが原因でアプリがインストールできません", +"App can't be installed because it is not compatible with this version of ownCloud" => "アプリは、このバージョンのownCloudと互換性がない為、インストールできません。", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "info.xml/versionのバージョンがアプリストアのバージョンと合っていない為、アプリはインストールされません", +"App directory already exists" => "アプリディレクトリは既に存在します", +"Can't create app folder. Please fix permissions. %s" => "アプリフォルダを作成出来ませんでした。%s のパーミッションを修正してください。", "Application is not enabled" => "アプリケーションは無効です", "Authentication error" => "認証エラー", "Token expired. Please reload page." => "トークンが無効になりました。ページを再読込してください。", diff --git a/lib/l10n/ko.php b/lib/l10n/ko.php index 4dab8b816bf..eec5be65abd 100644 --- a/lib/l10n/ko.php +++ b/lib/l10n/ko.php @@ -1,15 +1,31 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "현재 ownCloud 버전과 호환되지 않기 때문에 \"%s\" 앱을 설치할 수 없습니다.", +"No app name specified" => "앱 이름이 지정되지 않았습니다.", "Help" => "도움말", "Personal" => "개인", "Settings" => "설정", "Users" => "사용자", "Admin" => "관리자", +"Failed to upgrade \"%s\"." => "\"%s\" 업그레이드에 실패했습니다.", "web services under your control" => "내가 관리하는 웹 서비스", +"cannot open \"%s\"" => "\"%s\"을(를) 열 수 없습니다.", "ZIP download is turned off." => "ZIP 다운로드가 비활성화되었습니다.", "Files need to be downloaded one by one." => "파일을 개별적으로 다운로드해야 합니다.", "Back to Files" => "파일로 돌아가기", "Selected files too large to generate zip file." => "선택한 파일들은 ZIP 파일을 생성하기에 너무 큽니다.", +"No source specified when installing app" => "앱을 설치할 때 소스가 지정되지 않았습니다.", +"No href specified when installing app from http" => "http에서 앱을 설치할 대 href가 지정되지 않았습니다.", +"No path specified when installing app from local file" => "로컬 파일에서 앱을 설치할 때 경로가 지정되지 않았습니다.", +"Archives of type %s are not supported" => "%s 타입 아카이브는 지원되지 않습니다.", +"Failed to open archive when installing app" => "앱을 설치할 때 아카이브를 열지 못했습니다.", +"App does not provide an info.xml file" => "앱에서 info.xml 파일이 제공되지 않았습니다.", +"App can't be installed because of not allowed code in the App" => "앱에 허용되지 않는 코드가 있어서 앱을 설치할 수 없습니다. ", +"App can't be installed because it is not compatible with this version of ownCloud" => "현재 ownCloud 버전과 호환되지 않기 때문에 앱을 설치할 수 없습니다.", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "출하되지 않은 앱에 허용되지 않는 <shipped>true</shipped> 태그를 포함하고 있기 때문에 앱을 설치할 수 없습니다.", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "info.xml/version에 포함된 버전과 앱 스토어에 보고된 버전이 같지 않아서 앱을 설치할 수 없습니다. ", +"App directory already exists" => "앱 디렉토리가 이미 존재합니다. ", +"Can't create app folder. Please fix permissions. %s" => "앱 폴더를 만들 수 없습니다. 권한을 수정하십시오. %s ", "Application is not enabled" => "앱이 활성화되지 않았습니다", "Authentication error" => "인증 오류", "Token expired. Please reload page." => "토큰이 만료되었습니다. 페이지를 새로 고치십시오.", @@ -19,22 +35,34 @@ $TRANSLATIONS = array( "%s enter the database username." => "데이터베이스 사용자 명을 %s 에 입력해주십시오", "%s enter the database name." => "데이터베이스 명을 %s 에 입력해주십시오", "%s you may not use dots in the database name" => "%s 에 적으신 데이터베이스 이름에는 점을 사용할수 없습니다", +"MS SQL username and/or password not valid: %s" => "MS SQL 사용자 이름이나 암호가 잘못되었습니다: %s", +"You need to enter either an existing account or the administrator." => "기존 계정이나 administrator(관리자)를 입력해야 합니다.", +"MySQL username and/or password not valid" => "MySQL 사용자 이름이나 암호가 잘못되었습니다.", "DB Error: \"%s\"" => "DB 오류: \"%s\"", +"Offending command was: \"%s\"" => "잘못된 명령: \"%s\"", +"MySQL user '%s'@'localhost' exists already." => "MySQL 사용자 '%s'@'localhost'이(가) 이미 존재합니다.", +"Drop this user from MySQL" => "이 사용자를 MySQL에서 뺍니다.", +"MySQL user '%s'@'%%' already exists" => "MySQL 사용자 '%s'@'%%'이(가) 이미 존재합니다. ", +"Drop this user from MySQL." => "이 사용자를 MySQL에서 뺍니다.", +"Oracle connection could not be established" => "Oracle 연결을 수립할 수 없습니다.", +"Oracle username and/or password not valid" => "Oracle 사용자 이름이나 암호가 잘못되었습니다.", +"Offending command was: \"%s\", name: %s, password: %s" => "잘못된 명령: \"%s\", 이름: %s, 암호: %s", "PostgreSQL username and/or password not valid" => "PostgreSQL의 사용자 명 혹은 비밀번호가 잘못되었습니다", "Set an admin username." => "관리자 이름 설정", "Set an admin password." => "관리자 비밀번호 설정", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "WebDAV 인터페이스가 제대로 작동하지 않습니다. 웹 서버에서 파일 동기화를 사용할 수 있도록 설정이 제대로 되지 않은 것 같습니다.", "Please double check the <a href='%s'>installation guides</a>." => "<a href='%s'>설치 가이드</a>를 다시 한 번 확인하십시오.", "seconds ago" => "초 전", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), +"_%n minute ago_::_%n minutes ago_" => array("%n분 전 "), +"_%n hour ago_::_%n hours ago_" => array("%n시간 전 "), "today" => "오늘", "yesterday" => "어제", -"_%n day go_::_%n days ago_" => array(""), +"_%n day go_::_%n days ago_" => array("%n일 전 "), "last month" => "지난 달", -"_%n month ago_::_%n months ago_" => array(""), +"_%n month ago_::_%n months ago_" => array("%n달 전 "), "last year" => "작년", "years ago" => "년 전", +"Caused by:" => "원인: ", "Could not find category \"%s\"" => "분류 \"%s\"을(를) 찾을 수 없습니다." ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/l10n/lt_LT.php b/lib/l10n/lt_LT.php index fb109b86339..242b0a23106 100644 --- a/lib/l10n/lt_LT.php +++ b/lib/l10n/lt_LT.php @@ -17,13 +17,13 @@ $TRANSLATIONS = array( "Text" => "Žinučių", "Images" => "Paveikslėliai", "seconds ago" => "prieš sekundę", -"_%n minute ago_::_%n minutes ago_" => array("","",""), -"_%n hour ago_::_%n hours ago_" => array("","",""), +"_%n minute ago_::_%n minutes ago_" => array("",""," prieš %n minučių"), +"_%n hour ago_::_%n hours ago_" => array("","","prieš %n valandų"), "today" => "šiandien", "yesterday" => "vakar", "_%n day go_::_%n days ago_" => array("","",""), "last month" => "praeitą mėnesį", -"_%n month ago_::_%n months ago_" => array("","",""), +"_%n month ago_::_%n months ago_" => array("","","prieš %n mėnesių"), "last year" => "praeitais metais", "years ago" => "prieš metus" ); diff --git a/lib/l10n/nl.php b/lib/l10n/nl.php index 338c3673c5b..e546c1f3179 100644 --- a/lib/l10n/nl.php +++ b/lib/l10n/nl.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"No app name specified" => "De app naam is niet gespecificeerd.", "Help" => "Help", "Personal" => "Persoonlijk", "Settings" => "Instellingen", diff --git a/lib/l10n/pt_BR.php b/lib/l10n/pt_BR.php index 52329667174..a2379ca4883 100644 --- a/lib/l10n/pt_BR.php +++ b/lib/l10n/pt_BR.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "O aplicativo \"%s\" não pode ser instalado porque não é compatível com esta versão do ownCloud.", +"No app name specified" => "O nome do aplicativo não foi especificado.", "Help" => "Ajuda", "Personal" => "Pessoal", "Settings" => "Ajustes", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Voltar para Arquivos", "Selected files too large to generate zip file." => "Arquivos selecionados são muito grandes para gerar arquivo zip.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Baixe os arquivos em pedaços menores, separadamente ou solicite educadamente ao seu administrador.", +"No source specified when installing app" => "Nenhuma fonte foi especificada enquanto instalava o aplicativo", +"No href specified when installing app from http" => "Nenhuma href foi especificada enquanto instalava o aplicativo de httml", +"No path specified when installing app from local file" => "Nenhum caminho foi especificado enquanto instalava o aplicativo do arquivo local", +"Archives of type %s are not supported" => "Arquivos do tipo %s não são suportados", +"Failed to open archive when installing app" => "Falha para abrir o arquivo enquanto instalava o aplicativo", +"App does not provide an info.xml file" => "O aplicativo não fornece um arquivo info.xml", +"App can't be installed because of not allowed code in the App" => "O aplicativo não pode ser instalado por causa do código não permitido no Aplivativo", +"App can't be installed because it is not compatible with this version of ownCloud" => "O aplicativo não pode ser instalado porque não é compatível com esta versão do ownCloud", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "O aplicativo não pode ser instalado porque ele contém a marca <shipped>verdadeiro</shipped> que não é permitido para aplicações não embarcadas", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "O aplicativo não pode ser instalado porque a versão em info.xml /versão não é a mesma que a versão relatada na App Store", +"App directory already exists" => "Diretório App já existe", +"Can't create app folder. Please fix permissions. %s" => "Não é possível criar pasta app. Corrija as permissões. %s", "Application is not enabled" => "Aplicação não está habilitada", "Authentication error" => "Erro de autenticação", "Token expired. Please reload page." => "Token expirou. Por favor recarregue a página.", diff --git a/lib/l10n/sk_SK.php b/lib/l10n/sk_SK.php index 43a4b4a0bee..13487b039d6 100644 --- a/lib/l10n/sk_SK.php +++ b/lib/l10n/sk_SK.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Aplikácia \"%s\" nemôže byť nainštalovaná kvôli nekompatibilite z danou verziou ownCloudu.", +"No app name specified" => "Nešpecifikované meno aplikácie", "Help" => "Pomoc", "Personal" => "Osobné", "Settings" => "Nastavenia", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Späť na súbory", "Selected files too large to generate zip file." => "Zvolené súbory sú príliš veľké na vygenerovanie zip súboru.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Stiahnite súbory po menších častiach, samostatne, alebo sa obráťte na správcu.", +"No source specified when installing app" => "Nešpecifikovaný zdroj pri inštalácii aplikácie", +"No href specified when installing app from http" => "Nešpecifikovaný atribút \"href\" pri inštalácii aplikácie pomocou protokolu \"http\"", +"No path specified when installing app from local file" => "Nešpecifikovaná cesta pri inštalácii aplikácie z lokálneho súboru", +"Archives of type %s are not supported" => "Typ archívu %s nie je podporovaný", +"Failed to open archive when installing app" => "Zlyhanie pri otváraní archívu počas inštalácie aplikácie", +"App does not provide an info.xml file" => "Aplikácia neposkytuje súbor info.xml", +"App can't be installed because of not allowed code in the App" => "Aplikácia nemôže byť inštalovaná pre nepovolený kód v aplikácii", +"App can't be installed because it is not compatible with this version of ownCloud" => "Aplikácia nemôže byť inštalovaná pre nekompatibilitu z danou verziou ownCloudu", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Aplikácia nemôže byť inštalovaná pretože obsahuje <shipped>pravý</shipped> štítok, ktorý nie je povolený pre zaslané \"shipped\" aplikácie", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Aplikácia nemôže byť inštalovaná pretože verzia v info.xml/version nezodpovedá verzii špecifikovanej v aplikačnom obchode", +"App directory already exists" => "Aplikačný adresár už existuje", +"Can't create app folder. Please fix permissions. %s" => "Nemožno vytvoriť aplikačný priečinok. Prosím upravte povolenia. %s", "Application is not enabled" => "Aplikácia nie je zapnutá", "Authentication error" => "Chyba autentifikácie", "Token expired. Please reload page." => "Token vypršal. Obnovte, prosím, stránku.", @@ -40,13 +54,13 @@ $TRANSLATIONS = array( "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Váš webový server nie je správne nastavený na synchronizáciu, pretože rozhranie WebDAV je poškodené.", "Please double check the <a href='%s'>installation guides</a>." => "Prosím skontrolujte <a href='%s'>inštalačnú príručku</a>.", "seconds ago" => "pred sekundami", -"_%n minute ago_::_%n minutes ago_" => array("","",""), -"_%n hour ago_::_%n hours ago_" => array("","",""), +"_%n minute ago_::_%n minutes ago_" => array("","","pred %n minútami"), +"_%n hour ago_::_%n hours ago_" => array("","","pred %n hodinami"), "today" => "dnes", "yesterday" => "včera", -"_%n day go_::_%n days ago_" => array("","",""), +"_%n day go_::_%n days ago_" => array("","","pred %n dňami"), "last month" => "minulý mesiac", -"_%n month ago_::_%n months ago_" => array("","",""), +"_%n month ago_::_%n months ago_" => array("","","pred %n mesiacmi"), "last year" => "minulý rok", "years ago" => "pred rokmi", "Caused by:" => "Príčina:", diff --git a/lib/l10n/sv.php b/lib/l10n/sv.php index dd54e6ca5d3..e7c3420a85b 100644 --- a/lib/l10n/sv.php +++ b/lib/l10n/sv.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Appen \"%s\" kan inte installeras eftersom att den inte är kompatibel med denna version av ownCloud.", +"No app name specified" => "Inget appnamn angivet", "Help" => "Hjälp", "Personal" => "Personligt", "Settings" => "Inställningar", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Tillbaka till Filer", "Selected files too large to generate zip file." => "Valda filer är för stora för att skapa zip-fil.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Ladda ner filerna i mindre bitar, separat eller fråga din administratör.", +"No source specified when installing app" => "Ingen källa angiven vid installation av app ", +"No href specified when installing app from http" => "Ingen href angiven vid installation av app från http", +"No path specified when installing app from local file" => "Ingen sökväg angiven vid installation av app från lokal fil", +"Archives of type %s are not supported" => "Arkiv av typen %s stöds ej", +"Failed to open archive when installing app" => "Kunde inte öppna arkivet när appen skulle installeras", +"App does not provide an info.xml file" => "Appen har ingen info.xml fil", +"App can't be installed because of not allowed code in the App" => "Appen kan inte installeras eftersom att den innehåller otillåten kod", +"App can't be installed because it is not compatible with this version of ownCloud" => "Appen kan inte installeras eftersom att den inte är kompatibel med denna version av ownCloud", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Appen kan inte installeras eftersom att den innehåller etiketten <shipped>true</shipped> vilket inte är tillåtet för icke inkluderade appar", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Appen kan inte installeras eftersom versionen i info.xml inte är samma som rapporteras från app store", +"App directory already exists" => "Appens mapp finns redan", +"Can't create app folder. Please fix permissions. %s" => "Kan inte skapa appens mapp. Var god åtgärda rättigheterna. %s", "Application is not enabled" => "Applikationen är inte aktiverad", "Authentication error" => "Fel vid autentisering", "Token expired. Please reload page." => "Ogiltig token. Ladda om sidan.", diff --git a/lib/l10n/tr.php b/lib/l10n/tr.php index 498469ea8b1..b63c37c7240 100644 --- a/lib/l10n/tr.php +++ b/lib/l10n/tr.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Owncloud yazılımının bu sürümü ile uyumlu olmadığı için \"%s\" uygulaması kurulamaz.", +"No app name specified" => "Uygulama adı belirtimedli", "Help" => "Yardım", "Personal" => "Kişisel", "Settings" => "Ayarlar", @@ -13,6 +15,18 @@ $TRANSLATIONS = array( "Back to Files" => "Dosyalara dön", "Selected files too large to generate zip file." => "Seçilen dosyalar bir zip dosyası oluşturmak için fazla büyüktür.", "Download the files in smaller chunks, seperately or kindly ask your administrator." => "Dosyaları ayrı ayrı, küçük parçalar halinde indirin ya da yöneticinizden yardım isteyin. ", +"No source specified when installing app" => "Uygulama kurulurken bir kaynak belirtilmedi", +"No href specified when installing app from http" => "Uygulama kuruluyorken http'de href belirtilmedi.", +"No path specified when installing app from local file" => "Uygulama yerel dosyadan kuruluyorken dosya yolu belirtilmedi", +"Archives of type %s are not supported" => "%s arşiv tipi desteklenmiyor", +"Failed to open archive when installing app" => "Uygulama kuruluyorken arşiv dosyası açılamadı", +"App does not provide an info.xml file" => "Uygulama info.xml dosyası sağlamıyor", +"App can't be installed because of not allowed code in the App" => "Uygulamada izin verilmeyeden kodlar olduğu için kurulamıyor.", +"App can't be installed because it is not compatible with this version of ownCloud" => "Owncloud versiyonunuz ile uyumsuz olduğu için uygulama kurulamıyor.", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Uygulama kurulamıyor. Çünkü \"non shipped\" uygulamalar için <shipped>true</shipped> tag içermektedir.", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Uygulama kurulamıyor çünkü info.xml/version ile uygulama marketde belirtilen sürüm aynı değil.", +"App directory already exists" => "App dizini zaten mevcut", +"Can't create app folder. Please fix permissions. %s" => "app dizini oluşturulamıyor. Lütfen izinleri düzeltin. %s", "Application is not enabled" => "Uygulama etkinleştirilmedi", "Authentication error" => "Kimlik doğrulama hatası", "Token expired. Please reload page." => "Jetonun süresi geçti. Lütfen sayfayı yenileyin.", diff --git a/lib/l10n/ug.php b/lib/l10n/ug.php index 731ad904d7e..e2cf38ecc8c 100644 --- a/lib/l10n/ug.php +++ b/lib/l10n/ug.php @@ -8,6 +8,7 @@ $TRANSLATIONS = array( "Files" => "ھۆججەتلەر", "Text" => "قىسقا ئۇچۇر", "Images" => "سۈرەتلەر", +"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "سىزنىڭ تور مۇلازىمېتىرىڭىز ھۆججەت قەدەمداشلاشقا يول قويىدىغان قىلىپ توغرا تەڭشەلمەپتۇ، چۈنكى WebDAV نىڭ ئېغىزى بۇزۇلغاندەك تۇرىدۇ.", "_%n minute ago_::_%n minutes ago_" => array(""), "_%n hour ago_::_%n hours ago_" => array(""), "today" => "بۈگۈن", diff --git a/lib/l10n/zh_CN.GB2312.php b/lib/l10n/zh_CN.GB2312.php deleted file mode 100644 index bc81ff8fe1b..00000000000 --- a/lib/l10n/zh_CN.GB2312.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "帮助", -"Personal" => "私人", -"Settings" => "设置", -"Users" => "用户", -"Admin" => "管理员", -"web services under your control" => "您控制的网络服务", -"ZIP download is turned off." => "ZIP 下载已关闭", -"Files need to be downloaded one by one." => "需要逐个下载文件。", -"Back to Files" => "返回到文件", -"Selected files too large to generate zip file." => "选择的文件太大而不能生成 zip 文件。", -"Application is not enabled" => "应用未启用", -"Authentication error" => "验证错误", -"Token expired. Please reload page." => "会话过期。请刷新页面。", -"Files" => "文件", -"Text" => "文本", -"Images" => "图片", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "因WebDAV接口故障,您的网络服务器好像并未允许文件同步。", -"Please double check the <a href='%s'>installation guides</a>." => "请双击<a href='%s'>安装向导</a>。", -"seconds ago" => "秒前", -"_%n minute ago_::_%n minutes ago_" => array("%n 分钟以前"), -"_%n hour ago_::_%n hours ago_" => array("%n 小时以前"), -"today" => "今天", -"yesterday" => "昨天", -"_%n day go_::_%n days ago_" => array("%n 天以前"), -"last month" => "上个月", -"_%n month ago_::_%n months ago_" => array("%n 个月以前"), -"last year" => "去年", -"years ago" => "年前" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/l10n/zh_CN.php b/lib/l10n/zh_CN.php index 03bd48de74b..2c34356ea10 100644 --- a/lib/l10n/zh_CN.php +++ b/lib/l10n/zh_CN.php @@ -10,6 +10,7 @@ $TRANSLATIONS = array( "Files need to be downloaded one by one." => "需要逐一下载文件", "Back to Files" => "回到文件", "Selected files too large to generate zip file." => "选择的文件太大,无法生成 zip 文件。", +"App does not provide an info.xml file" => "应用未提供 info.xml 文件", "Application is not enabled" => "应用程序未启用", "Authentication error" => "认证出错", "Token expired. Please reload page." => "Token 过期,请刷新页面。", @@ -38,12 +39,12 @@ $TRANSLATIONS = array( "Please double check the <a href='%s'>installation guides</a>." => "请认真检查<a href='%s'>安装指南</a>.", "seconds ago" => "秒前", "_%n minute ago_::_%n minutes ago_" => array("%n 分钟前"), -"_%n hour ago_::_%n hours ago_" => array(""), +"_%n hour ago_::_%n hours ago_" => array("%n 小时前"), "today" => "今天", "yesterday" => "昨天", -"_%n day go_::_%n days ago_" => array(""), +"_%n day go_::_%n days ago_" => array("%n 天前"), "last month" => "上月", -"_%n month ago_::_%n months ago_" => array(""), +"_%n month ago_::_%n months ago_" => array("%n 月前"), "last year" => "去年", "years ago" => "年前", "Could not find category \"%s\"" => "无法找到分类 \"%s\"" diff --git a/lib/l10n/zh_TW.php b/lib/l10n/zh_TW.php index f405eb88ae9..210c766aa59 100644 --- a/lib/l10n/zh_TW.php +++ b/lib/l10n/zh_TW.php @@ -1,15 +1,32 @@ <?php $TRANSLATIONS = array( +"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "無法安裝應用程式 %s 因為它和此版本的 ownCloud 不相容。", +"No app name specified" => "沒有指定應用程式名稱", "Help" => "說明", "Personal" => "個人", "Settings" => "設定", "Users" => "使用者", "Admin" => "管理", +"Failed to upgrade \"%s\"." => "升級失敗:%s", "web services under your control" => "由您控制的網路服務", +"cannot open \"%s\"" => "無法開啓 %s", "ZIP download is turned off." => "ZIP 下載已關閉。", "Files need to be downloaded one by one." => "檔案需要逐一下載。", "Back to Files" => "回到檔案列表", "Selected files too large to generate zip file." => "選擇的檔案太大以致於無法產生壓縮檔。", +"Download the files in smaller chunks, seperately or kindly ask your administrator." => "以小分割下載您的檔案,請詢問您的系統管理員。", +"No source specified when installing app" => "沒有指定應用程式安裝來源", +"No href specified when installing app from http" => "從 http 安裝應用程式,找不到 href 屬性", +"No path specified when installing app from local file" => "從本地檔案安裝應用程式時沒有指定路徑", +"Archives of type %s are not supported" => "不支援 %s 格式的壓縮檔", +"Failed to open archive when installing app" => "安裝應用程式時無法開啓壓縮檔", +"App does not provide an info.xml file" => "應用程式沒有提供 info.xml 檔案", +"App can't be installed because of not allowed code in the App" => "無法安裝應用程式因為在當中找到危險的代碼", +"App can't be installed because it is not compatible with this version of ownCloud" => "無法安裝應用程式因為它和此版本的 ownCloud 不相容。", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "無法安裝應用程式,因為它包含了 <shipped>true</shipped> 標籤,在未發行的應用程式當中這是不允許的", +"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "無法安裝應用程式,因為它在 info.xml/version 宣告的版本與 app store 當中記載的版本不同", +"App directory already exists" => "應用程式目錄已經存在", +"Can't create app folder. Please fix permissions. %s" => "無法建立應用程式目錄,請檢查權限:%s", "Application is not enabled" => "應用程式未啟用", "Authentication error" => "認證錯誤", "Token expired. Please reload page." => "Token 過期,請重新整理頁面。", @@ -37,15 +54,16 @@ $TRANSLATIONS = array( "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "您的網頁伺服器尚未被正確設定來進行檔案同步,因為您的 WebDAV 界面似乎無法使用。", "Please double check the <a href='%s'>installation guides</a>." => "請參考<a href='%s'>安裝指南</a>。", "seconds ago" => "幾秒前", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), +"_%n minute ago_::_%n minutes ago_" => array("%n 分鐘前"), +"_%n hour ago_::_%n hours ago_" => array("%n 小時前"), "today" => "今天", "yesterday" => "昨天", -"_%n day go_::_%n days ago_" => array(""), +"_%n day go_::_%n days ago_" => array("%n 天前"), "last month" => "上個月", -"_%n month ago_::_%n months ago_" => array(""), +"_%n month ago_::_%n months ago_" => array("%n 個月前"), "last year" => "去年", "years ago" => "幾年前", +"Caused by:" => "原因:", "Could not find category \"%s\"" => "找不到分類:\"%s\"" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/log/rotate.php b/lib/log/rotate.php new file mode 100644 index 00000000000..bf23ad588b3 --- /dev/null +++ b/lib/log/rotate.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Log; + +/** + * This rotates the current logfile to a new name, this way the total log usage + * will stay limited and older entries are available for a while longer. + * For more professional log management set the 'logfile' config to a different + * location and manage that with your own tools. + */ +class Rotate extends \OC\BackgroundJob\Job { + private $max_log_size; + public function run($logFile) { + $this->max_log_size = \OC_Config::getValue('log_rotate_size', false); + if ($this->max_log_size) { + $filesize = @filesize($logFile); + if ($filesize >= $this->max_log_size) { + $this->rotate($logFile); + } + } + } + + protected function rotate($logfile) { + $rotatedLogfile = $logfile.'.1'; + rename($logfile, $rotatedLogfile); + $msg = 'Log file "'.$logfile.'" was over '.$this->max_log_size.' bytes, moved to "'.$rotatedLogfile.'"'; + \OC_Log::write('OC\Log\Rotate', $msg, \OC_Log::WARN); + } +} diff --git a/lib/ocs/cloud.php b/lib/ocs/cloud.php index 132d923d960..2dd99319057 100644 --- a/lib/ocs/cloud.php +++ b/lib/ocs/cloud.php @@ -35,13 +35,49 @@ class OC_OCS_Cloud { 'edition' => OC_Util::getEditionString(), ); - $result['capabilities'] = array( - 'core' => array( - 'pollinterval' => OC_Config::getValue('pollinterval', 60), - ), - ); + $result['capabilities'] = array( + 'core' => array( + 'pollinterval' => OC_Config::getValue('pollinterval', 60), + ), + ); + return new OC_OCS_Result($result); } + + /** + * gets user info + * + * exposes the quota of an user: + * <data> + * <quota> + * <free>1234</free> + * <used>4321</used> + * <total>5555</total> + * <ralative>0.78</ralative> + * </quota> + * </data> + * + * @param $parameters object should contain parameter 'userid' which identifies + * the user from whom the information will be returned + */ + public static function getUser($parameters) { + // Check if they are viewing information on themselves + if($parameters['userid'] === OC_User::getUser()) { + // Self lookup + $quota = array(); + $storage = OC_Helper::getStorageInfo(); + $quota = array( + 'free' => $storage['free'], + 'used' => $storage['used'], + 'total' => $storage['total'], + 'relative' => $storage['relative'], + ); + return new OC_OCS_Result(array('quota' => $quota)); + } else { + // No permission to view this user data + return new OC_OCS_Result(null, 997); + } + } public static function getUserPublickey($parameters) { diff --git a/lib/preview.php b/lib/preview.php new file mode 100755 index 00000000000..b40ba191fba --- /dev/null +++ b/lib/preview.php @@ -0,0 +1,627 @@ +<?php +/** + * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org + * 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. + * + * Thumbnails: + * structure of filename: + * /data/user/thumbnails/pathhash/x-y.png + * + */ +namespace OC; + +require_once 'preview/image.php'; +require_once 'preview/movies.php'; +require_once 'preview/mp3.php'; +require_once 'preview/pdf.php'; +require_once 'preview/svg.php'; +require_once 'preview/txt.php'; +require_once 'preview/unknown.php'; +require_once 'preview/office.php'; + +class Preview { + //the thumbnail folder + const THUMBNAILS_FOLDER = 'thumbnails'; + + //config + private $maxScaleFactor; + private $configMaxX; + private $configMaxY; + + //fileview object + private $fileView = null; + private $userView = null; + + //vars + private $file; + private $maxX; + private $maxY; + private $scalingup; + + //preview images object + private $preview; + + //preview providers + static private $providers = array(); + static private $registeredProviders = array(); + + /** + * @brief check if thumbnail or bigger version of thumbnail of file is cached + * @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 + * @param bool $scalingUp Disable/Enable upscaling of previews + * @return mixed (bool / string) + * false if thumbnail does not exist + * path to thumbnail if thumbnail exists + */ + public function __construct($user='', $root='/', $file='', $maxX=1, $maxY=1, $scalingUp=true) { + //set config + $this->configMaxX = \OC_Config::getValue('preview_max_x', null); + $this->configMaxY = \OC_Config::getValue('preview_max_y', null); + $this->maxScaleFactor = \OC_Config::getValue('preview_max_scale_factor', 2); + + //save parameters + $this->setFile($file); + $this->setMaxX($maxX); + $this->setMaxY($maxY); + $this->setScalingUp($scalingUp); + + //init fileviews + if($user === ''){ + $user = \OC_User::getUser(); + } + $this->fileView = new \OC\Files\View('/' . $user . '/' . $root); + $this->userView = new \OC\Files\View('/' . $user); + + $this->preview = null; + + //check if there are preview backends + if(empty(self::$providers)) { + self::initProviders(); + } + + if(empty(self::$providers)) { + \OC_Log::write('core', 'No preview providers exist', \OC_Log::ERROR); + throw new \Exception('No preview providers'); + } + } + + /** + * @brief returns the path of the file you want a thumbnail from + * @return string + */ + public function getFile() { + return $this->file; + } + + /** + * @brief returns the max width of the preview + * @return integer + */ + public function getMaxX() { + return $this->maxX; + } + + /** + * @brief returns the max height of the preview + * @return integer + */ + public function getMaxY() { + return $this->maxY; + } + + /** + * @brief returns whether or not scalingup is enabled + * @return bool + */ + public function getScalingUp() { + return $this->scalingup; + } + + /** + * @brief returns the name of the thumbnailfolder + * @return string + */ + public function getThumbnailsFolder() { + return self::THUMBNAILS_FOLDER; + } + + /** + * @brief returns the max scale factor + * @return integer + */ + public function getMaxScaleFactor() { + return $this->maxScaleFactor; + } + + /** + * @brief returns the max width set in ownCloud's config + * @return integer + */ + public function getConfigMaxX() { + return $this->configMaxX; + } + + /** + * @brief returns the max height set in ownCloud's config + * @return integer + */ + public function getConfigMaxY() { + return $this->configMaxY; + } + + /** + * @brief set the path of the file you want a thumbnail from + * @param string $file + * @return $this + */ + public function setFile($file) { + $this->file = $file; + return $this; + } + + /** + * @brief set the the max width of the preview + * @param int $maxX + * @return $this + */ + public function setMaxX($maxX=1) { + if($maxX <= 0) { + throw new \Exception('Cannot set width of 0 or smaller!'); + } + $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 + * @param int $maxY + * @return $this + */ + public function setMaxY($maxY=1) { + if($maxY <= 0) { + throw new \Exception('Cannot set height of 0 or smaller!'); + } + $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 + * @param bool $scalingUp + * @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 bool + */ + public function isFileValid() { + $file = $this->getFile(); + if($file === '') { + \OC_Log::write('core', 'No filename passed', \OC_Log::DEBUG); + return false; + } + + if(!$this->fileView->file_exists($file)) { + \OC_Log::write('core', 'File:"' . $file . '" not found', \OC_Log::DEBUG); + return false; + } + + return true; + } + + /** + * @brief deletes previews of a file with specific x and y + * @return bool + */ + public function deletePreview() { + $file = $this->getFile(); + + $fileInfo = $this->fileView->getFileInfo($file); + $fileId = $fileInfo['fileid']; + + $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/' . $this->getMaxX() . '-' . $this->getMaxY() . '.png'; + $this->userView->unlink($previewPath); + return !$this->userView->file_exists($previewPath); + } + + /** + * @brief deletes all previews of a file + * @return bool + */ + public function deleteAllPreviews() { + $file = $this->getFile(); + + $fileInfo = $this->fileView->getFileInfo($file); + $fileId = $fileInfo['fileid']; + + $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; + $this->userView->deleteAll($previewPath); + $this->userView->rmdir($previewPath); + return !$this->userView->is_dir($previewPath); + } + + /** + * @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 + */ + private function isCached() { + $file = $this->getFile(); + $maxX = $this->getMaxX(); + $maxY = $this->getMaxY(); + $scalingUp = $this->getScalingUp(); + $maxScaleFactor = $this->getMaxScaleFactor(); + + $fileInfo = $this->fileView->getFileInfo($file); + $fileId = $fileInfo['fileid']; + + if(is_null($fileId)) { + return false; + } + + $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; + if(!$this->userView->is_dir($previewPath)) { + return false; + } + + //does a preview with the wanted height and width already exist? + if($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) { + return $previewPath . $maxX . '-' . $maxY . '.png'; + } + + $wantedAspectRatio = (float) ($maxX / $maxY); + + //array for usable cached thumbnails + $possibleThumbnails = array(); + + $allThumbnails = $this->userView->getDirectoryContent($previewPath); + foreach($allThumbnails as $thumbnail) { + $name = rtrim($thumbnail['name'], '.png'); + $size = explode('-', $name); + $x = (int) $size[0]; + $y = (int) $size[1]; + + $aspectRatio = (float) ($x / $y); + if($aspectRatio !== $wantedAspectRatio) { + continue; + } + + if($x < $maxX || $y < $maxY) { + if($scalingUp) { + $scalefactor = $maxX / $x; + if($scalefactor > $maxScaleFactor) { + continue; + } + }else{ + continue; + } + } + $possibleThumbnails[$x] = $thumbnail['path']; + } + + if(count($possibleThumbnails) === 0) { + return false; + } + + if(count($possibleThumbnails) === 1) { + return current($possibleThumbnails); + } + + ksort($possibleThumbnails); + + if(key(reset($possibleThumbnails)) > $maxX) { + return current(reset($possibleThumbnails)); + } + + if(key(end($possibleThumbnails)) < $maxX) { + return current(end($possibleThumbnails)); + } + + foreach($possibleThumbnails as $width => $path) { + if($width < $maxX) { + continue; + }else{ + return $path; + } + } + } + + /** + * @brief return a preview of a file + * @return \OC_Image + */ + public function getPreview() { + 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(); + + $fileInfo = $this->fileView->getFileInfo($file); + $fileId = $fileInfo['fileid']; + + $cached = $this->isCached(); + + if($cached) { + $image = new \OC_Image($this->userView->file_get_contents($cached, 'r')); + $this->preview = $image->valid() ? $image : null; + $this->resizeAndCrop(); + } + + if(is_null($this->preview)) { + $mimetype = $this->fileView->getMimeType($file); + $preview = null; + + foreach(self::$providers as $supportedMimetype => $provider) { + if(!preg_match($supportedMimetype, $mimetype)) { + continue; + } + + \OC_Log::write('core', 'Generating preview for "' . $file . '" with "' . get_class($provider) . '"', \OC_Log::DEBUG); + + $preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView); + + if(!($preview instanceof \OC_Image)) { + continue; + } + + $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() . '/'); + } + + if($this->userView->is_dir($previewPath) === false) { + $this->userView->mkdir($previewPath); + } + + $this->userView->file_put_contents($cachePath, $preview->data()); + + break; + } + } + + if(is_null($this->preview)) { + $this->preview = new \OC_Image(); + } + + return $this->preview; + } + + /** + * @brief show preview + * @return void + */ + public function showPreview() { + \OCP\Response::enableCaching(3600 * 24); // 24 hours + if(is_null($this->preview)) { + $this->getPreview(); + } + $this->preview->show(); + return; + } + + /** + * @brief show preview + * @return void + */ + public function show() { + $this->showPreview(); + return; + } + + /** + * @brief resize, crop and fix orientation + * @return void + */ + private function resizeAndCrop() { + $image = $this->preview; + $x = $this->getMaxX(); + $y = $this->getMaxY(); + $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); + return; + } + + $image->fixOrientation(); + + $realx = (int) $image->width(); + $realy = (int) $image->height(); + + if($x === $realx && $y === $realy) { + $this->preview = $image; + return; + } + + $factorX = $x / $realx; + $factorY = $y / $realy; + + if($factorX >= $factorY) { + $factor = $factorX; + }else{ + $factor = $factorY; + } + + if($scalingUp === false) { + if($factor > 1) { + $factor = 1; + } + } + + if(!is_null($maxscalefactor)) { + if($factor > $maxscalefactor) { + \OC_Log::write('core', 'scalefactor reduced from ' . $factor . ' to ' . $maxscalefactor, \OC_Log::DEBUG); + $factor = $maxscalefactor; + } + } + + $newXsize = (int) ($realx * $factor); + $newYsize = (int) ($realy * $factor); + + $image->preciseResize($newXsize, $newYsize); + + if($newXsize === $x && $newYsize === $y) { + $this->preview = $image; + return; + } + + if($newXsize >= $x && $newYsize >= $y) { + $cropX = floor(abs($x - $newXsize) * 0.5); + //don't crop previews on the Y axis, this sucks if it's a document. + //$cropY = floor(abs($y - $newYsize) * 0.5); + $cropY = 0; + + $image->crop($cropX, $cropY, $x, $y); + + $this->preview = $image; + return; + } + + if($newXsize < $x || $newYsize < $y) { + if($newXsize > $x) { + $cropX = floor(($newXsize - $x) * 0.5); + $image->crop($cropX, 0, $x, $newYsize); + } + + if($newYsize > $y) { + $cropY = floor(($newYsize - $y) * 0.5); + $image->crop(0, $cropY, $newXsize, $y); + } + + $newXsize = (int) $image->width(); + $newYsize = (int) $image->height(); + + //create transparent background layer + $backgroundlayer = imagecreatetruecolor($x, $y); + $white = imagecolorallocate($backgroundlayer, 255, 255, 255); + imagefill($backgroundlayer, 0, 0, $white); + + $image = $image->resource(); + + $mergeX = floor(abs($x - $newXsize) * 0.5); + $mergeY = floor(abs($y - $newYsize) * 0.5); + + imagecopy($backgroundlayer, $image, $mergeX, $mergeY, 0, 0, $newXsize, $newYsize); + + //$black = imagecolorallocate(0,0,0); + //imagecolortransparent($transparentlayer, $black); + + $image = new \OC_Image($backgroundlayer); + + $this->preview = $image; + return; + } + } + + /** + * @brief register a new preview provider to be used + * @param string $provider class name of a Preview_Provider + * @param array $options + * @return void + */ + public static function registerProvider($class, $options=array()) { + self::$registeredProviders[]=array('class'=>$class, 'options'=>$options); + } + + /** + * @brief create instances of all the registered preview providers + * @return void + */ + private static function initProviders() { + if(!\OC_Config::getValue('enable_previews', true)) { + $provider = new Preview\Unknown(array()); + self::$providers = array($provider->getMimeType() => $provider); + return; + } + + if(count(self::$providers)>0) { + return; + } + + foreach(self::$registeredProviders as $provider) { + $class=$provider['class']; + $options=$provider['options']; + + $object = new $class($options); + + self::$providers[$object->getMimeType()] = $object; + } + + $keys = array_map('strlen', array_keys(self::$providers)); + array_multisort($keys, SORT_DESC, self::$providers); + } + + public static function post_write($args) { + self::post_delete($args); + } + + public static function post_delete($args) { + $path = $args['path']; + if(substr($path, 0, 1) === '/') { + $path = substr($path, 1); + } + $preview = new Preview(\OC_User::getUser(), 'files/', $path); + $preview->deleteAllPreviews(); + } + + 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(); + } + + //remove last element because it has the mimetype * + $providers = array_slice(self::$providers, 0, -1); + foreach($providers as $supportedMimetype => $provider) { + if(preg_match($supportedMimetype, $mimetype)) { + return true; + } + } + return false; + } +}
\ No newline at end of file diff --git a/lib/preview/image.php b/lib/preview/image.php new file mode 100644 index 00000000000..9aec967282d --- /dev/null +++ b/lib/preview/image.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org + * 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 Image extends Provider { + + public function getMimeType() { + return '/image\/.*/'; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + //get fileinfo + $fileInfo = $fileview->getFileInfo($path); + if(!$fileInfo) { + return false; + } + + //check if file is encrypted + if($fileInfo['encrypted'] === true) { + $image = new \OC_Image(stream_get_contents($fileview->fopen($path, 'r'))); + }else{ + $image = new \OC_Image(); + $image->loadFromFile($fileview->getLocalFile($path)); + } + + return $image->valid() ? $image : false; + } +} + +\OC\Preview::registerProvider('OC\Preview\Image');
\ No newline at end of file diff --git a/lib/preview/movies.php b/lib/preview/movies.php new file mode 100644 index 00000000000..e2a1b8edddc --- /dev/null +++ b/lib/preview/movies.php @@ -0,0 +1,47 @@ +<?php +/** + * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org + * 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; + +$isShellExecEnabled = !in_array('shell_exec', explode(', ', ini_get('disable_functions'))); +$whichFFMPEG = shell_exec('which ffmpeg'); +$isFFMPEGAvailable = !empty($whichFFMPEG); + +if($isShellExecEnabled && $isFFMPEGAvailable) { + + class Movie extends Provider { + + public function getMimeType() { + return '/video\/.*/'; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + $absPath = \OC_Helper::tmpFile(); + $tmpPath = \OC_Helper::tmpFile(); + + $handle = $fileview->fopen($path, 'rb'); + + $firstmb = stream_get_contents($handle, 1048576); //1024 * 1024 = 1048576 + file_put_contents($absPath, $firstmb); + + //$cmd = 'ffmpeg -y -i ' . escapeshellarg($absPath) . ' -f mjpeg -vframes 1 -ss 1 -s ' . escapeshellarg($maxX) . 'x' . escapeshellarg($maxY) . ' ' . $tmpPath; + $cmd = 'ffmpeg -an -y -i ' . escapeshellarg($absPath) . ' -f mjpeg -vframes 1 -ss 1 ' . escapeshellarg($tmpPath); + + shell_exec($cmd); + + $image = new \OC_Image($tmpPath); + + unlink($absPath); + unlink($tmpPath); + + return $image->valid() ? $image : false; + } + } + + \OC\Preview::registerProvider('OC\Preview\Movie'); +}
\ No newline at end of file diff --git a/lib/preview/mp3.php b/lib/preview/mp3.php new file mode 100644 index 00000000000..1eed566315c --- /dev/null +++ b/lib/preview/mp3.php @@ -0,0 +1,48 @@ +<?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 MP3 extends Provider { + + public function getMimeType() { + return '/audio\/mpeg/'; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + require_once('getid3/getid3.php'); + + $getID3 = new \getID3(); + + $tmpPath = $fileview->toTmpFile($path); + + $tags = $getID3->analyze($tmpPath); + \getid3_lib::CopyTagsToComments($tags); + if(isset($tags['id3v2']['APIC'][0]['data'])) { + $picture = @$tags['id3v2']['APIC'][0]['data']; + unlink($tmpPath); + $image = new \OC_Image($picture); + return $image->valid() ? $image : $this->getNoCoverThumbnail(); + } + + return $this->getNoCoverThumbnail(); + } + + private function getNoCoverThumbnail() { + $icon = \OC::$SERVERROOT . '/core/img/filetypes/audio.png'; + + if(!file_exists($icon)) { + return false; + } + + $image = new \OC_Image($icon); + return $image->valid() ? $image : false; + } + +} + +\OC\Preview::registerProvider('OC\Preview\MP3');
\ No newline at end of file diff --git a/lib/preview/office-cl.php b/lib/preview/office-cl.php new file mode 100644 index 00000000000..112909d6523 --- /dev/null +++ b/lib/preview/office-cl.php @@ -0,0 +1,134 @@ +<?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; + +//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 = ' --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); + $export = 'export HOME=/' . $tmpDir; + + shell_exec($export . "\n" . $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($pdf); + + unlink($absPath); + unlink($absPath . '.pdf'); + + return $image->valid() ? $image : false; + } + + private function initCmd() { + $cmd = ''; + + if(is_string(\OC_Config::getValue('preview_libreoffice_path', null))) { + $cmd = \OC_Config::getValue('preview_libreoffice_path', null); + } + + $whichLibreOffice = shell_exec('which libreoffice'); + if($cmd === '' && !empty($whichLibreOffice)) { + $cmd = 'libreoffice'; + } + + $whichOpenOffice = shell_exec('which openoffice'); + if($cmd === '' && !empty($whichOpenOffice)) { + $cmd = 'openoffice'; + } + + if($cmd === '') { + $cmd = null; + } + + $this->cmd = $cmd; + } +} + +//.doc, .dot +class MSOfficeDoc extends Office { + + public function getMimeType() { + return '/application\/msword/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\MSOfficeDoc'); + +//.docm, .dotm, .xls(m), .xlt(m), .xla(m), .ppt(m), .pot(m), .pps(m), .ppa(m) +class MSOffice2003 extends Office { + + public function getMimeType() { + return '/application\/vnd.ms-.*/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\MSOffice2003'); + +//.docx, .dotx, .xlsx, .xltx, .pptx, .potx, .ppsx +class MSOffice2007 extends Office { + + public function getMimeType() { + return '/application\/vnd.openxmlformats-officedocument.*/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\MSOffice2007'); + +//.odt, .ott, .oth, .odm, .odg, .otg, .odp, .otp, .ods, .ots, .odc, .odf, .odb, .odi, .oxt +class OpenDocument extends Office { + + public function getMimeType() { + return '/application\/vnd.oasis.opendocument.*/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\OpenDocument'); + +//.sxw, .stw, .sxc, .stc, .sxd, .std, .sxi, .sti, .sxg, .sxm +class StarOffice extends Office { + + public function getMimeType() { + return '/application\/vnd.sun.xml.*/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\StarOffice');
\ No newline at end of file diff --git a/lib/preview/office-fallback.php b/lib/preview/office-fallback.php new file mode 100644 index 00000000000..e69ab0ab8cb --- /dev/null +++ b/lib/preview/office-fallback.php @@ -0,0 +1,142 @@ +<?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; + +/* //There is no (good) php-only solution for converting 2003 word documents to pdfs / pngs ... +class DOC extends Provider { + + public function getMimeType() { + return '/application\/msword/'; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + require_once(''); + } + +} + +\OC\Preview::registerProvider('OC\Preview\DOC'); +*/ + +class DOCX extends Provider { + + public function getMimeType() { + return '/application\/vnd.openxmlformats-officedocument.wordprocessingml.document/'; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + require_once('phpdocx/classes/TransformDoc.inc'); + + $tmpDoc = $fileview->toTmpFile($path); + + $transformdoc = new \TransformDoc(); + $transformdoc->setStrFile($tmpDoc); + $transformdoc->generatePDF($tmpDoc); + + $pdf = new \imagick($tmpDoc . '[0]'); + $pdf->setImageFormat('jpg'); + + unlink($tmpDoc); + + $image = new \OC_Image($pdf); + + return $image->valid() ? $image : false; + } + +} + +\OC\Preview::registerProvider('OC\Preview\DOCX'); + +class MSOfficeExcel extends Provider { + + public function getMimeType() { + return null; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + require_once('PHPExcel/Classes/PHPExcel.php'); + require_once('PHPExcel/Classes/PHPExcel/IOFactory.php'); + + $absPath = $fileview->toTmpFile($path); + $tmpPath = \OC_Helper::tmpFile(); + + $rendererName = \PHPExcel_Settings::PDF_RENDERER_DOMPDF; + $rendererLibraryPath = \OC::$THIRDPARTYROOT . '/3rdparty/dompdf'; + + \PHPExcel_Settings::setPdfRenderer($rendererName, $rendererLibraryPath); + + $phpexcel = new \PHPExcel($absPath); + $excel = \PHPExcel_IOFactory::createWriter($phpexcel, 'PDF'); + $excel->save($tmpPath); + + $pdf = new \imagick($tmpPath . '[0]'); + $pdf->setImageFormat('jpg'); + + unlink($absPath); + unlink($tmpPath); + + $image = new \OC_Image($pdf); + + return $image->valid() ? $image : false; + } + +} + +class XLS extends MSOfficeExcel { + + public function getMimeType() { + return '/application\/vnd.ms-excel/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\XLS'); + +class XLSX extends MSOfficeExcel { + + public function getMimeType() { + return '/application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\XLSX'); + +/* //There is no (good) php-only solution for converting powerpoint documents to pdfs / pngs ... +class MSOfficePowerPoint extends Provider { + + public function getMimeType() { + return null; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + return false; + } + +} + +class PPT extends MSOfficePowerPoint { + + public function getMimeType() { + return '/application\/vnd.ms-powerpoint/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\PPT'); + +class PPTX extends MSOfficePowerPoint { + + public function getMimeType() { + return '/application\/vnd.openxmlformats-officedocument.presentationml.presentation/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\PPTX'); +*/
\ No newline at end of file diff --git a/lib/preview/office.php b/lib/preview/office.php new file mode 100644 index 00000000000..5287bbd6ac1 --- /dev/null +++ b/lib/preview/office.php @@ -0,0 +1,22 @@ +<?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. + */ +//both, libreoffice backend and php fallback, need imagick +if (extension_loaded('imagick')) { + $isShellExecEnabled = !in_array('shell_exec', explode(', ', ini_get('disable_functions'))); + $whichLibreOffice = shell_exec('which libreoffice'); + $isLibreOfficeAvailable = !empty($whichLibreOffice); + $whichOpenOffice = shell_exec('which libreoffice'); + $isOpenOfficeAvailable = !empty($whichOpenOffice); + //let's see if there is libreoffice or openoffice on this machine + if($isShellExecEnabled && ($isLibreOfficeAvailable || $isOpenOfficeAvailable || is_string(\OC_Config::getValue('preview_libreoffice_path', null)))) { + require_once('office-cl.php'); + }else{ + //in case there isn't, use our fallback + require_once('office-fallback.php'); + } +}
\ No newline at end of file diff --git a/lib/preview/pdf.php b/lib/preview/pdf.php new file mode 100644 index 00000000000..cc974b68818 --- /dev/null +++ b/lib/preview/pdf.php @@ -0,0 +1,40 @@ +<?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; + +if (extension_loaded('imagick')) { + + class PDF extends Provider { + + public function getMimeType() { + return '/application\/pdf/'; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + $tmpPath = $fileview->toTmpFile($path); + + //create imagick object from pdf + try{ + $pdf = new \imagick($tmpPath . '[0]'); + $pdf->setImageFormat('jpg'); + } catch (\Exception $e) { + \OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR); + return false; + } + + unlink($tmpPath); + + //new image object + $image = new \OC_Image($pdf); + //check if image object is valid + return $image->valid() ? $image : false; + } + } + + \OC\Preview::registerProvider('OC\Preview\PDF'); +} diff --git a/lib/preview/provider.php b/lib/preview/provider.php new file mode 100644 index 00000000000..e4a730bafc8 --- /dev/null +++ b/lib/preview/provider.php @@ -0,0 +1,19 @@ +<?php +namespace OC\Preview; + +abstract class Provider { + private $options; + + public function __construct($options) { + $this->options=$options; + } + + abstract public function getMimeType(); + + /** + * search for $query + * @param string $query + * @return + */ + abstract public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview); +} diff --git a/lib/preview/svg.php b/lib/preview/svg.php new file mode 100644 index 00000000000..b49e51720fa --- /dev/null +++ b/lib/preview/svg.php @@ -0,0 +1,46 @@ +<?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; + +if (extension_loaded('imagick')) { + + class SVG extends Provider { + + public function getMimeType() { + return '/image\/svg\+xml/'; + } + + public function getThumbnail($path,$maxX,$maxY,$scalingup,$fileview) { + try{ + $svg = new \Imagick(); + $svg->setBackgroundColor(new \ImagickPixel('transparent')); + + $content = stream_get_contents($fileview->fopen($path, 'r')); + if(substr($content, 0, 5) !== '<?xml') { + $content = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . $content; + } + + $svg->readImageBlob($content); + $svg->setImageFormat('png32'); + } catch (\Exception $e) { + \OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR); + return false; + } + + + //new image object + $image = new \OC_Image(); + $image->loadFromData($svg); + //check if image object is valid + return $image->valid() ? $image : false; + } + } + + \OC\Preview::registerProvider('OC\Preview\SVG'); + +}
\ No newline at end of file diff --git a/lib/preview/txt.php b/lib/preview/txt.php new file mode 100644 index 00000000000..a487330691e --- /dev/null +++ b/lib/preview/txt.php @@ -0,0 +1,73 @@ +<?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 TXT extends Provider { + + public function getMimeType() { + return '/text\/.*/'; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + $content = $fileview->fopen($path, 'r'); + $content = stream_get_contents($content); + + //don't create previews of empty text files + if(trim($content) === '') { + return false; + } + + $lines = preg_split("/\r\n|\n|\r/", $content); + + $fontSize = 5; //5px + $lineSize = ceil($fontSize * 1.25); + + $image = imagecreate($maxX, $maxY); + imagecolorallocate($image, 255, 255, 255); + $textColor = imagecolorallocate($image, 0, 0, 0); + + foreach($lines as $index => $line) { + $index = $index + 1; + + $x = (int) 1; + $y = (int) ($index * $lineSize) - $fontSize; + + imagestring($image, 1, $x, $y, $line, $textColor); + + if(($index * $lineSize) >= $maxY) { + break; + } + } + + $image = new \OC_Image($image); + + return $image->valid() ? $image : false; + } +} + +\OC\Preview::registerProvider('OC\Preview\TXT'); + +class PHP extends TXT { + + public function getMimeType() { + return '/application\/x-php/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\PHP'); + +class JavaScript extends TXT { + + public function getMimeType() { + return '/application\/javascript/'; + } + +} + +\OC\Preview::registerProvider('OC\Preview\JavaScript');
\ No newline at end of file diff --git a/lib/preview/unknown.php b/lib/preview/unknown.php new file mode 100644 index 00000000000..9e6cd68d401 --- /dev/null +++ b/lib/preview/unknown.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org + * 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 Unknown extends Provider { + + public function getMimeType() { + return '/.*/'; + } + + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + $mimetype = $fileview->getMimeType($path); + + $path = \OC_Helper::mimetypeIcon($mimetype); + $path = \OC::$SERVERROOT . substr($path, strlen(\OC::$WEBROOT)); + + return new \OC_Image($path); + } +} + +\OC\Preview::registerProvider('OC\Preview\Unknown');
\ No newline at end of file diff --git a/lib/public/preview.php b/lib/public/preview.php new file mode 100644 index 00000000000..7588347eccb --- /dev/null +++ b/lib/public/preview.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org + * 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 OCP; + +/** + * This class provides functions to render and show thumbnails and previews of files + */ +class Preview { + + /** + * @brief return a preview of a file + * @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 + * @param $scaleup Scale smaller images up to the thumbnail size or not. Might look ugly + * @return image + */ + public static function show($file,$maxX=100,$maxY=75,$scaleup=false) { + return(\OC\Preview::show($file,$maxX,$maxY,$scaleup)); + } + + + + public static function isMimeSupported($mimetype='*') { + return \OC\Preview::isMimeSupported($mimetype); + } + +} diff --git a/lib/public/share.php b/lib/public/share.php index 7714837769d..fe996dbe266 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -209,7 +209,7 @@ class Share { } } } - + // let's get the parent for the next round $meta = $cache->get((int)$source); if($meta !== false) { @@ -840,7 +840,11 @@ class Share { // Get filesystem root to add it to the file target and remove from the // file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { - $root = \OC\Files\Filesystem::getRoot(); + if(!is_null($uidOwner)) { + $root = \OC\Files\Filesystem::getRoot(); + } else { + $root = ''; + } $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; @@ -1303,11 +1307,11 @@ class Share { 'run' => &$run, 'error' => &$error )); - + if ($run === false) { throw new \Exception($error); } - + if (isset($fileSource)) { if ($parentFolder) { if ($parentFolder === true) { @@ -1398,11 +1402,11 @@ class Share { 'run' => &$run, 'error' => &$error )); - + if ($run === false) { throw new \Exception($error); } - + if (isset($fileSource)) { if ($parentFolder) { if ($parentFolder === true) { diff --git a/lib/public/template.php b/lib/public/template.php index ab1089c332d..3b1a4ed4906 100644 --- a/lib/public/template.php +++ b/lib/public/template.php @@ -54,6 +54,25 @@ function mimetype_icon( $mimetype ) { return(\mimetype_icon( $mimetype )); } +/** + * @brief make preview_icon available as a simple function + * Returns the path to the preview of the image. + * @param $path path of file + * @returns link to the preview + */ +function preview_icon( $path ) { + return(\preview_icon( $path )); +} + +/** + * @brief make publicpreview_icon available as a simple function + * Returns the path to the preview of the image. + * @param $path path of file + * @returns link to the preview + */ +function publicPreview_icon ( $path, $token ) { + return(\publicPreview_icon( $path, $token )); +} /** * @brief make OC_Helper::humanFileSize available as a simple function diff --git a/lib/template/functions.php b/lib/template/functions.php index 717e197c1cb..501f8081bff 100644 --- a/lib/template/functions.php +++ b/lib/template/functions.php @@ -59,6 +59,22 @@ function mimetype_icon( $mimetype ) { } /** + * @brief make preview_icon available as a simple function + * Returns the path to the preview of the image. + * @param $path path of file + * @returns link to the preview + * + * For further information have a look at OC_Helper::previewIcon + */ +function preview_icon( $path ) { + return OC_Helper::previewIcon( $path ); +} + +function publicPreview_icon ( $path, $token ) { + return OC_Helper::publicPreviewIcon( $path, $token ); +} + +/** * @brief make OC_Helper::humanFileSize available as a simple function * @param int $bytes size in bytes * @return string size as string diff --git a/lib/util.php b/lib/util.php index f343e783206..0777643a952 100755 --- a/lib/util.php +++ b/lib/util.php @@ -108,7 +108,7 @@ class OC_Util { public static function getVersion() { // hint: We only can count up. Reset minor/patchlevel when // updating major/minor version number. - return array(5, 80, 05); + return array(5, 80, 07); } /** |