summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorGeorg Ehrke <dev@georgswebsite.de>2012-03-25 14:02:40 +0200
committerGeorg Ehrke <dev@georgswebsite.de>2012-03-25 14:02:40 +0200
commitac0c5ba6daf5ffe84088571ea307f5223bd1049a (patch)
treec1d51a3f52832dc11cd2648c35edb93e47c148fc /apps
parent8e8c4a8edc630ff833361c067da5e0d30e94c6d1 (diff)
parent34c08b3165ff7ee024006b4c425130fde057863c (diff)
downloadnextcloud-server-ac0c5ba6daf5ffe84088571ea307f5223bd1049a.tar.gz
nextcloud-server-ac0c5ba6daf5ffe84088571ea307f5223bd1049a.zip
Merge branch 'master' into sabredav_1.6
Diffstat (limited to 'apps')
-rw-r--r--apps/bookmarks/bookmarksHelper.php7
-rw-r--r--apps/bookmarks/js/bookmarks.js6
-rwxr-xr-xapps/calendar/ajax/events.php6
-rw-r--r--apps/files_remote/appinfo/app.php2
-rw-r--r--apps/files_remote/lib/google.php409
-rw-r--r--apps/files_remote/lib/webdav.php293
-rw-r--r--apps/files_remote/tests/config.php13
-rw-r--r--apps/files_remote/tests/ftp.php5
-rw-r--r--apps/files_remote/tests/google.php38
-rw-r--r--apps/files_remote/tests/webdav.php23
-rw-r--r--apps/gallery/ajax/galleryOp.php44
-rw-r--r--apps/gallery/ajax/sharing.php115
-rw-r--r--apps/gallery/appinfo/app.php1
-rw-r--r--apps/gallery/appinfo/database.xml24
-rw-r--r--apps/gallery/css/sharing.css8
-rw-r--r--apps/gallery/css/styles.css2
-rw-r--r--apps/gallery/img/breadcrumb.pngbin0 -> 220 bytes
-rw-r--r--apps/gallery/index.php5
-rw-r--r--apps/gallery/js/album_cover.js50
-rw-r--r--apps/gallery/js/albums.js11
-rw-r--r--apps/gallery/js/sharing.js57
-rw-r--r--apps/gallery/lib/album.php2
-rw-r--r--apps/gallery/lib/photo.php5
-rw-r--r--apps/gallery/lib/sharing.php89
-rw-r--r--apps/gallery/sharing.php47
-rw-r--r--apps/gallery/templates/index.php3
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
new file mode 100644
index 00000000000..a252a751554
--- /dev/null
+++ b/apps/gallery/img/breadcrumb.png
Binary files differ
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">