Projects
Kolab:Winterfell
chwala
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 2
View file
chwala.spec
Changed
@@ -32,7 +32,7 @@ Name: chwala Version: 0.4 -Release: 0.20160122.git%{?dist} +Release: 0.20160210.git%{?dist} Summary: Glorified WebDAV, done right Group: Applications/Internet
View file
chwala-0.4.tar.gz/lib/api/common.php
Changed
@@ -163,4 +163,20 @@ return $result; } + + /** + * Update manticore session on file/folder move + */ + protected function session_uri_update($from, $to, $is_folder = false) + { + // check Manticore support. Note: we don't use config->get('fileapi_manticore') + // here as it may be not properly set if backend driver wasn't initialized yet + $capabilities = $this->api->capabilities(false); + if (empty($capabilities['MANTICORE'])) { + return; + } + + $manticore = new file_manticore($this->api); + $manticore->session_uri_update($from, $to, $is_folder); + } }
View file
chwala-0.4.tar.gz/lib/api/document.php
Changed
@@ -40,8 +40,14 @@ if ($this->args['method'] == 'invitations') { return $this->invitations(); } + + // Sessions list + if ($this->args['method'] == 'sessions') { + return $this->sessions(); + } + // Session and invitations management - else if (strpos($this->args['method'], 'document_') === 0) { + if (strpos($this->args['method'], 'document_') === 0) { if ($_SERVER['REQUEST_METHOD'] == 'POST') { $post = file_get_contents('php://input'); $this->args += (array) json_decode($post, true); @@ -116,6 +122,24 @@ } /** + * Get sessions list + */ + protected function sessions() + { + $manticore = new file_manticore($this->api); + + $params = array( + 'reverse' => rcube_utils::get_boolean((string) $this->args['reverse']), + ); + + if (!empty($this->args['sort'])) { + $params['sort'] = strtolower($this->args['sort']); + } + + return $manticore->sessions_list($params); + } + + /** * Close (delete) manticore session */ protected function document_delete($id)
View file
chwala-0.4.tar.gz/lib/api/file_move.php
Changed
@@ -112,6 +112,11 @@ throw $e; } } + + // Update manticore sessions + if ($request == 'file_move') { + $this->session_uri_update($file, $new_file, false); + } } if (!empty($errors)) {
View file
chwala-0.4.tar.gz/lib/api/folder_move.php
Changed
@@ -68,10 +68,14 @@ throw new Exception("Destination folder already exists", file_api_core::ERROR_CODE); } - return $this->folder_move_to_other_driver($src_driver, $src_path, $dst_driver, $dst_path); + $this->folder_move_to_other_driver($src_driver, $src_path, $dst_driver, $dst_path); + } + else { + $src_driver->folder_move($src_path, $dst_path); } - return $src_driver->folder_move($src_path, $dst_path); + // Update manticore + $this->session_uri_update($this->args['folder'], $this->args['new'], true); } /**
View file
chwala-0.4.tar.gz/lib/file_api.php
Changed
@@ -259,7 +259,7 @@ ); // Redirect all document_* actions into 'document' action - if (preg_match('/^(invitations|document_[a-z]+)$/', $request)) { + if (preg_match('/^(sessions|invitations|document_[a-z]+)$/', $request)) { $request = 'document'; }
View file
chwala-0.4.tar.gz/lib/file_manticore.php
Changed
@@ -72,8 +72,7 @@ public function session_start($file, &$session_id = null) { if ($file !== null) { - list($driver, $path) = $this->api->get_driver($file); - $uri = $driver->path2uri($path); + $uri = $this->path2uri($file, $driver); } $backend = $this->api->get_backend(); @@ -224,9 +223,7 @@ public function session_find($path, $invitations = true) { // create an URI for specified path - list($driver, $path) = $this->api->get_driver($path); - - $uri = trim($driver->path2uri($path), '/') . '/'; + $uri = trim($this->path2uri($path), '/') . '/'; // get existing sessions $sessions = array(); @@ -322,6 +319,109 @@ } /** + * Find sessions, including: + * 1. to which the user has access (is a creator or has been invited) + * 2. to which the user is considered eligible to request authorization + * to participate in the session by already having access to the file + * + * @param array $param List parameters + * + * @return array Sessions list + */ + public function sessions_list($param = array()) + { + $db = $this->rc->get_dbh(); + $sessions = array(); + + // 1. Get sessions user has access to + $result = $db->query("SELECT s.`id`, s.`uri`, s.`owner`, s.`owner_name`" + . " FROM `{$this->sessions_table}` s" + . " WHERE s.`owner` = ? OR s.`id` IN (" + . "SELECT i.`session_id` FROM `{$this->invitations_table}` i" + . " WHERE i.`user` = ?" + . ")", + $this->user, $this->user); + + if ($db->is_error($result)) { + throw new Exception("Internal error.", file_api_core::ERROR_CODE); + } + + while ($row = $db->fetch_assoc($result)) { + if ($path = $this->uri2path($row['uri'], true)) { + $sessions[$row['id']] = $this->session_info_parse($row, $path); + // For performance reasons we don't want to fetch info of every file + // on the list. As we support only ODT files here... + $sessions[$row['id']]['type'] = 'application/vnd.oasis.opendocument.text'; + } + } + + // 2. Get sessions user is eligible + // - get list of all folder URIs and find sessions for files in these locations + // @FIXME: in corner cases (user has many folders) this may produce a big query, + // maybe fetching all sessions and then comparing with list of locations would be faster? + $uris = $this->all_folder_locations(); + $where = array_map(function($uri) use ($db) { + return 's.`uri` LIKE ' . $db->quote(str_replace('%', '_', $uri) . '/%'); + }, $uris); + + $result = $db->query("SELECT s.`id`, s.`uri`, s.`owner`, s.`owner_name`" + . " FROM `{$this->sessions_table}` s WHERE " . join(' OR ', $where)); + + if ($db->is_error($result)) { + throw new Exception("Internal error.", file_api_core::ERROR_CODE); + } + + while ($row = $db->fetch_assoc($result)) { + if (empty($sessions[$row['id']])) { + // remove filename (and anything after it) so we have the folder URI + // to check if it's on the folders list we have + $uri = substr($row['uri'], 0, strrpos($row['uri'], '/')); + if (in_array($uri, $uris) && ($path = $this->uri2path($row['uri'], true))) { + $sessions[$row['id']] = $this->session_info_parse($row, $path); + // For performance reasons we don't want to fetch info of every file + // on the list. As we support only ODT files here... + $sessions[$row['id']]['type'] = 'application/vnd.oasis.opendocument.text'; + } + } + } + + // set 'is_invited' flag + if (!empty($sessions)) { + $invitations = $this->invitations_find(array('user' => $this->user)); + $states = array(self::STATUS_INVITED, self::STATUS_ACCEPTED, self::STATUS_ACCEPTED_OWNER); + + foreach ($invitations as $invitation) { + if (!empty($sessions[$invitation['session_id']]) && in_array($invitation['status'], $states)) { + $sessions[$invitation['session_id']]['is_invited'] = true; + } + } + } + + // Sorting + $sort = !empty($params['sort']) ? $params['sort'] : 'name'; + $index = array(); + + if (in_array($sort, array('name', 'file', 'owner'))) { + foreach ($sessions as $key => $val) { + if ($sort == 'name' || $sort == 'file') { + $path = explode(file_storage::SEPARATOR, $val['file']); + $index[$key] = $path[count($path) - 1]; + continue; + } + + $index[$key] = $val[$sort]; + } + array_multisort($index, SORT_ASC, SORT_LOCALE_STRING, $sessions); + } + + if ($params['reverse']) { + $sessions = array_reverse($sessions, true); + } + + return $sessions; + } + + /** * Find invitations for current user. This will return all * invitations related to the user including his sessions. * @@ -392,7 +492,7 @@ } $result = $db->query("SELECT $select FROM `{$this->invitations_table}` i" - . "$query ORDER BY `changed`"); + . "$query ORDER BY i.`changed`"); if ($db->is_error($result)) { throw new Exception("Internal error.", file_api_core::ERROR_CODE); @@ -580,15 +680,37 @@ } /** + * Update a session URI (e.g. on file/folder move) + * + * @param string $from Source file/folder path + * @param string $to Destination file/folder path + * @param bool $is_folder True if the path is a folder + */ + public function session_uri_update($from, $to, $is_folder = false) + { + $db = $this->rc->get_dbh(); + + // Resolve paths + $from = $this->path2uri($from); + $to = $this->path2uri($to); + + if ($is_folder) { + $set = "`uri` = REPLACE(`uri`, " . $db->quote($from . '/') . ", " . $db->quote($to .'/') . ")"; + $where = "`uri` LIKE " . $db->quote(str_replace('%', '_', $from) . '/%'); + } + else { + $set = "`uri` = " . $db->quote($to); + $where = "`uri` = " . $db->quote($from); + } + + $db->query("UPDATE `{$this->sessions_table}` SET $set WHERE $where"); + } + + /** * Parse session info data */ protected function session_info_parse($record, $path = null, $filter = array()) { -/* - if (is_string($data) && !empty($data)) { - $data = json_decode($data, true); - } -*/ $session = array(); $fields = array('id', 'uri', 'owner', 'owner_name'); @@ -626,9 +748,19 @@ } /** + * Get file URI from path + */ + protected function path2uri($path, &$driver = null) + { + list($driver, $path) = $this->api->get_driver($path); + + return $driver->path2uri($path); + } + + /** * Get file path from the URI */ - protected function uri2path($uri) + protected function uri2path($uri, $use_fallback = false) { $backend = $this->api->get_backend(); @@ -654,6 +786,16 @@ // do nothing } } + + // likely user has no access to the file, but has been invited, + // extract filename from the URI + if ($use_fallback && $uri) { + $path = parse_url($uri, PHP_URL_PATH); + $path = explode('/', $path); + $path = $path[count($path) - 1]; + + return $path; + } } /** @@ -686,4 +828,33 @@ return $this->request; } + + /** + * Get URI of all user folders (with shared locations) + */ + protected function all_folder_locations() + { + $locations = array(); + + foreach (array_merge(array($this->api->get_backend()), $this->api->get_drivers(true)) as $driver) { + // Performance optimization: We're interested here in shared folders, + // Kolab is the only driver that currently supports them, ignore others + if (get_class($driver) != 'kolab_file_storage') { + continue; + } + + try { + foreach ($driver->folder_list() as $folder) { + if ($uri = $driver->path2uri($folder)) { + $locations[] = $uri; + } + } + } + catch (Exception $e) { + // do nothing + } + } + + return $locations; + } }
View file
chwala-0.4.tar.gz/lib/locale/en_US.php
Changed
@@ -41,6 +41,7 @@ $LANG['folder.driverwithpassdesc'] = 'Stored passwords will be encrypted. Enable this if you do not want to be asked for the password on every login or you want this storage to be available via WebDAV.'; $LANG['folder.name'] = 'Name:'; $LANG['folder.authenticate'] = 'Logon to $title'; +$LANG['folder.parent'] = 'Subfolder of:'; $LANG['form.submit'] = 'Submit'; $LANG['form.cancel'] = 'Cancel';
View file
chwala-0.4.tar.gz/public_html/js/files_api.js
Changed
@@ -91,7 +91,7 @@ type: 'POST', url: url, data: JSON.stringify(data), dataType: 'json', contentType: 'application/json; charset=utf-8', success: function(response) { if (typeof func == 'function') func(response); else ref[func](response); }, - error: function(o, status, err) { ref.http_error(o, status, err); }, + error: function(o, status, err) { ref.http_error(o, status, err, data); }, cache: false, beforeSend: function(xmlhttp) { xmlhttp.setRequestHeader('X-Session-Token', ref.env.token); } }); @@ -110,7 +110,7 @@ return $.ajax({ type: 'GET', url: url, data: data, dataType: 'json', success: function(response) { if (typeof func == 'function') func(response); else ref[func](response); }, - error: function(o, status, err) { ref.http_error(o, status, err); }, + error: function(o, status, err) { ref.http_error(o, status, err, data); }, cache: false, beforeSend: function(xmlhttp) { xmlhttp.setRequestHeader('X-Session-Token', ref.env.token); } }); @@ -125,7 +125,7 @@ }; // handle HTTP request errors - this.http_error = function(request, status, err) + this.http_error = function(request, status, err, data) { var errmsg = request.statusText;
View file
chwala-0.4.tar.gz/public_html/skins/default/images/mimetypes/_css.sh
Changed
@@ -72,10 +72,10 @@ $class =~ s/\.png$//; $class =~ s/[^a-z0-9_]/_/g; - $line .= "#filelist tbody td.filename." .$class . " span"; + $line .= ".filelist tbody td.filename." .$class . " span"; for my $alias (@{$aliases{$class}}) { - $line .= ",\n#filelist tbody td.filename." .$alias . " span"; + $line .= ",\n.filelist tbody td.filename." .$alias . " span"; } $line .= " {\n background: url($file) 0 0 no-repeat;\n";
View file
chwala.dsc
Changed
@@ -2,7 +2,7 @@ Source: chwala Binary: chwala Architecture: all -Version: 0.4~dev20160122-0~kolab1 +Version: 0.4~dev20160210-0~kolab1 Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Uploaders: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>, Paul Klos <kolab@klos2day.nl> Homepage: http://kolab.org/about/chwala/
View file
debian.changelog
Changed
@@ -1,4 +1,4 @@ -chwala (0.4~dev20160122-0~kolab1) unstable; urgency=low +chwala (0.4~dev20160210-0~kolab1) unstable; urgency=low * Require roundcubemail-plugin-kolab_folders and create necessary symbolic link
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.