diff options
author | Robin Appelman <icewind@owncloud.com> | 2012-11-21 22:37:14 +0100 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2012-11-21 22:37:14 +0100 |
commit | 97380f3485fe40120b361f2f0bc9d12d060d6311 (patch) | |
tree | 1e03f5375f2d9f97770fee8b6aafaf627c998b01 /lib | |
parent | 40fae0acbf2e84782c273a82eb10a2ed9fdf8162 (diff) | |
parent | 495a8da354eb5aee4bda65138b51da7fab74cef2 (diff) | |
download | nextcloud-server-97380f3485fe40120b361f2f0bc9d12d060d6311.tar.gz nextcloud-server-97380f3485fe40120b361f2f0bc9d12d060d6311.zip |
merge master into filesystem
Diffstat (limited to 'lib')
-rw-r--r-- | lib/helper.php | 16 | ||||
-rw-r--r-- | lib/image.php | 309 | ||||
-rw-r--r-- | lib/l10n/gl.php | 25 | ||||
-rw-r--r-- | lib/l10n/sl.php | 7 | ||||
-rw-r--r-- | lib/l10n/vi.php | 6 | ||||
-rw-r--r-- | lib/l10n/zh_CN.php | 6 | ||||
-rw-r--r-- | lib/public/contacts.php | 103 | ||||
-rwxr-xr-x | lib/util.php | 2 |
8 files changed, 436 insertions, 38 deletions
diff --git a/lib/helper.php b/lib/helper.php index 2b63778024d..536b70b074a 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -743,4 +743,20 @@ class OC_Helper { return false; } + + /** + * Shortens str to maxlen by replacing characters in the middle with '...', eg. + * ellipsis('a very long string with lots of useless info to make a better example', 14) becomes 'a very ...example' + * @param string $str the string + * @param string $maxlen the maximum length of the result + * @return string with at most maxlen characters + */ + public static function ellipsis($str, $maxlen) { + if (strlen($str) > $maxlen) { + $characters = floor($maxlen / 2); + return substr($str, 0, $characters) . '...' . substr($str, -1 * $characters); + } + return $str; + } + } diff --git a/lib/image.php b/lib/image.php index eb08a6281f0..b66c19c2868 100644 --- a/lib/image.php +++ b/lib/image.php @@ -20,32 +20,13 @@ * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ - -//From user comments at http://dk2.php.net/manual/en/function.exif-imagetype.php -if ( ! function_exists( 'exif_imagetype' ) ) { - function exif_imagetype ( $filename ) { - if ( ( $info = getimagesize( $filename ) ) !== false ) { - return $info[2]; - } - return false; - } -} - -function ellipsis($str, $maxlen) { - if (strlen($str) > $maxlen) { - $characters = floor($maxlen / 2); - return substr($str, 0, $characters) . '...' . substr($str, -1 * $characters); - } - return $str; -} - /** * Class for basic image manipulation - * */ 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; /** @@ -214,9 +195,11 @@ class OC_Image { $retval = imagexbm($this->resource, $filepath); break; case IMAGETYPE_WBMP: - case IMAGETYPE_BMP: $retval = imagewbmp($this->resource, $filepath); break; + case IMAGETYPE_BMP: + $retval = imagebmp($this->resource, $filepath, $this->bit_depth); + break; default: $retval = imagepng($this->resource, $filepath); } @@ -402,7 +385,7 @@ class OC_Image { public function loadFromFile($imagepath=false) { if(!is_file($imagepath) || !file_exists($imagepath) || !is_readable($imagepath)) { // Debug output disabled because this method is tried before loadFromBase64? - OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: '.ellipsis($imagepath, 50), OC_Log::DEBUG); + OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: '.$imagepath, OC_Log::DEBUG); return false; } $itype = exif_imagetype($imagepath); @@ -436,13 +419,15 @@ class OC_Image { } break; case IMAGETYPE_WBMP: - case IMAGETYPE_BMP: if (imagetypes() & IMG_WBMP) { $this->resource = imagecreatefromwbmp($imagepath); } else { - OC_Log::write('core', 'OC_Image->loadFromFile, (W)BMP images not supported: '.$imagepath, OC_Log::DEBUG); + OC_Log::write('core', 'OC_Image->loadFromFile, WBMP images not supported: '.$imagepath, OC_Log::DEBUG); } break; + case IMAGETYPE_BMP: + $this->resource = $this->imagecreatefrombmp($imagepath); + break; /* case IMAGETYPE_TIFF_II: // (intel byte order) break; @@ -522,6 +507,147 @@ class OC_Image { } /** + * Create a new image from file or URL + * @link http://www.programmierer-forum.de/function-imagecreatefrombmp-laeuft-mit-allen-bitraten-t143137.htm + * @version 1.00 + * @param string $filename <p> + * Path to the BMP 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); + 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); + return false; + } + // read image header + $meta += unpack('Vheadersize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vcolors/Vimportant', fread($fh, 40)); + // read additional 16bit header + if ($meta['bits'] == 16) { + $meta += unpack('VrMask/VgMask/VbMask', fread($fh, 12)); + } + // set bytes and padding + $meta['bytes'] = $meta['bits'] / 8; + $this->bit_depth = $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; + } + // obtain imagesize + if ($meta['imagesize'] < 1) { + $meta['imagesize'] = $meta['filesize'] - $meta['offset']; + // in rare cases filesize is equal to offset so we need to read physical size + if ($meta['imagesize'] < 1) { + $meta['imagesize'] = @filesize($filename) - $meta['offset']; + if ($meta['imagesize'] < 1) { + trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $filename . '!', E_USER_WARNING); + return false; + } + } + } + // calculate colors + $meta['colors'] = !$meta['colors'] ? pow(2, $meta['bits']) : $meta['colors']; + // read color palette + $palette = array(); + if ($meta['bits'] < 16) { + $palette = unpack('l' . $meta['colors'], fread($fh, $meta['colors'] * 4)); + // in rare cases the color value is signed + if ($palette[1] < 0) { + foreach ($palette as $i => $color) { + $palette[$i] = $color + 16777216; + } + } + } + // create gd image + $im = imagecreatetruecolor($meta['width'], $meta['height']); + $data = fread($fh, $meta['imagesize']); + $p = 0; + $vide = chr(0); + $y = $meta['height'] - 1; + $error = 'imagecreatefrombmp: ' . $filename . ' has not enough data!'; + // loop through the image data beginning with the lower left corner + while ($y >= 0) { + $x = 0; + while ($x < $meta['width']) { + switch ($meta['bits']) { + case 32: + case 24: + if (!($part = substr($data, $p, 3))) { + trigger_error($error, E_USER_WARNING); + return $im; + } + $color = unpack('V', $part . $vide); + break; + case 16: + if (!($part = substr($data, $p, 2))) { + trigger_error($error, E_USER_WARNING); + return $im; + } + $color = unpack('v', $part); + $color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3); + break; + case 8: + $color = unpack('n', $vide . substr($data, $p, 1)); + $color[1] = $palette[ $color[1] + 1 ]; + break; + case 4: + $color = unpack('n', $vide . substr($data, floor($p), 1)); + $color[1] = ($p * 2) % 2 == 0 ? $color[1] >> 4 : $color[1] & 0x0F; + $color[1] = $palette[ $color[1] + 1 ]; + break; + case 1: + $color = unpack('n', $vide . substr($data, floor($p), 1)); + switch (($p * 8) % 8) { + case 0: + $color[1] = $color[1] >> 7; + break; + case 1: + $color[1] = ($color[1] & 0x40) >> 6; + break; + case 2: + $color[1] = ($color[1] & 0x20) >> 5; + break; + case 3: + $color[1] = ($color[1] & 0x10) >> 4; + break; + case 4: + $color[1] = ($color[1] & 0x8) >> 3; + break; + case 5: + $color[1] = ($color[1] & 0x4) >> 2; + break; + case 6: + $color[1] = ($color[1] & 0x2) >> 1; + break; + case 7: + $color[1] = ($color[1] & 0x1); + break; + } + $color[1] = $palette[ $color[1] + 1 ]; + break; + default: + trigger_error('imagecreatefrombmp: ' . $filename . ' has ' . $meta['bits'] . ' bits and this is not supported!', E_USER_WARNING); + return false; + } + imagesetpixel($im, $x, $y, $color[1]); + $x++; + $p += $meta['bytes']; + } + $y--; + $p += $meta['decal']; + } + fclose($fh); + return $im; + } + + /** * @brief Resizes the image preserving ratio. * @param $maxsize The maximum size of either the width or height. * @returns bool @@ -685,3 +811,138 @@ class OC_Image { $this->destroy(); } } +if ( ! function_exists( 'imagebmp') ) { + /** + * Output a BMP image to either the browser or a file + * @link http://www.ugia.cn/wp-data/imagebmp.php + * @author legend <legendsky@hotmail.com> + * @link http://www.programmierer-forum.de/imagebmp-gute-funktion-gefunden-t143716.htm + * @author mgutt <marc@gutt.it> + * @version 1.00 + * @param resource $image + * @param string $filename [optional] <p>The path to save the file to.</p> + * @param int $bit [optional] <p>Bit depth, (default is 24).</p> + * @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) { + if (!in_array($bit, array(1, 4, 8, 16, 24, 32))) { + $bit = 24; + } + else if ($bit == 32) { + $bit = 24; + } + $bits = pow(2, $bit); + imagetruecolortopalette($im, true, $bits); + $width = imagesx($im); + $height = imagesy($im); + $colors_num = imagecolorstotal($im); + $rgb_quad = ''; + if ($bit <= 8) { + for ($i = 0; $i < $colors_num; $i++) { + $colors = imagecolorsforindex($im, $i); + $rgb_quad .= chr($colors['blue']) . chr($colors['green']) . chr($colors['red']) . "\0"; + } + $bmp_data = ''; + if ($compression == 0 || $bit < 8) { + $compression = 0; + $extra = ''; + $padding = 4 - ceil($width / (8 / $bit)) % 4; + if ($padding % 4 != 0) { + $extra = str_repeat("\0", $padding); + } + for ($j = $height - 1; $j >= 0; $j --) { + $i = 0; + while ($i < $width) { + $bin = 0; + $limit = $width - $i < 8 / $bit ? (8 / $bit - $width + $i) * $bit : 0; + for ($k = 8 - $bit; $k >= $limit; $k -= $bit) { + $index = imagecolorat($im, $i, $j); + $bin |= $index << $k; + $i++; + } + $bmp_data .= chr($bin); + } + $bmp_data .= $extra; + } + } + // RLE8 + else if ($compression == 1 && $bit == 8) { + for ($j = $height - 1; $j >= 0; $j--) { + $last_index = "\0"; + $same_num = 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); + } + $last_index = $index; + $same_num = 1; + } + else { + $same_num++; + } + } + $bmp_data .= "\0\0"; + } + $bmp_data .= "\0\1"; + } + $size_quad = strlen($rgb_quad); + $size_data = strlen($bmp_data); + } + else { + $extra = ''; + $padding = 4 - ($width * ($bit / 8)) % 4; + if ($padding % 4 != 0) { + $extra = str_repeat("\0", $padding); + } + $bmp_data = ''; + for ($j = $height - 1; $j >= 0; $j--) { + for ($i = 0; $i < $width; $i++) { + $index = imagecolorat($im, $i, $j); + $colors = imagecolorsforindex($im, $index); + if ($bit == 16) { + $bin = 0 << $bit; + $bin |= ($colors['red'] >> 3) << 10; + $bin |= ($colors['green'] >> 3) << 5; + $bin |= $colors['blue'] >> 3; + $bmp_data .= pack("v", $bin); + } + else { + $bmp_data .= pack("c*", $colors['blue'], $colors['green'], $colors['red']); + } + } + $bmp_data .= $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); + fclose($fp); + return true; + } + echo $file_header . $info_header. $rgb_quad . $bmp_data; + return true; + } +} + +if ( ! function_exists( 'exif_imagetype' ) ) { + /** + * Workaround if exif_imagetype does not exist + * @link http://www.php.net/manual/en/function.exif-imagetype.php#80383 + * @param string $filename + * @return string|boolean + */ + function exif_imagetype ( $filename ) { + if ( ( $info = getimagesize( $filename ) ) !== false ) { + return $info[2]; + } + return false; + } +} diff --git a/lib/l10n/gl.php b/lib/l10n/gl.php index de399de2cf8..fd59cff02fa 100644 --- a/lib/l10n/gl.php +++ b/lib/l10n/gl.php @@ -1,29 +1,34 @@ <?php $TRANSLATIONS = array( "Help" => "Axuda", "Personal" => "Personal", -"Settings" => "Preferencias", +"Settings" => "Configuracións", "Users" => "Usuarios", -"Apps" => "Apps", +"Apps" => "Aplicativos", "Admin" => "Administración", -"ZIP download is turned off." => "Descargas ZIP está deshabilitadas", -"Files need to be downloaded one by one." => "Os ficheiros necesitan ser descargados de un en un", -"Back to Files" => "Voltar a ficheiros", -"Selected files too large to generate zip file." => "Os ficheiros seleccionados son demasiado grandes para xerar un ficheiro ZIP", -"Application is not enabled" => "O aplicativo non está habilitado", +"ZIP download is turned off." => "As descargas ZIP están desactivadas", +"Files need to be downloaded one by one." => "Os ficheiros necesitan ser descargados de un en un.", +"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.", +"Application is not enabled" => "O aplicativo non está activado", "Authentication error" => "Erro na autenticación", -"Token expired. Please reload page." => "Testemuño caducado. Por favor recargue a páxina.", +"Token expired. Please reload page." => "Token caducado. Recarga a páxina.", "Files" => "Ficheiros", "Text" => "Texto", +"Images" => "Imaxes", "seconds ago" => "hai segundos", "1 minute ago" => "hai 1 minuto", "%d minutes ago" => "hai %d minutos", +"1 hour ago" => "1 hora antes", +"%d hours ago" => "%d horas antes", "today" => "hoxe", "yesterday" => "onte", "%d days ago" => "hai %d días", "last month" => "último mes", +"%d months ago" => "%d meses antes", "last year" => "último ano", "years ago" => "anos atrás", -"%s is available. Get <a href=\"%s\">more information</a>" => "%s está dispoñible. Obteña <a href=\"%s\">máis información</a>", +"%s is available. Get <a href=\"%s\">more information</a>" => "%s está dispoñible. Obtén <a href=\"%s\">máis información</a>", "up to date" => "ao día", -"updates check is disabled" => "comprobación de actualizacións está deshabilitada" +"updates check is disabled" => "a comprobación de actualizacións está desactivada", +"Could not find category \"%s\"" => "Non se puido atopar a categoría «%s»" ); diff --git a/lib/l10n/sl.php b/lib/l10n/sl.php index 5787d2b7f30..391d932c4ee 100644 --- a/lib/l10n/sl.php +++ b/lib/l10n/sl.php @@ -14,16 +14,21 @@ "Token expired. Please reload page." => "Žeton je potekel. Spletišče je traba znova naložiti.", "Files" => "Datoteke", "Text" => "Besedilo", +"Images" => "Slike", "seconds ago" => "pred nekaj sekundami", "1 minute ago" => "pred minuto", "%d minutes ago" => "pred %d minutami", +"1 hour ago" => "Pred 1 uro", +"%d hours ago" => "Pred %d urami", "today" => "danes", "yesterday" => "včeraj", "%d days ago" => "pred %d dnevi", "last month" => "prejšnji mesec", +"%d months ago" => "Pred %d meseci", "last year" => "lani", "years ago" => "pred nekaj leti", "%s is available. Get <a href=\"%s\">more information</a>" => "%s je na voljo. <a href=\"%s\">Več podrobnosti.</a>", "up to date" => "posodobljeno", -"updates check is disabled" => "preverjanje za posodobitve je onemogočeno" +"updates check is disabled" => "preverjanje za posodobitve je onemogočeno", +"Could not find category \"%s\"" => "Kategorije \"%s\" ni bilo mogoče najti." ); diff --git a/lib/l10n/vi.php b/lib/l10n/vi.php index 4efb4760580..8b7242ae611 100644 --- a/lib/l10n/vi.php +++ b/lib/l10n/vi.php @@ -18,13 +18,17 @@ "seconds ago" => "1 giây trước", "1 minute ago" => "1 phút trước", "%d minutes ago" => "%d phút trước", +"1 hour ago" => "1 giờ trước", +"%d hours ago" => "%d giờ trước", "today" => "hôm nay", "yesterday" => "hôm qua", "%d days ago" => "%d ngày trước", "last month" => "tháng trước", +"%d months ago" => "%d tháng trước", "last year" => "năm trước", "years ago" => "năm trước", "%s is available. Get <a href=\"%s\">more information</a>" => "%s có sẵn. <a href=\"%s\">xem thêm ở đây</a>", "up to date" => "đến ngày", -"updates check is disabled" => "đã TĂT chức năng cập nhật " +"updates check is disabled" => "đã TĂT chức năng cập nhật ", +"Could not find category \"%s\"" => "không thể tìm thấy mục \"%s\"" ); diff --git a/lib/l10n/zh_CN.php b/lib/l10n/zh_CN.php index 270f69594e9..c3af288b727 100644 --- a/lib/l10n/zh_CN.php +++ b/lib/l10n/zh_CN.php @@ -18,13 +18,17 @@ "seconds ago" => "几秒前", "1 minute ago" => "1分钟前", "%d minutes ago" => "%d 分钟前", +"1 hour ago" => "1小时前", +"%d hours ago" => "%d小时前", "today" => "今天", "yesterday" => "昨天", "%d days ago" => "%d 天前", "last month" => "上月", +"%d months ago" => "%d 月前", "last year" => "上年", "years ago" => "几年前", "%s is available. Get <a href=\"%s\">more information</a>" => "%s 已存在. 点此 <a href=\"%s\">获取更多信息</a>", "up to date" => "已更新。", -"updates check is disabled" => "检查更新功能被关闭。" +"updates check is disabled" => "检查更新功能被关闭。", +"Could not find category \"%s\"" => "无法找到分类 \"%s\"" ); diff --git a/lib/public/contacts.php b/lib/public/contacts.php new file mode 100644 index 00000000000..5762fd28e02 --- /dev/null +++ b/lib/public/contacts.php @@ -0,0 +1,103 @@ +<?php +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2012 Thomas Müller thomas.mueller@tmit.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/** + * Public interface of ownCloud for apps to use. + * Contacts Class + * + */ + +// use OCP namespace for all classes that are considered public. +// This means that they should be used by apps instead of the internal ownCloud classes +namespace OCP; + +/** + * This class provides access to the contacts app. Use this class exclusively if you want to access contacts. + * + * Contacts in general will be expressed as an array of key-value-pairs. + * The keys will match the property names defined in https://tools.ietf.org/html/rfc2426#section-1 + * + * Proposed workflow for working with contacts: + * - search for the contacts + * - manipulate the results array + * - createOrUpdate will save the given contacts overwriting the existing data + * + * For updating it is mandatory to keep the id. + * Without an id a new contact will be created. + * + */ +class Contacts +{ + /** + * This function is used to search and find contacts within the users address books. + * In case $pattern is empty all contacts will be returned. + * + * @param string $pattern which should match within the $searchProperties + * @param array $searchProperties defines the properties within the query pattern should match + * @param array $options - for future use. One should always have options! + * @return array of contacts which are arrays of key-value-pairs + */ + public static function search($pattern, $searchProperties = array(), $options = array()) { + + // dummy results + return array( + array('id' => 0, 'FN' => 'Thomas Müller', 'EMAIL' => 'a@b.c', 'GEO' => '37.386013;-122.082932'), + array('id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => array('d@e.f', 'g@h.i')), + ); + } + + /** + * This function can be used to delete the contact identified by the given id + * + * @param object $id the unique identifier to a contact + * @return bool successful or not + */ + public static function delete($id) { + return false; + } + + /** + * This function is used to create a new contact if 'id' is not given or not present. + * Otherwise the contact will be updated by replacing the entire data set. + * + * @param array $properties this array if key-value-pairs defines a contact + * @return array representing the contact just created or updated + */ + public static function createOrUpdate($properties) { + + // dummy + return array('id' => 0, 'FN' => 'Thomas Müller', 'EMAIL' => 'a@b.c', + 'PHOTO' => 'VALUE=uri:http://www.abc.com/pub/photos/jqpublic.gif', + 'ADR' => ';;123 Main Street;Any Town;CA;91921-1234' + ); + } + + /** + * Check if contacts are available (e.g. contacts app enabled) + * + * @return bool true if enabled, false if not + */ + public static function isEnabled() { + return false; + } + +} diff --git a/lib/util.php b/lib/util.php index 16dcfc73d7d..89fbcd05cda 100755 --- a/lib/util.php +++ b/lib/util.php @@ -698,7 +698,7 @@ class OC_Util { curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($curl, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_USERAGENT, "ownCloud Server Crawler"); + curl_setopt($curl, CURLOPT_USERAGENT, "ownCloud Server Crawler"); $data = curl_exec($curl); curl_close($curl); |