diff options
author | Robin Appelman <icewind@owncloud.com> | 2013-08-18 11:34:56 +0200 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2013-08-18 11:34:56 +0200 |
commit | d8c71ba734d95e954d4ff3af50a44b94f9f016ff (patch) | |
tree | c89cd494a618e621f9c8941bac52bfed15dbad4c /lib/files | |
parent | 5c9aedac1b9e858e450ac0b1f009d8042206060b (diff) | |
parent | 12f4494de02457d51004ca6a82c1b2160189819f (diff) | |
download | nextcloud-server-d8c71ba734d95e954d4ff3af50a44b94f9f016ff.tar.gz nextcloud-server-d8c71ba734d95e954d4ff3af50a44b94f9f016ff.zip |
merge master in storage-wrapper-quota
Diffstat (limited to 'lib/files')
-rw-r--r-- | lib/files/cache/cache.php | 40 | ||||
-rw-r--r-- | lib/files/cache/scanner.php | 17 | ||||
-rw-r--r-- | lib/files/type/detection.php | 121 | ||||
-rw-r--r-- | lib/files/type/templatemanager.php | 46 | ||||
-rw-r--r-- | lib/files/utils/scanner.php | 13 |
5 files changed, 203 insertions, 34 deletions
diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 3818fdbd840..39e36684b7b 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -200,7 +200,7 @@ class Cache { $data['path'] = $file; $data['parent'] = $this->getParentId($file); - $data['name'] = basename($file); + $data['name'] = \OC_Util::basename($file); $data['encrypted'] = isset($data['encrypted']) ? ((int)$data['encrypted']) : 0; list($queryParts, $params) = $this->buildParts($data); @@ -485,28 +485,28 @@ class Cache { * @return int */ public function calculateFolderSize($path) { - $id = $this->getId($path); - if ($id === -1) { - return 0; - } - $sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'; - $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); $totalSize = 0; - $hasChilds = 0; - while ($row = $result->fetchRow()) { - $hasChilds = true; - $size = (int)$row['size']; - if ($size === -1) { - $totalSize = -1; - break; - } else { - $totalSize += $size; + $entry = $this->get($path); + if ($entry && $entry['mimetype'] === 'httpd/unix-directory') { + $id = $entry['fileid']; + $sql = 'SELECT SUM(`size`), MIN(`size`) FROM `*PREFIX*filecache` '. + 'WHERE `parent` = ? AND `storage` = ?'; + $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); + if ($row = $result->fetchRow()) { + list($sum, $min) = array_values($row); + $sum = (int)$sum; + $min = (int)$min; + if ($min === -1) { + $totalSize = $min; + } else { + $totalSize = $sum; + } + if ($entry['size'] !== $totalSize) { + $this->update($id, array('size' => $totalSize)); + } + } } - - if ($hasChilds) { - $this->update($id, array('size' => $totalSize)); - } return $totalSize; } diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index bcd6032fcac..597eabecf54 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -75,9 +75,10 @@ class Scanner extends BasicEmitter { * * @param string $file * @param int $reuseExisting + * @param bool $parentExistsInCache * @return array with metadata of the scanned file */ - public function scanFile($file, $reuseExisting = 0) { + public function scanFile($file, $reuseExisting = 0, $parentExistsInCache = false) { if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file) ) { @@ -85,7 +86,7 @@ class Scanner extends BasicEmitter { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); if ($data) { - if ($file) { + if ($file and !$parentExistsInCache) { $parent = dirname($file); if ($parent === '.' or $parent === '/') { $parent = ''; @@ -97,7 +98,7 @@ class Scanner extends BasicEmitter { $newData = $data; if ($reuseExisting and $cacheData = $this->cache->get($file)) { // only reuse data if the file hasn't explicitly changed - if ($data['mtime'] === $cacheData['mtime']) { + if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) { if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) { $data['size'] = $cacheData['size']; } @@ -108,9 +109,9 @@ class Scanner extends BasicEmitter { // Only update metadata that has changed $newData = array_diff($data, $cacheData); } - } - if (!empty($newData)) { - $this->cache->put($file, $newData); + if (!empty($newData)) { + $this->cache->put($file, $newData); + } } return $data; } @@ -162,7 +163,7 @@ class Scanner extends BasicEmitter { $child = ($path) ? $path . '/' . $file : $file; if (!Filesystem::isIgnoredDir($file)) { $newChildren[] = $file; - $data = $this->scanFile($child, $reuse); + $data = $this->scanFile($child, $reuse, true); if ($data) { if ($data['size'] === -1) { if ($recursive === self::SCAN_RECURSIVE) { @@ -183,7 +184,7 @@ class Scanner extends BasicEmitter { } \OC_DB::commit(); foreach ($childQueue as $child) { - $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE); + $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse); if ($childSize === -1) { $size = -1; } else { diff --git a/lib/files/type/detection.php b/lib/files/type/detection.php new file mode 100644 index 00000000000..242a81cb5a4 --- /dev/null +++ b/lib/files/type/detection.php @@ -0,0 +1,121 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Type; + +/** + * Class Detection + * + * Mimetype detection + * + * @package OC\Files\Type + */ +class Detection { + protected $mimetypes = array(); + + /** + * add an extension -> mimetype mapping + * + * @param string $extension + * @param string $mimetype + */ + public function registerType($extension, $mimetype) { + $this->mimetypes[$extension] = $mimetype; + } + + /** + * add an array of extension -> mimetype mappings + * + * @param array $types + */ + public function registerTypeArray($types) { + $this->mimetypes = array_merge($this->mimetypes, $types); + } + + /** + * detect mimetype only based on filename, content of file is not used + * + * @param string $path + * @return string + */ + public function detectPath($path) { + if (strpos($path, '.')) { + //try to guess the type by the file extension + $extension = strtolower(strrchr(basename($path), ".")); + $extension = substr($extension, 1); //remove leading . + return (isset($this->mimetypes[$extension])) ? $this->mimetypes[$extension] : 'application/octet-stream'; + } else { + return 'application/octet-stream'; + } + } + + /** + * detect mimetype based on both filename and content + * + * @param string $path + * @return string + */ + public function detect($path) { + $isWrapped = (strpos($path, '://') !== false) and (substr($path, 0, 7) === 'file://'); + + if (@is_dir($path)) { + // directories are easy + return "httpd/unix-directory"; + } + + $mimeType = $this->detectPath($path); + + if ($mimeType === 'application/octet-stream' and function_exists('finfo_open') + and function_exists('finfo_file') and $finfo = finfo_open(FILEINFO_MIME) + ) { + $info = @strtolower(finfo_file($finfo, $path)); + if ($info) { + $mimeType = substr($info, 0, strpos($info, ';')); + } + finfo_close($finfo); + } + if (!$isWrapped and $mimeType === 'application/octet-stream' && function_exists("mime_content_type")) { + // use mime magic extension if available + $mimeType = mime_content_type($path); + } + if (!$isWrapped and $mimeType === 'application/octet-stream' && \OC_Helper::canExecute("file")) { + // it looks like we have a 'file' command, + // lets see if it does have mime support + $path = escapeshellarg($path); + $fp = popen("file -b --mime-type $path 2>/dev/null", "r"); + $reply = fgets($fp); + pclose($fp); + + //trim the newline + $mimeType = trim($reply); + + } + return $mimeType; + } + + /** + * detect mimetype based on the content of a string + * + * @param string $data + * @return string + */ + public function detectString($data) { + if (function_exists('finfo_open') and function_exists('finfo_file')) { + $finfo = finfo_open(FILEINFO_MIME); + return finfo_buffer($finfo, $data); + } else { + $tmpFile = \OC_Helper::tmpFile(); + $fh = fopen($tmpFile, 'wb'); + fwrite($fh, $data, 8024); + fclose($fh); + $mime = $this->detect($tmpFile); + unset($tmpFile); + return $mime; + } + } +} diff --git a/lib/files/type/templatemanager.php b/lib/files/type/templatemanager.php new file mode 100644 index 00000000000..cd1536d2732 --- /dev/null +++ b/lib/files/type/templatemanager.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Type; + +class TemplateManager { + protected $templates = array(); + + public function registerTemplate($mimetype, $path) { + $this->templates[$mimetype] = $path; + } + + /** + * get the path of the template for a mimetype + * + * @param string $mimetype + * @return string | null + */ + public function getTemplatePath($mimetype) { + if (isset($this->templates[$mimetype])) { + return $this->templates[$mimetype]; + } else { + return null; + } + } + + /** + * get the template content for a mimetype + * + * @param string $mimetype + * @return string + */ + public function getTemplate($mimetype) { + $path = $this->getTemplatePath($mimetype); + if ($path) { + return file_get_contents($path); + } else { + return ''; + } + } +} diff --git a/lib/files/utils/scanner.php b/lib/files/utils/scanner.php index 800bb649934..f0dc41ffad3 100644 --- a/lib/files/utils/scanner.php +++ b/lib/files/utils/scanner.php @@ -8,8 +8,8 @@ namespace OC\Files\Utils; -use OC\Hooks\BasicEmitter; use OC\Files\Filesystem; +use OC\Hooks\PublicEmitter; /** * Class Scanner @@ -20,7 +20,7 @@ use OC\Files\Filesystem; * * @package OC\Files\Utils */ -class Scanner extends BasicEmitter { +class Scanner extends PublicEmitter { /** * @var string $user */ @@ -60,11 +60,12 @@ class Scanner extends BasicEmitter { */ protected function attachListener($mount) { $scanner = $mount->getStorage()->getScanner(); - $scanner->listen('\OC\Files\Cache\Scanner', 'scanFile', function ($path) use ($mount) { - $this->emit('\OC\Files\Utils\Scanner', 'scanFile', array($mount->getMountPoint() . $path)); + $emitter = $this; + $scanner->listen('\OC\Files\Cache\Scanner', 'scanFile', function ($path) use ($mount, $emitter) { + $emitter->emit('\OC\Files\Utils\Scanner', 'scanFile', array($mount->getMountPoint() . $path)); }); - $scanner->listen('\OC\Files\Cache\Scanner', 'scanFolder', function ($path) use ($mount) { - $this->emit('\OC\Files\Utils\Scanner', 'scanFolder', array($mount->getMountPoint() . $path)); + $scanner->listen('\OC\Files\Cache\Scanner', 'scanFolder', function ($path) use ($mount, $emitter) { + $emitter->emit('\OC\Files\Utils\Scanner', 'scanFolder', array($mount->getMountPoint() . $path)); }); } |