diff options
author | Georg Ehrke <dev@georgswebsite.de> | 2012-03-25 14:02:40 +0200 |
---|---|---|
committer | Georg Ehrke <dev@georgswebsite.de> | 2012-03-25 14:02:40 +0200 |
commit | ac0c5ba6daf5ffe84088571ea307f5223bd1049a (patch) | |
tree | c1d51a3f52832dc11cd2648c35edb93e47c148fc /apps | |
parent | 8e8c4a8edc630ff833361c067da5e0d30e94c6d1 (diff) | |
parent | 34c08b3165ff7ee024006b4c425130fde057863c (diff) | |
download | nextcloud-server-ac0c5ba6daf5ffe84088571ea307f5223bd1049a.tar.gz nextcloud-server-ac0c5ba6daf5ffe84088571ea307f5223bd1049a.zip |
Merge branch 'master' into sabredav_1.6
Diffstat (limited to 'apps')
26 files changed, 1237 insertions, 28 deletions
diff --git a/apps/bookmarks/bookmarksHelper.php b/apps/bookmarks/bookmarksHelper.php index 8def7401e2f..7ada69014fb 100644 --- a/apps/bookmarks/bookmarksHelper.php +++ b/apps/bookmarks/bookmarksHelper.php @@ -71,7 +71,7 @@ function getURLMetadata($url) { return $metadata; } -function addBookmark($url, $title='', $tags='') { +function addBookmark($url, $title, $tags='') { $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" ); if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){ $_ut = "strftime('%s','now')"; @@ -93,6 +93,11 @@ function addBookmark($url, $title='', $tags='') { $title = $metadata['title']; } + if(empty($title)) { + $l = new OC_L10N('bookmarks'); + $title = $l->t('unnamed'); + } + $params=array( htmlspecialchars_decode($url), htmlspecialchars_decode($title), diff --git a/apps/bookmarks/js/bookmarks.js b/apps/bookmarks/js/bookmarks.js index fa5adde2545..9502af0a00d 100644 --- a/apps/bookmarks/js/bookmarks.js +++ b/apps/bookmarks/js/bookmarks.js @@ -9,9 +9,7 @@ $(document).ready(function() { fillWindow($('.bookmarks_list')); }); $(window).resize(); - $($('.bookmarks_list')).scroll(updateOnBottom); - - $('.bookmarks_list').empty(); + $('.bookmarks_list').scroll(updateOnBottom).empty().width($('#content').width()); getBookmarks(); }); @@ -145,7 +143,7 @@ function updateBookmarksList(bookmark) { '<p class="bookmark_title">'+ '<a href="' + encodeEntities(bookmark.url) + '" target="_blank" class="bookmark_link">' + encodeEntities(bookmark.title) + '</a>' + '</p>' + - '<p class="bookmark_url">' + encodeEntities(bookmark.url) + '</p>' + + '<p class="bookmark_url"><a href="' + encodeEntities(bookmark.url) + '" target="_blank" class="bookmark_link">' + encodeEntities(bookmark.url) + '</a></p>' + '</div>' ); if(taglist != '') { diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php index dff02e15875..724cde45669 100755 --- a/apps/calendar/ajax/events.php +++ b/apps/calendar/ajax/events.php @@ -8,11 +8,13 @@ require_once ('../../../lib/base.php'); require_once('when/When.php'); - +$l = new OC_L10N('calendar'); +$unnamed = $l->t('unnamed'); function create_return_event($event, $vevent){ $return_event = array(); + global $unnamed; $return_event['id'] = (int)$event['id']; - $return_event['title'] = htmlspecialchars($event['summary']); + $return_event['title'] = htmlspecialchars(($event['summary']!=NULL || $event['summary'] != '')?$event['summary']: $unnamed); $return_event['description'] = isset($vevent->DESCRIPTION)?htmlspecialchars($vevent->DESCRIPTION->value):''; $last_modified = $vevent->__get('LAST-MODIFIED'); if ($last_modified){ diff --git a/apps/files_remote/appinfo/app.php b/apps/files_remote/appinfo/app.php index f94e813ea5f..02c1c3ae313 100644 --- a/apps/files_remote/appinfo/app.php +++ b/apps/files_remote/appinfo/app.php @@ -7,3 +7,5 @@ */ OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_remote/lib/ftp.php'; +OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_remote/lib/webdav.php'; +OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_remote/lib/google.php'; diff --git a/apps/files_remote/lib/google.php b/apps/files_remote/lib/google.php new file mode 100644 index 00000000000..0d6db1987f8 --- /dev/null +++ b/apps/files_remote/lib/google.php @@ -0,0 +1,409 @@ +<?php + +/** +* ownCloud +* +* @author Michael Gapczynski +* @copyright 2012 Michael Gapczynski mtgap@owncloud.com +* +* 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/>. +*/ + +require_once 'common.inc.php'; + +class OC_Filestorage_Google extends OC_Filestorage_Common { + + private $consumer; + private $oauth_token; + private $sig_method; + private $entries; + + public function __construct($arguments) { + $consumer_key = isset($arguments['consumer_key']) ? $arguments['consumer_key'] : 'anonymous'; + $consumer_secret = isset($arguments['consumer_secret']) ? $arguments['consumer_secret'] : 'anonymous'; + $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); + $this->oauth_token = new OAuthToken($arguments['token'], $arguments['token_secret']); + $this->sig_method = new OAuthSignatureMethod_HMAC_SHA1(); + $this->entries = array(); + } + + private function sendRequest($feedUri, $http_method, $isDownload = false, $postData = null) { + $feedUri = trim($feedUri); + // create an associative array from each key/value url query param pair. + $params = array(); + $pieces = explode('?', $feedUri); + if (isset($pieces[1])) { + $params = explode_assoc('=', '&', $pieces[1]); + } + // urlencode each url parameter key/value pair + $tempStr = $pieces[0]; + foreach ($params as $key => $value) { + $tempStr .= '&' . urlencode($key) . '=' . urlencode($value); + } + $feedUri = preg_replace('/&/', '?', $tempStr, 1); + $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $http_method, $feedUri, $params); + $request->sign_request($this->sig_method, $this->consumer, $this->oauth_token); + $auth_header = $request->to_header(); + $headers = array($auth_header, 'Content-Type: application/atom+xml', 'GData-Version: 3.0'); + $curl = curl_init($feedUri); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_FAILONERROR, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + switch ($http_method) { + case 'GET': + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + break; + case 'POST': + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); + break; + case 'PUT': + $headers[] = 'If-Match: *'; + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method); + curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); + break; + case 'DELETE': + $headers[] = 'If-Match: *'; + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method); + break; + default: + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + } + if ($isDownload) { + $tmpFile = OC_Helper::tmpFile(); + $fp = fopen($tmpFile, 'w'); + curl_setopt($curl, CURLOPT_FILE, $fp); + curl_exec($curl); + curl_close($curl); + return $tmpFile; + } + $result = curl_exec($curl); + curl_close($curl); + $dom = new DOMDocument(); + $dom->loadXML($result); + return $dom; + } + + private function getResource($path) { + $file = basename($path); + if (array_key_exists($file, $this->entries)) { + return $this->entries[$file]; + } else { + // Strip the file extension; file could be a native Google Docs resource + if ($pos = strpos($file, '.')) { + $title = substr($file, 0, $pos); + $dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$title, 'GET'); + // Check if request was successful and entry exists + if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) { + $this->entries[$file] = $entry; + return $entry; + } + } + $dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$file, 'GET'); + // Check if request was successful and entry exists + if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) { + $this->entries[$file] = $entry; + return $entry; + } + return false; + } + } + + private function getExtension($entry) { + $mimetype = $this->getMimeType('', $entry); + switch ($mimetype) { + case 'httpd/unix-directory': + return ''; + case 'application/vnd.oasis.opendocument.text': + return 'odt'; + case 'application/vnd.oasis.opendocument.spreadsheet': + return 'ods'; + case 'application/vnd.oasis.opendocument.presentation': + return 'pptx'; + case 'text/html': + return 'html'; + default: + return 'html'; + } + } + + + public function mkdir($path) { + $dir = dirname($path); + // Check if path parent is root directory + if ($dir == '/' || $dir == '\.' || $dir == '.') { + $feedUri = 'https://docs.google.com/feeds/default/private/full'; + // Get parent content link + } else if ($dom = $this->getResource(basename($dir))) { + $feedUri = $dom->getElementsByTagName('content')->item(0)->getAttribute('src'); + } + if (isset($feedUri)) { + $title = basename($path); + // Construct post data + $postData = '<?xml version="1.0" encoding="UTF-8"?>'; + $postData .= '<entry xmlns="http://www.w3.org/2005/Atom">'; + $postData .= '<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#folder"/>'; + $postData .= '<title>'.$title.'</title>'; + $postData .= '</entry>'; + if ($dom = $this->sendRequest($feedUri, 'POST', $postData)) { + return true; + } + } + return false; + } + + public function rmdir($path) { + return $this->unlink($path); + } + + public function opendir($path) { + if ($path == '' || $path == '/') { + $next = 'https://docs.google.com/feeds/default/private/full/folder%3Aroot/contents'; + } else { + if ($entry = $this->getResource($path)) { + $next = $entry->getElementsByTagName('content')->item(0)->getAttribute('src'); + } else { + return false; + } + } + $files = array(); + while ($next) { + $dom = $this->sendRequest($next, 'GET'); + $links = $dom->getElementsByTagName('link'); + foreach ($links as $link) { + if ($link->getAttribute('rel') == 'next') { + $next = $link->getAttribute('src'); + break; + } else { + $next = false; + } + } + $entries = $dom->getElementsByTagName('entry'); + foreach ($entries as $entry) { + $name = $entry->getElementsByTagName('title')->item(0)->nodeValue; + // Google Docs resources don't always include extensions in title + if (!strpos($name, '.')) { + $extension = $this->getExtension($entry); + if ($extension != '') { + $name .= '.'.$extension; + } + } + $files[] = $name; + // Cache entry for future use + $this->entries[$name] = $entry; + } + } + OC_FakeDirStream::$dirs['google'] = $files; + return opendir('fakedir://google'); + } + + public function stat($path) { + if ($path == '' || $path == '/') { + $stat['size'] = $this->free_space($path); + $stat['atime'] = time(); + $stat['mtime'] = time(); + $stat['ctime'] = time(); + } else if ($entry = $this->getResource($path)) { + // NOTE: Native resources don't have a file size + $stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue; +// if (isset($atime = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue)) +// $stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue); + $stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue); + $stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue); + } + if (isset($stat)) { + return $stat; + } + return false; + } + + public function filetype($path) { + if ($path == '' || $path == '/') { + return 'dir'; + } else if ($entry = $this->getResource($path)) { + $categories = $entry->getElementsByTagName('category'); + foreach ($categories as $category) { + if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') { + $type = $category->getAttribute('label'); + if (strlen(strstr($type, 'folder')) > 0) { + return 'dir'; + } else { + return 'file'; + } + } + } + } + return false; + } + + public function is_readable($path) { + return true; + } + + public function is_writable($path) { + if ($path == '' || $path == '/') { + return true; + } else if ($entry = $this->getResource($path)) { + // Check if edit or edit-media links exist + $links = $entry->getElementsByTagName('link'); + foreach ($links as $link) { + if ($link->getAttribute('rel') == 'edit') { + return true; + } else if ($link->getAttribute('rel') == 'edit-media') { + return true; + } + } + } + return false; + } + + public function file_exists($path) { + if ($path == '' || $path == '/') { + return true; + } else if ($this->getResource($path)) { + return true; + } + return false; + } + + public function unlink($path) { + // Get resource self link to trash resource + if ($entry = $this->getResource($path)) { + $links = $entry->getElementsByTagName('link'); + foreach ($links as $link) { + if ($link->getAttribute('rel') == 'self') { + $feedUri = $link->getAttribute('href'); + } + } + } + if (isset($feedUri)) { + $this->sendRequest($feedUri, 'DELETE'); + return true; + } + return false; + } + + public function rename($path1, $path2) { + // TODO Add support for moving to different collections + // Get resource edit link to rename resource + if ($entry = $this->getResource($path1)) { + $etag = $entry->getElementsByTagName('entry')->item(0)->getAttribute('gd:etag'); + $links = $entry->getElementsByTagName('link'); + foreach ($links as $link) { + if ($link->getAttribute('rel') == 'edit') { + $feedUri = $link->getAttribute('href'); + } + } + } + if (isset($etag) && isset($feedUri)) { + $title = basename($path2); + // Construct post data + $postData = '<?xml version="1.0" encoding="UTF-8"?>'; + $postData .= '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007" xmlns:gd="http://schemas.google.com/g/2005" gd:etag='.$etag.'>'; + $postData .= '<title>'.$title.'</title>'; + $postData .= '</entry>'; + $this->sendRequest($feedUri, 'PUT', $postData); + return true; + } + return false; + } + + public function fopen($path, $mode) { + if ($entry = $this->getResource($path)) { + switch ($mode) { + case 'r': + case 'rb': + $extension = $this->getExtension($entry); + $downloadUri = $entry->getElementsByTagName('content')->item(0)->getAttribute('src'); + // TODO Non-native documents don't need these additional parameters + $downloadUri .= '&exportFormat='.$extension.'&format='.$extension; + $tmpFile = $this->sendRequest($downloadUri, 'GET', true); + return fopen($tmpFile, 'r'); + case 'w': + case 'wb': + case 'a': + case 'ab': + case 'r+': + case 'w+': + case 'wb+': + case 'a+': + case 'x': + case 'x+': + case 'c': + case 'c+': + // TODO Edit documents + } + + } + return false; + } + + public function getMimeType($path, $entry = null) { + // Entry can be passed, because extension is required for opendir and the entry can't be cached without the extension + if ($entry == null) { + if ($path == '' || $path == '/') { + return 'httpd/unix-directory'; + } else { + $entry = $this->getResource($path); + } + } + if ($entry) { + $mimetype = $entry->getElementsByTagName('content')->item(0)->getAttribute('type'); + // Native Google Docs resources often default to text/html, but it may be more useful to default to a corresponding ODF mimetype + // Collections get reported as application/atom+xml, make sure it actually is a folder and fix the mimetype + if ($mimetype == 'text/html' || $mimetype == 'application/atom+xml;type=feed') { + $categories = $entry->getElementsByTagName('category'); + foreach ($categories as $category) { + if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') { + $type = $category->getAttribute('label'); + if (strlen(strstr($type, 'folder')) > 0) { + return 'httpd/unix-directory'; + } else if (strlen(strstr($type, 'document')) > 0) { + return 'application/vnd.oasis.opendocument.text'; + } else if (strlen(strstr($type, 'spreadsheet')) > 0) { + return 'application/vnd.oasis.opendocument.spreadsheet'; + } else if (strlen(strstr($type, 'presentation')) > 0) { + return 'application/vnd.oasis.opendocument.presentation'; + } else if (strlen(strstr($type, 'drawing')) > 0) { + return 'application/vnd.oasis.opendocument.graphics'; + } else { + // If nothing matches return text/html, all native Google Docs resources can be exported as text/html + return 'text/html'; + } + } + } + } + return $mimetype; + } + return false; + } + + public function free_space($path) { + if ($dom = $this->sendRequest('https://docs.google.com/feeds/metadata/default', 'GET')) { + // NOTE: Native Google Docs resources don't count towards quota + $total = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesTotal')->item(0)->nodeValue; + $used = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue; + return $total - $used; + } + return false; + } + + public function touch($path, $mtime = null) { + + } + +}
\ No newline at end of file diff --git a/apps/files_remote/lib/webdav.php b/apps/files_remote/lib/webdav.php new file mode 100644 index 00000000000..7a2da5c8ec0 --- /dev/null +++ b/apps/files_remote/lib/webdav.php @@ -0,0 +1,293 @@ +<?php +/** + * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class OC_FileStorage_DAV extends OC_Filestorage_Common{ + private $password; + private $user; + private $host; + private $secure; + private $root; + /** + * @var Sabre_DAV_Client + */ + private $client; + + private static $tempFiles=array(); + + public function __construct($params){ + $this->host=$params['host']; + $this->user=$params['user']; + $this->password=$params['password']; + $this->secure=isset($params['secure'])?(bool)$params['secure']:false; + $this->root=isset($params['root'])?$params['root']:'/'; + if(substr($this->root,0,1)!='/'){ + $this->root='/'.$this->root; + } + if(substr($this->root,-1,1)!='/'){ + $this->root.='/'; + } + + $settings = array( + 'baseUri' => $this->createBaseUri(), + 'userName' => $this->user, + 'password' => $this->password, + ); + $this->client = new Sabre_DAV_Client($settings); + + //create the root folder if necesary + $this->mkdir(''); + } + + private function createBaseUri(){ + $baseUri='http'; + if($this->secure){ + $baseUri.'s'; + } + $baseUri.='://'.$this->host.$this->root; + return $baseUri; + } + + public function mkdir($path){ + $path=$this->cleanPath($path); + return $this->simpleResponse('MKCOL',$path,null,201); + } + + public function rmdir($path){ + $path=$this->cleanPath($path); + return $this->simpleResponse('DELETE',$path,null,204); + } + + public function opendir($path){ + $path=$this->cleanPath($path); + try{ + $response=$this->client->propfind($path, array(),1); + $stripLength=strlen($this->root)+strlen($path); + $id=md5('webdav'.$this->root.$path); + OC_FakeDirStream::$dirs[$id]=array(); + foreach($response as $file=>$data){ + //strip root and path + $file=trim(substr($file,$stripLength)); + $file=trim($file,'/'); + if($file){ + OC_FakeDirStream::$dirs[$id][]=$file; + } + } + return opendir('fakedir://'.$id); + }catch(Exception $e){ + return false; + } + } + + public function filetype($path){ + $path=$this->cleanPath($path); + try{ + $response=$this->client->propfind($path, array('{DAV:}resourcetype')); + $responseType=$response["{DAV:}resourcetype"]->resourceType; + return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file'; + }catch(Exception $e){ + return false; + } + } + + public function is_readable($path){ + return true;//not properly supported + } + + public function is_writable($path){ + return true;//not properly supported + } + + public function file_exists($path){ + $path=$this->cleanPath($path); + try{ + $response=$this->client->propfind($path, array('{DAV:}resourcetype')); + return true;//no 404 exception + }catch(Exception $e){ + return false; + } + } + + public function unlink($path){ + return $this->simpleResponse('DELETE',$path,null,204); + } + + public function fopen($path,$mode){ + $path=$this->cleanPath($path); + switch($mode){ + case 'r': + case 'rb': + //straight up curl instead of sabredav here, sabredav put's the entire get result in memory + $curl = curl_init(); + $fp = fopen('php://temp', 'r+'); + curl_setopt($curl,CURLOPT_USERPWD,$this->user.':'.$this->password); + curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$path); + curl_setopt($curl, CURLOPT_FILE, $fp); + + curl_exec ($curl); + curl_close ($curl); + rewind($fp); + return $fp; + case 'w': + case 'wb': + case 'a': + case 'ab': + case 'r+': + case 'w+': + case 'wb+': + case 'a+': + case 'x': + case 'x+': + case 'c': + case 'c+': + //emulate these + if(strrpos($path,'.')!==false){ + $ext=substr($path,strrpos($path,'.')); + }else{ + $ext=''; + } + $tmpFile=OC_Helper::tmpFile($ext); + OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); + if($this->file_exists($path)){ + $this->getFile($path,$tmpFile); + } + self::$tempFiles[$tmpFile]=$path; + return fopen('close://'.$tmpFile,$mode); + } + } + + public function writeBack($tmpFile){ + if(isset(self::$tempFiles[$tmpFile])){ + $this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]); + unlink($tmpFile); + } + } + + public function free_space($path){ + $path=$this->cleanPath($path); + try{ + $response=$this->client->propfind($path, array('{DAV:}quota-available-bytes')); + if(isset($response['{DAV:}quota-available-bytes'])){ + return (int)$response['{DAV:}quota-available-bytes']; + }else{ + return 0; + } + }catch(Exception $e){ + return 0; + } + } + + public function touch($path,$mtime=null){ + if(is_null($mtime)){ + $mtime=time(); + } + $path=$this->cleanPath($path); + $this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime,)); + } + + public function getFile($path,$target){ + $source=$this->fopen($path,'r'); + file_put_contents($target,$source); + } + + public function uploadFile($path,$target){ + $source=fopen($path,'r'); + + $curl = curl_init(); + curl_setopt($curl,CURLOPT_USERPWD,$this->user.':'.$this->password); + curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$target); + curl_setopt($curl, CURLOPT_BINARYTRANSFER, true); + curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer + curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path)); + curl_setopt($curl, CURLOPT_PUT, true); + curl_exec ($curl); + curl_close ($curl); + } + + public function rename($path1,$path2){ + $path1=$this->cleanPath($path1); + $path2=$this->root.$this->cleanPath($path2); + try{ + $response=$this->client->request('MOVE',$path1,null,array('Destination'=>$path2)); + return true; + }catch(Exception $e){ + echo $e; + echo 'fail'; + var_dump($response); + return false; + } + } + + public function copy($path1,$path2){ + $path1=$this->cleanPath($path1); + $path2=$this->root.$this->cleanPath($path2); + try{ + $response=$this->client->request('COPY',$path1,null,array('Destination'=>$path2)); + return true; + }catch(Exception $e){ + echo $e; + echo 'fail'; + var_dump($response); + return false; + } + } + + public function stat($path){ + $path=$this->cleanPath($path); + try{ + $response=$this->client->propfind($path, array('{DAV:}getlastmodified','{DAV:}getcontentlength')); + if(isset($response['{DAV:}getlastmodified']) and isset($response['{DAV:}getcontentlength'])){ + return array( + 'mtime'=>strtotime($response['{DAV:}getlastmodified']), + 'size'=>(int)$response['{DAV:}getcontentlength'], + 'ctime'=>-1, + ); + }else{ + return array(); + } + }catch(Exception $e){ + return array(); + } + } + + public function getMimeType($path){ + $path=$this->cleanPath($path); + try{ + $response=$this->client->propfind($path, array('{DAV:}getcontenttype','{DAV:}resourcetype')); + $responseType=$response["{DAV:}resourcetype"]->resourceType; + $type=(count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file'; + if($type=='dir'){ + return 'httpd/unix-directory'; + }elseif(isset($response['{DAV:}getcontenttype'])){ + return $response['{DAV:}getcontenttype']; + }else{ + return false; + } + }catch(Exception $e){ + return false; + } + } + + private function cleanPath($path){ + if(substr($path,0,1)=='/'){ + return substr($path,1); + }else{ + return $path; + } + } + + private function simpleResponse($method,$path,$body,$expected){ + $path=$this->cleanPath($path); + try{ + $response=$this->client->request($method,$path,$body); + return $response['statusCode']==$expected; + }catch(Exception $e){ + return false; + } + } +} + diff --git a/apps/files_remote/tests/config.php b/apps/files_remote/tests/config.php index 54105782919..9b40d2b98cf 100644 --- a/apps/files_remote/tests/config.php +++ b/apps/files_remote/tests/config.php @@ -5,5 +5,18 @@ return array( 'user'=>'test', 'password'=>'test', 'root'=>'/test', + ), + 'webdav'=>array( + 'host'=>'localhost', + 'user'=>'test', + 'password'=>'test', + 'root'=>'/owncloud/files/webdav.php', + ), + 'google'=>array( + 'consumer_key'=>'anonymous', + 'consumer_secret'=>'anonymous', + 'token'=>'test', + 'token_secret'=>'test', + 'root'=>'/google', ) ); diff --git a/apps/files_remote/tests/ftp.php b/apps/files_remote/tests/ftp.php index 2d5405ccda6..03633b7c0d1 100644 --- a/apps/files_remote/tests/ftp.php +++ b/apps/files_remote/tests/ftp.php @@ -7,9 +7,6 @@ */ class Test_Filestorage_FTP extends Test_FileStorage { - /** - * @var string tmpDir - */ private $config; private $id; @@ -24,5 +21,3 @@ class Test_Filestorage_FTP extends Test_FileStorage { OC_Helper::rmdirr($this->instance->constructUrl('')); } } - -?>
\ No newline at end of file diff --git a/apps/files_remote/tests/google.php b/apps/files_remote/tests/google.php new file mode 100644 index 00000000000..b49f9e4647c --- /dev/null +++ b/apps/files_remote/tests/google.php @@ -0,0 +1,38 @@ +<?php + +/** +* ownCloud +* +* @author Michael Gapczynski +* @copyright 2012 Michael Gapczynski mtgap@owncloud.com +* +* 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/>. +*/ + +class Test_Filestorage_Google extends Test_FileStorage { + + private $config; + private $id; + + public function setUp(){ + $id=uniqid(); + $this->config=include('apps/files_remote/tests/config.php'); + $this->config['google']['root'].='/'.$id;//make sure we have an new empty folder to work in + $this->instance=new OC_Filestorage_Google($this->config['google']); + } + + public function tearDown(){ + $this->instance->rmdir('/'); + } +}
\ No newline at end of file diff --git a/apps/files_remote/tests/webdav.php b/apps/files_remote/tests/webdav.php new file mode 100644 index 00000000000..219fff8852d --- /dev/null +++ b/apps/files_remote/tests/webdav.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_Filestorage_DAV extends Test_FileStorage { + private $config; + private $id; + + public function setUp(){ + $id=uniqid(); + $this->config=include('apps/files_remote/tests/config.php'); + $this->config['webdav']['root'].='/'.$id;//make sure we have an new empty folder to work in + $this->instance=new OC_Filestorage_DAV($this->config['webdav']); + } + + public function tearDown(){ + $this->instance->rmdir('/'); + } +} diff --git a/apps/gallery/ajax/galleryOp.php b/apps/gallery/ajax/galleryOp.php index 459c30f6ac6..b0433898cda 100644 --- a/apps/gallery/ajax/galleryOp.php +++ b/apps/gallery/ajax/galleryOp.php @@ -111,9 +111,48 @@ function handleGetGallery($path) { $p[] = utf8_encode($r['file_path']); } - OC_JSON::success(array('albums'=>$a, 'photos'=>$p)); + $r = OC_Gallery_Sharing::getEntryByAlbumId($album_details['album_id']); + $shared = false; + $recursive = false; + $token = ''; + if ($row = $r->fetchRow()) { + $shared = true; + $recursive = ($row['recursive'] == 1)? true : false; + $token = $row['token']; + } + + OC_JSON::success(array('albums'=>$a, 'photos'=>$p, 'shared' => $shared, 'recursive' => $recursive, 'token' => $token)); +} + +function handleShare($path, $share, $recursive) { + $recursive = $recursive == 'true' ? 1 : 0; + $owner = OC_User::getUser(); + $r = OC_Gallery_Album::find($owner, null, $path); + if ($row = $r->fetchRow()) { + $albumId = $row['album_id']; + } else { + OC_JSON::error(array('cause' => 'Couldn\'t find requested gallery')); + exit; + } + + if ($share == false) { + OC_Gallery_Sharing::remove($albumId); + OC_JSON::success(array('sharing' => false)); + } else { // share, yeah \o/ + $r = OC_Gallery_Sharing::getEntryByAlbumId($albumId); + if (($row = $r->fetchRow())) { // update entry + OC_Gallery_Sharing::updateSharingByToken($row['token'], $recursive); + OC_JSON::success(array('sharing' => true, 'token' => $row['token'], 'recursive' => $recursive == 1 ? true : false )); + } else { // and new sharing entry + $date = new DateTime(); + $token = md5($owner . $date->getTimestamp()); + OC_Gallery_Sharing::addShared($token, intval($albumId), $recursive); + OC_JSON::success(array('sharing' => true, 'token' => $token, 'recursive' => $recursive == 1 ? true : false )); + } + } } + if ($_GET['operation']) { switch($_GET['operation']) { case 'rename': @@ -136,6 +175,9 @@ if ($_GET['operation']) { case 'get_gallery': handleGetGallery($_GET['path']); break; + case 'share': + handleShare($_GET['path'], $_GET['share'] == 'true' ? true : false, $_GET['recursive']); + break; default: OC_JSON::error(array('cause' => 'Unknown operation')); } diff --git a/apps/gallery/ajax/sharing.php b/apps/gallery/ajax/sharing.php new file mode 100644 index 00000000000..fba85fa34ee --- /dev/null +++ b/apps/gallery/ajax/sharing.php @@ -0,0 +1,115 @@ +<?php + +/** +* ownCloud - gallery application +* +* @author Bartek Przybylski +* @copyright 2012 Bartek Przybylski bartek@alefzero.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 Lesser General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +require_once('../../../lib/base.php'); + +if (!isset($_GET['token']) || !isset($_GET['operation'])) { + OC_JSON::error(array('cause' => 'Not enought arguments')); + exit; +} + +$operation = $_GET['operation']; +$token = $_GET['token']; + +if (!OC_Gallery_Sharing::isTokenValid($token)) { + OC_JSON::error(array('cause' => 'Given token is not valid')); + exit; +} + +function handleGetGallery($token, $path) { + $owner = OC_Gallery_Sharing::getTokenOwner($token); + $apath = OC_Gallery_Sharing::getPath($token); + + if ($path == false) + $root = $apath; + else + $root = rtrim($apath,'/').$path; + + $r = OC_Gallery_Album::find($owner, null, $root); + $albums = array(); + $photos = array(); + $albumId = -1; + if ($row = $r->fetchRow()) { + $albumId = $row['album_id']; + } + if ($albumId != -1) { + + if (OC_Gallery_Sharing::isRecursive($token)) { + $r = OC_Gallery_Album::find($owner, null, null, $root); + while ($row = $r->fetchRow()) + $albums[] = $row['album_name']; + } + + $r = OC_Gallery_Photo::find($albumId); + while ($row = $r->fetchRow()) + $photos[] = $row['file_path']; + } + + OC_JSON::success(array('albums' => $albums, 'photos' => $photos)); +} + +function handleGetThumbnail($token, $imgpath) { + $owner = OC_Gallery_Sharing::getTokenOwner($token); + $image = OC_Gallery_Photo::getThumbnail($imgpath, $owner); + if ($image) { + OC_Response::enableCaching(3600 * 24); // 24 hour + $image->show(); + } +} + +function handleGetAlbumThumbnail($token, $albumname) +{ + $owner = OC_Gallery_Sharing::getTokenOwner($token); + $file = OC_Config::getValue("datadirectory").'/'. $owner .'/gallery/'.$albumname.'.png'; + $image = new OC_Image($file); + if ($image->valid()) { + $image->centerCrop(); + $image->resize(200); + $image->fixOrientation(); + OC_Response::enableCaching(3600 * 24); // 24 hour + $image->show(); + } +} + +function handleGetPhoto($token, $photo) { + $owner = OC_Gallery_Sharing::getTokenOwner($token); + $file = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$owner.'/files'.urldecode($photo); + header('Content-Type: '.OC_Image::getMimeTypeForFile($file)); + OC_Response::sendFile($file); +} + +switch ($operation) { + case 'get_gallery': + handleGetGallery($token, isset($_GET['path'])? $_GET['path'] : false); + break; + case 'get_thumbnail': + handleGetThumbnail($token, urldecode($_GET['img'])); + break; + case 'get_album_thumbnail': + handleGetAlbumThumbnail($token, urldecode($_GET['albumname'])); + break; + case 'get_photo': + handleGetPhoto($token, urldecode($_GET['photo'])); + break; +} + diff --git a/apps/gallery/appinfo/app.php b/apps/gallery/appinfo/app.php index 1e5e27d408f..3e7e38301cf 100644 --- a/apps/gallery/appinfo/app.php +++ b/apps/gallery/appinfo/app.php @@ -24,6 +24,7 @@ OC::$CLASSPATH['OC_Gallery_Album'] = 'apps/gallery/lib/album.php'; OC::$CLASSPATH['OC_Gallery_Photo'] = 'apps/gallery/lib/photo.php'; OC::$CLASSPATH['OC_Gallery_Scanner'] = 'apps/gallery/lib/scanner.php'; +OC::$CLASSPATH['OC_Gallery_Sharing'] = 'apps/gallery/lib/sharing.php'; OC::$CLASSPATH['OC_Gallery_Hooks_Handlers'] = 'apps/gallery/lib/hooks_handlers.php'; $l = new OC_L10N('gallery'); diff --git a/apps/gallery/appinfo/database.xml b/apps/gallery/appinfo/database.xml index 62fdbee9cd8..e3b13f7e93c 100644 --- a/apps/gallery/appinfo/database.xml +++ b/apps/gallery/appinfo/database.xml @@ -67,4 +67,28 @@ </field> </declaration> </table> + <table> + <name>*dbprefix*gallery_sharing</name> + <declaration> + <field> + <name>token</name> + <type>text</type> + <notnull>true</notnull> + <length>64</length> + </field> + <field> + <name>gallery_id</name> + <type>integer</type> + <default>0</default> + <notnull>true</notnull> + <length>4</length> + </field> + <field> + <name>recursive</name> + <type>integer</type> + <notnull>true</notnull> + <length>1</length> + </field> + </declaration> + </table> </database> diff --git a/apps/gallery/css/sharing.css b/apps/gallery/css/sharing.css new file mode 100644 index 00000000000..eaac82ebd60 --- /dev/null +++ b/apps/gallery/css/sharing.css @@ -0,0 +1,8 @@ +body { background-color: #eee; margin: 0; padding: 0;} +#gallery_list { height: 100%; width: 80%; background-color: white; margin: 0 auto; box-shadow: 0 0 8px #888; } +div.gallery_box { width: 200px; position:relative; text-align: center; border: 0; display: inline-block; margin: 5pt; vertical-align: top; padding: 5px 5px 5px 5px; position: relative; cursor: pointer; -webkit-transition: color 0.5s ease-in-out; -o-transition: color 0.5s ease-in-out; -moz-transition: color 0.5s ease-in-out;color: #BBB;} +div.gallery_box:hover { color: black; } +div.gallery_box h1 {font-size: 17px; font-weight: normal;} +div#breadcrumb { border: 0; width: 70%; margin: 0 auto; padding: 25px 0; font-family: Verdana; text-align: center;} +span.breadcrumbelement { margin: 10px; margin-right: 0; cursor: pointer;} +span.inside { background-image: url('../img/breadcrumb.png'); padding-left: 20px; background-position: left; background-repeat: no-repeat;} diff --git a/apps/gallery/css/styles.css b/apps/gallery/css/styles.css index 013cd1b262d..fbf54e43db2 100644 --- a/apps/gallery/css/styles.css +++ b/apps/gallery/css/styles.css @@ -16,3 +16,5 @@ div.gallery_control_overlay a { color:white; } #g-settings {position: absolute; left 13.5em; top: 0;} input[type=button] { -webkit-transition: opacity 0.5s ease-in-out; -moz-transition: opacity 0.5s ease-in-out; -o-transition: opacity 0.5s ease-in-out; opacity: 1} input[type=button]:disabled { opacity: 0.5 } +.ui-dialog tr {background-color: #eee;} +.ui-dialog input {width: 90%;} diff --git a/apps/gallery/img/breadcrumb.png b/apps/gallery/img/breadcrumb.png Binary files differnew file mode 100644 index 00000000000..a252a751554 --- /dev/null +++ b/apps/gallery/img/breadcrumb.png diff --git a/apps/gallery/index.php b/apps/gallery/index.php index 822a5b8e143..7de7c094142 100644 --- a/apps/gallery/index.php +++ b/apps/gallery/index.php @@ -4,7 +4,7 @@ * ownCloud - gallery application * * @author Bartek Przybylski -* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com +* @copyright 2012 Bartek Przybylski bartek@alefzero.eu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -29,9 +29,6 @@ OC_App::setActiveNavigationEntry( 'gallery_index' ); if (!file_exists(OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery')) { mkdir(OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery'); - $f = fopen(OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery/.htaccess', 'w'); - fwrite($f, "allow from all"); - fclose($f); } if (!isset($_GET['view'])) { diff --git a/apps/gallery/js/album_cover.js b/apps/gallery/js/album_cover.js index 8cafce35f98..061bbcd0b47 100644 --- a/apps/gallery/js/album_cover.js +++ b/apps/gallery/js/album_cover.js @@ -30,17 +30,61 @@ function albumClick(title) { }); } +function constructSharingPath() { + return document.location.protocol + '//' + document.location.host + OC.linkTo('gallery', 'sharing.php') + '?token=' + Albums.token; +} + +function shareGallery() { + var existing_token = ''; + if (Albums.token) + existing_token = constructSharingPath(); + var form_fields = [{text: 'Share', name: 'share', type: 'checkbox', value: Albums.shared}, + {text: 'Share recursive', name: 'recursive', type: 'checkbox', value: Albums.recursive}, + {text: 'Shared gallery address', name: 'address', type: 'text', value: existing_token}]; + OC.dialogs.form(form_fields, t('gallery', 'Share gallery'), function(values){ + var p = ''; + for (var i in paths) p += '/'+paths[i]; + if (p == '') p = '/'; + $.getJSON(OC.filePath('gallery', 'ajax', 'galleryOp.php'), {operation: 'share', path: p, share: values[0].value, recursive: values[1].value}, function(r) { + if (r.status == 'success') { + Albums.shared = r.sharing; + if (Albums.shared) { + Albums.token = r.token; + Albums.recursive = r.recursive; + } else { + Albums.token = ''; + Albums.recursive = false; + } + var actual_addr = ''; + if (Albums.token) + actual_addr = constructSharingPath(); + $('input[name="address"]').val(actual_addr); + } else { + OC.dialogs.alert(t('gallery', 'Error: ') + r.cause, t('gallery', 'Internal error')); + } + }); + }); +} + function albumClickHandler(r) { Albums.photos = []; Albums.albums = []; if (r.status == 'success') { for (var i in r.albums) { var a = r.albums[i]; - Albums.add(a.name, a.numOfItems,a.path); + Albums.add(a.name, a.numOfItems, a.path, a.shared, a.recursive, a.token); } for (var i in r.photos) { - Albums.photos.push(r.photos[i]); + Albums.photos.push(r.photos[i]); } + Albums.shared = r.shared; + if (Albums.shared) { + Albums.recursive = r.recursive; + Albums.token = r.token; + } else { + Albums.recursive = false; + Albums.token = ''; + } var targetDiv = document.getElementById('gallery_list'); if (targetDiv) { $(targetDiv).html(''); @@ -54,7 +98,7 @@ function albumClickHandler(r) { OC.dialogs.alert(t('gallery', 'Error: no such layer `gallery_list`'), t('gallery', 'Internal error')); } } else { - OC.dialogs.alert(t('gallery', 'Error: ') + r.message, t('gallery', 'Internal error')); + OC.dialogs.alert(t('gallery', 'Error: ') + r.cause, t('gallery', 'Internal error')); } $('#g-album-loading').hide(); } diff --git a/apps/gallery/js/albums.js b/apps/gallery/js/albums.js index d3326841cc7..1fb38a5546c 100644 --- a/apps/gallery/js/albums.js +++ b/apps/gallery/js/albums.js @@ -8,12 +8,15 @@ Albums={ // the album cover albums:new Array(), photos:new Array(), + shared: false, + recursive: false, + token: '', // add simply adds new album to internal structure // however albums names must be unique so other // album with the same name wont be insered, // and false will be returned // true on success - add: function(album_name, num,path) { + add: function(album_name, num, path) { if (Albums.albums[album_name] != undefined) return false; Albums.albums[album_name] = {name: album_name, numOfCovers: num, path:path}; return true; @@ -64,14 +67,14 @@ Albums={ $(".gallery_album_cover", local).css('background-repeat', 'no-repeat'); $(".gallery_album_cover", local).css('background-position', '0'); $(".gallery_album_cover", local).css('background-image','url("'+OC.filePath('gallery','ajax','galleryOp.php')+'?operation=get_covers&albumname='+escape(a.name)+'")'); - $(".gallery_album_cover", local).mousemove(function(e) { + $(".gallery_album_cover", local).mousemove(function(event) { var albumMetadata = Albums.find(this.title); if (albumMetadata == undefined) { return; } - var x = Math.floor((e.layerX - this.offsetLeft)/(this.offsetWidth/albumMetadata.numOfCovers)); + var x = Math.floor(event.offsetX/(this.offsetWidth/albumMetadata.numOfCovers)); x *= this.offsetWidth; - if (x < 0) x=0; + if (x < 0 || isNaN(x)) x=0; $(this).css('background-position', -x+'px 0'); }); $(element).append(local); diff --git a/apps/gallery/js/sharing.js b/apps/gallery/js/sharing.js new file mode 100644 index 00000000000..340d1b9b274 --- /dev/null +++ b/apps/gallery/js/sharing.js @@ -0,0 +1,57 @@ +$(document).ready(function() { + $.getJSON('ajax/sharing.php', {operation: 'get_gallery', token: TOKEN}, albumClickHandler); +}); + +var paths = []; +var counter = 0; + +function returnTo(num) { + while (num != counter) { + paths.pop(); + $('.breadcrumbelement:last').remove(); + counter--; + } + path = ''; + for (var e in paths) path += '/' + paths[e]; + $.getJSON('ajax/sharing.php', {operation: 'get_gallery', token: TOKEN, path: path}, function(r) { + albumClickHandler(r); + }); +} + +function albumClickHandler(r) { + var element = $('div#gallery_list'); + element.html(''); + var album_template = '<div class="gallery_box"><div><a rel="images"><img src="ajax/sharing.php?token='+TOKEN+'&operation=get_album_thumbnail&albumname=IMGPATH"></a></div><h1></h1></div>'; + + for (var i in r.albums) { + var a = r.albums[i]; + var local = $(album_template.replace('IMGPATH', encodeURIComponent(a))); + local.attr('title', a); + $('h1', local).html(a); + element.append(local); + } + + $('div.gallery_box').each(function(i, element) { + $(element).click(function() { + paths.push($(this).attr('title')); + path = ''; + for (var e in paths) path += '/' + paths[e]; + $.getJSON('ajax/sharing.php', {operation: 'get_gallery', token: TOKEN, path: path}, function(r) { + var name = paths[paths.length-1]; + counter++; + var d = '<span class="breadcrumbelement" onclick="javascript:returnTo('+counter+');return false;">'+name+'</span>'; + d = $(d).addClass('inside'); + $('#breadcrumb').append(d); + albumClickHandler(r); + }); + }); + }); + + var pat = ''; + for (var a in paths) pat += '/'+paths[a]; + var photo_template = '<div class="gallery_box"><div><a rel="images" href="*HREF*" target="_blank"><img src="ajax/sharing.php?token='+TOKEN+'&operation=get_thumbnail&img=IMGPATH"></a></div></div>'; + for (var a in r.photos) { + var local = photo_template.replace('IMGPATH', encodeURIComponent(r.photos[a])).replace('*HREF*', 'ajax/sharing.php?token='+TOKEN+'&operation=get_photo&photo='+encodeURIComponent(r.photos[a])); + element.append(local); + } +} diff --git a/apps/gallery/lib/album.php b/apps/gallery/lib/album.php index 070afdd6cd6..ef361a37913 100644 --- a/apps/gallery/lib/album.php +++ b/apps/gallery/lib/album.php @@ -79,7 +79,7 @@ class OC_Gallery_Album { $sql .= ' AND parent_path = ?'; $args[] = $parent; } - $order = OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'order', 'ASC'); + $order = OC_Preferences::getValue($owner, 'gallery', 'order', 'ASC'); $sql .= ' ORDER BY album_name ' . $order; $stmt = OC_DB::prepare($sql); diff --git a/apps/gallery/lib/photo.php b/apps/gallery/lib/photo.php index 5e6df8069b5..0c0f16e659a 100644 --- a/apps/gallery/lib/photo.php +++ b/apps/gallery/lib/photo.php @@ -66,8 +66,9 @@ class OC_Gallery_Photo { $stmt->execute(array($newpath, $newAlbumId, $oldAlbumId, $oldpath)); } - public static function getThumbnail($image_name) { - $save_dir = OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery/'; + public static function getThumbnail($image_name, $owner = null) { + if (!$owner) $owner = OC_User::getUser(); + $save_dir = OC_Config::getValue("datadirectory").'/'. $owner .'/gallery/'; $save_dir .= dirname($image_name). '/'; $image_path = $image_name; $thumb_file = $save_dir . basename($image_name); diff --git a/apps/gallery/lib/sharing.php b/apps/gallery/lib/sharing.php new file mode 100644 index 00000000000..60f108bd6c6 --- /dev/null +++ b/apps/gallery/lib/sharing.php @@ -0,0 +1,89 @@ +<?php + +/** +* ownCloud - gallery application +* +* @author Bartek Przybylski +* @copyright 2012 Bartek Przybylski bartek@alefzero.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 Lesser General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +class OC_Gallery_Sharing { + private static function getEntries($token) { + $sql = 'SELECT * FROM *PREFIX*gallery_sharing WHERE token = ?'; + $stmt = OC_DB::prepare($sql); + return $stmt->execute(array($token)); + } + + public static function isTokenValid($token) { + $r = self::getEntries($token); + $row = $r->fetchRow(); + return $row != null; + } + + public static function isRecursive($token) { + $r = self::getEntries($token); + if ($row = $r->fetchRow()) return $row['recursive'] == 1; + return false; + } + + public static function getTokenOwner($token) { + $r = self::getEntries($token); + if ($row = $r->fetchRow()) { + $galleryId = $row['gallery_id']; + $sql = 'SELECT * FROM *PREFIX*gallery_albums WHERE album_id = ?'; + $stmt = OC_DB::prepare($sql); + $r = $stmt->execute(array($galleryId)); + if ($row = $r->fetchRow()) + return $row['uid_owner']; + } + return false; + } + + public static function getPath($token) { + $r = self::getEntries($token); + if ($row = $r->fetchRow()) { + $galleryId = $row['gallery_id']; + $sql = 'SELECT * FROM *PREFIX*gallery_albums WHERE album_id = ?'; + $stmt = OC_DB::prepare($sql); + $r = $stmt->execute(array($galleryId)); + if ($row = $r->fetchRow()) + return $row['album_path']; + } + } + + public static function updateSharingByToken($token, $recursive) { + $stmt = OC_DB::prepare('UPDATE *PREFIX*gallery_sharing SET recursive = ? WHERE token = ?'); + $stmt->execute(array($recursive, $token)); + } + + public static function getEntryByAlbumId($album_id) { + $stmt = OC_DB::prepare('SELECT * FROM *PREFIX*gallery_sharing WHERE gallery_id = ?'); + return $stmt->execute(array($album_id)); + } + + public static function addShared($token, $albumId, $recursive) { + $sql = 'INSERT INTO *PREFIX*gallery_sharing (token, gallery_id, recursive) VALUES (?, ?, ?)'; + $stmt = OC_DB::prepare($sql); + $stmt->execute(array($token, $albumId, $recursive)); + } + + public static function remove($albumId) { + $stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_sharing WHERE gallery_id = ?'); + $stmt->execute(array($albumId)); + } +} + diff --git a/apps/gallery/sharing.php b/apps/gallery/sharing.php new file mode 100644 index 00000000000..d7430becf43 --- /dev/null +++ b/apps/gallery/sharing.php @@ -0,0 +1,47 @@ +<?php + +/** +* ownCloud - gallery application +* +* @author Bartek Przybylski +* @copyright 2012 Bartek Przybylski bartek@alefzero.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 Lesser General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +if (!isset($_GET['token']) || empty($_GET['token'])) { + exit; +} + +require_once('../../lib/base.php'); + +OC_Util::checkAppEnabled('gallery'); + +?> +<!doctype html> +<html> + <head> + <link rel="stylesheet" href="css/sharing.css" type="text/css"/> + <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> + <script src="js/sharing.js" type="text/javascript"></script> + <script> + var TOKEN = '<?php echo $_GET['token']; ?>'; + </script> + </head> + <body> + <div id="breadcrumb"><span class="breadcrumbelement" onclick="javascript:returnTo(0);return false;">Shared gallery</span></div> + <div id="gallery_list"></div> + </body> +</html> diff --git a/apps/gallery/templates/index.php b/apps/gallery/templates/index.php index dc5852733bd..c6373d3b0a2 100644 --- a/apps/gallery/templates/index.php +++ b/apps/gallery/templates/index.php @@ -14,7 +14,8 @@ $l = new OC_L10N('gallery'); <div id="scan"> <div id="scanprogressbar"></div> <input type="button" class="start" value="<?php echo $l->t('Rescan');?>" onclick="javascript:scanForAlbums();" /> - <input type="button" class="stop" style="display:none" value="<?php echo $l->t('Stop');?>" onclick="javascript:Scanner.stop();" /> + <input type="button" class="stop" style="display:none" value="<?php echo $l->t('Stop');?>" onclick="javascript:Scanner.stop();" /> + <input type="button" id="g-share-button" value="<?php echo $l->t('Share'); ?>" onclick="javascript:shareGallery();" /> <input type="button" id="g-settings-button" value="<?php echo $l->t('Settings');?>" onclick="javascript:settings();"/> </div> <div id="g-album-navigation"> |