Page MenuHomePhorge

No OneTemporary

diff --git a/lib/api/folder_list.php b/lib/api/folder_list.php
index c3e9d9f..92a4fe0 100644
--- a/lib/api/folder_list.php
+++ b/lib/api/folder_list.php
@@ -1,154 +1,156 @@
<?php
/*
+--------------------------------------------------------------------------+
| This file is part of the Kolab File API |
| |
| Copyright (C) 2012-2014, Kolab Systems AG |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU Affero General Public License as published |
| by the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program 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 program. If not, see <http://www.gnu.org/licenses/> |
+--------------------------------------------------------------------------+
| Author: Aleksander Machniak <machniak@kolabsys.com> |
+--------------------------------------------------------------------------+
*/
class file_api_folder_list extends file_api_common
{
/**
* Request handler
*/
public function handle()
{
parent::handle();
$params = $this->folder_list_params();
$search = isset($params['search']) ? mb_strtoupper($params['search']) : null;
$drivers = $this->api->get_drivers(true, $this->admin_drivers);
$errors = array();
$has_more = false;
if (isset($this->args['folder']) && strlen($this->args['folder'])) {
list($driver, $path) = $this->api->get_driver($this->args['folder']);
$title = $driver->title();
$params['path'] = $path;
try {
$folders = $this->folder_list($driver, $params, true);
}
catch (Exception $e) {
$folders = array();
if ($e->getCode() == file_storage::ERROR_NOAUTH) {
if (!in_array($title, $this->admin_drivers)) {
// inform UI about to ask user for credentials
$errors[$title] = $this->parse_metadata($driver->driver_metadata());
}
else {
$errors[$title] = array('error' => file_storage::ERROR_NOAUTH);
}
}
}
$drivers = array();
}
else {
$backend = $this->api->get_backend();
// get folders from default driver
if (!$this->rc->config->get('fileapi_backend_storage_disabled')) {
$folders = $this->folder_list($backend, $params);
+ } else {
+ $folders = array();
}
}
// old result format
if ($this->api->client_version() < 2) {
return $folders;
}
// get folders from external sources
foreach ($drivers as $driver) {
$title = $driver->title();
$prefix = $title . file_storage::SEPARATOR;
// folder exists in main source, replace it with external one
foreach ($folders as $idx => $folder) {
if (is_array($folder)) {
$folder = $folder['folder'];
}
if ($folder == $title || strpos($folder, $prefix) === 0) {
unset($folders[$idx]);
}
}
if ($search === null || strpos(mb_strtoupper($title), $search) !== false) {
if ($folder = $this->driver_root_folder($driver, $params)) {
$has_more = $has_more || count($folders) > 0;
$folders[] = $folder;
}
}
if ($driver != $backend && $params['level'] != 1) {
try {
$_folders = $this->folder_list($driver, $params);
if (!empty($_folders)) {
$folders = array_merge($folders, $_folders);
$has_more = true;
unset($_folders);
}
}
catch (Exception $e) {
if ($e->getCode() == file_storage::ERROR_NOAUTH) {
if (!in_array($title, $this->admin_drivers)) {
// inform UI about to ask user for credentials
$errors[$title] = $this->parse_metadata($driver->driver_metadata());
}
else {
$errors[$title] = array('error' => file_storage::ERROR_NOAUTH);
}
}
}
}
}
// re-sort the list
if ($has_more) {
usort($folders, array('file_utils', 'sort_folder_comparator'));
}
return array(
'list' => array_values($folders),
'auth_errors' => $errors,
);
}
protected function driver_root_folder($driver, $params)
{
$title = $driver->title();
$folder = $params['extended'] ? array('folder' => $title) : $title;
if ($params['permissions'] || ($params['type'] & file_storage::FILTER_WRITABLE)) {
if ($readonly = !($driver->folder_rights('') & file_storage::ACL_WRITE)) {
if ($params['permissions']) {
$folder['readonly'] = true;
}
}
}
else {
$readonly = false;
}
if (!$readonly || !($params['type'] & file_storage::FILTER_WRITABLE)) {
return $folder;
}
}
}
diff --git a/lib/drivers/seafile/seafile_api.php b/lib/drivers/seafile/seafile_api.php
index 0f14a21..3ee3fff 100644
--- a/lib/drivers/seafile/seafile_api.php
+++ b/lib/drivers/seafile/seafile_api.php
@@ -1,1404 +1,1406 @@
<?php
/*
+--------------------------------------------------------------------------+
| This file is part of the Kolab File API |
| |
| Copyright (C) 2012-2014, Kolab Systems AG |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU Affero General Public License as published |
| by the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program 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 program. If not, see <http://www.gnu.org/licenses/> |
+--------------------------------------------------------------------------+
| Author: Aleksander Machniak <machniak@kolabsys.com> |
+--------------------------------------------------------------------------+
*/
/**
* Class implementing access via SeaFile Web API v2
*/
class seafile_api
{
const STATUS_OK = 200;
const CREATED = 201;
const ACCEPTED = 202;
const MOVED_PERMANENTLY = 301;
const BAD_REQUEST = 400;
const FORBIDDEN = 403;
const NOT_FOUND = 404;
const CONFLICT = 409;
const TOO_MANY_REQUESTS = 429;
const REPO_PASSWD_REQUIRED = 440;
const REPO_PASSWD_MAGIC_REQUIRED = 441;
const INTERNAL_SERVER_ERROR = 500;
const OPERATION_FAILED = 520;
const CONNECTION_ERROR = 550;
private $status = null;
/**
* Specifies how long max. we'll wait and renew throttled request (in seconds)
*/
const WAIT_LIMIT = 30;
/**
* Configuration
*
* @var array
*/
protected $config = array();
/**
* HTTP request handle
*
* @var HTTP_Request
*/
protected $request;
/**
* Web API URI prefix
*
* @var string
*/
protected $url;
/**
* Session token
*
* @var string
*/
protected $token;
/**
* API URL prefix (schema and host[:port])
*
* @var string
*/
protected $url_prefix;
public function __construct($config = array())
{
$this->config = $config;
$this->token = $config['token'];
// set Web API URI
$this->url = rtrim(trim($config['host']), '/') ?: 'localhost';
if (!preg_match('|^https?://|i', $this->url)) {
$this->url = 'https://' . $this->url;
}
if (!preg_match('|/api2$|', $this->url)) {
$this->url .= '/api2/';
}
$this->url_prefix = preg_replace('|^(https?://[^/]+).*$|i', '\\1', $this->url);
}
/**
*
* @param array Configuration for this Request instance, that will be merged
* with default configuration
*
* @return HTTP_Request2 Request object
*/
public static function http_request($config = array())
{
// remove unknown config, otherwise HTTP_Request will throw an error
$config = array_intersect_key($config, array_flip(array(
'connect_timeout', 'timeout', 'use_brackets', 'protocol_version',
'buffer_size', 'store_body', 'follow_redirects', 'max_redirects',
'strict_redirects', 'ssl_verify_peer', 'ssl_verify_host',
'ssl_cafile', 'ssl_capath', 'ssl_local_cert', 'ssl_passphrase'
)));
// force CURL adapter, this allows to handle correctly
// compressed responses with simple SplObserver registered
$config['adapter'] = 'HTTP_Request2_Adapter_Curl';
try {
$request = new HTTP_Request2();
$request->setConfig($config);
}
catch (Exception $e) {
rcube::raise_error($e, true, false);
return;
}
return $request;
}
/**
* Send HTTP request
*
* @param string $method Request method ('OPTIONS','GET','HEAD','POST','PUT','DELETE','TRACE','CONNECT')
* @param string $url Request API URL
* @param array $get GET parameters
* @param array $post POST parameters
* @param array $upload Uploaded files data
* @param string $version API version (to replace "api2" with "api/v$version" in the URL
*
* @return string|array Server response
*/
protected function request($method, $url, $get = null, $post = null, $upload = null, $version = null)
{
if (!preg_match('/^https?:\/\//', $url)) {
$url = $this->url . $url;
// Note: It didn't work for me without the last backslash
$url = rtrim($url, '/') . '/';
}
else {
$url = $this->mod_url($url);
}
if ($version && $version != 2) {
$url = str_replace('/api2/', "/api/v$version/", $url);
}
if (!$this->request) {
$this->config['store_body'] = true;
// some methods respond with 301 redirect, we'll not follow them
// also because of https://github.com/haiwen/seahub/issues/288
$this->config['follow_redirects'] = false;
$this->request = self::http_request($this->config);
if (!$this->request) {
$this->status = self::CONNECTION_ERROR;
return;
}
}
// cleanup
try {
$this->request->setBody('');
$this->request->setUrl($url);
}
catch (Exception $e) {
rcube::raise_error($e, true, false);
$this->status = self::CONNECTION_ERROR;
return;
}
if ($this->config['debug']) {
$log_line = "SeaFile $method: $url";
$json_opt = PHP_VERSION_ID >= 50400 ? JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE : 0;
if (!empty($get)) {
$log_line .= ", GET: " . @json_encode($get, $json_opt);
}
if (!empty($post)) {
$log_line .= ", POST: " . preg_replace('/("password":)[^\},]+/', '\\1"*"', @json_encode($post, $json_opt));
}
if (!empty($upload)) {
$log_line .= ", Files: " . @json_encode(array_keys($upload), $json_opt);
}
rcube::write_log('console', $log_line);
}
$this->request->setMethod($method ?: HTTP_Request2::METHOD_GET);
if (!empty($get)) {
$_url = $this->request->getUrl();
$_url->setQueryVariables($get);
$this->request->setUrl($_url);
}
// HTTP_Request2 does not support POST params on PUT requests
if (!empty($post) && $method == 'PUT') {
$body = http_build_query($post, '', '&');
$body = str_replace('%7E', '~', $body); // support RFC 3986 by not encoding '~' symbol
$post = null;
$this->request->setBody($body);
$this->request->setHeader('content-type', 'application/x-www-form-urlencoded');
}
if (!empty($post)) {
$this->request->addPostParameter($post);
}
if (!empty($upload)) {
foreach ($upload as $field_name => $file) {
$this->request->addUpload($field_name, $file['data'], $file['name'], $file['type']);
}
}
if ($this->token) {
$this->request->setHeader('Authorization', "Token " . $this->token);
}
// some HTTP server configurations require this header
$this->request->setHeader('Accept', "application/json,text/javascript,*/*");
// proxy User-Agent string
$this->request->setHeader('User-Agent', $_SERVER['HTTP_USER_AGENT']);
// send request to the SeaFile API server
try {
$response = $this->request->send();
$this->status = $response->getStatus();
$body = $response->getBody();
}
catch (Exception $e) {
rcube::raise_error($e, true, false);
$this->status = self::CONNECTION_ERROR;
}
if ($this->config['debug']) {
rcube::write_log('console', "SeaFile Response [$this->status]: " . trim($body));
}
// request throttled, try again
if ($this->status == self::TOO_MANY_REQUESTS) {
if (preg_match('/([0-9]+) second/', $body, $m) && ($seconds = $m[1]) < self::WAIT_LIMIT) {
sleep($seconds);
return $this->request($method, $url, $get, $post, $upload);
}
}
if ($this->status < 400) {
$body = @json_decode($body, true);
}
// Sometimes we can get an error with response code 200
if ($this->status == 200
&& ($method == 'PUT' || $method == 'POST')
&& !empty($body) && is_array($body) && !empty($body['failed']) && empty($body['success'])
) {
// Note: $body['failed'] is an array where each element is an array with 'error_msg' item
// TODO: Support partial success/error result
$this->status = 520;
}
// decode response
return $this->status >= 400 ? false : $body;
}
/**
* Return error code of last operation
*/
public function is_error()
{
return $this->status >= 400 ? $this->status : false;
}
/**
* Authenticate to SeaFile API and get auth token
*
* @param string $username User name (email)
* @param string $password User password
*
* @return string|null Authentication token
*/
public function authenticate($username, $password)
{
// sanity checks
if ($username === '' || !is_string($username) || $password === '' || !is_string($password)) {
$this->status = self::BAD_REQUEST;
return false;
}
$result = $this->request('POST', 'auth-token', null, array(
'username' => $username,
'password' => $password,
));
if ($result['token']) {
return $this->token = $result['token'];
}
}
/**
* Get account information
*
* @return array Account info (usage, total, email)
*/
public function account_info()
{
return $this->request('GET', "account/info");
}
/**
* Delete a directory
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
*
* @return bool True on success, False on failure
*/
public function directory_delete($repo_id, $dir)
{
// sanity checks
if ($dir === '' || $dir === '/' || !is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
$this->request('DELETE', "repos/$repo_id/dir", array('p' => $dir));
return $this->is_error() === false;
}
/**
* Rename a directory
*
* @param string $repo_id Library identifier
* @param string $src_dir Directory name (with path)
* @param string $dest_dir New directory name (with path)
*
* @return bool True on success, False on failure
*/
public function directory_rename($repo_id, $src_dir, $dest_dir)
{
// sanity checks
if ($src_dir === '' || $src_dir === '/' || !is_string($src_dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dest_dir === '' || $dest_dir === '/' || !is_string($dest_dir) || $dest_dir === $src_dir) {
$this->status = self::BAD_REQUEST;
return false;
}
$result = $this->request('POST', "repos/$repo_id/dir", array('p' => $src_dir), array(
'operation' => 'rename',
'newname' => $dest_dir,
));
return $this->is_error() === false;
}
/**
* Rename a directory
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
*
* @return bool True on success, False on failure
*/
public function directory_create($repo_id, $dir)
{
// sanity checks
if ($dir === '' || $dir === '/' || !is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
$result = $this->request('POST', "repos/$repo_id/dir", array('p' => $dir), array(
'operation' => 'mkdir',
));
return $this->is_error() === false;
}
/**
* List directory entries (files and directories)
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
* @param string $type Entry type ('dir' or 'file') (requires Seafile 4.4.1)
* @param bool $recursive Enable recursive call for 'dir' listing (requires Seafile 4.4.1)
*
* @return bool|array List of directories/files on success, False on failure
*/
public function directory_entries($repo_id, $dir, $type = null, $recursive = false)
{
// sanity checks
if (!is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dir === '') {
$dir = '/';
}
// args: p=<$name> ('/' is a root, default), oid=?
// sample result
// [{
// "id": "0000000000000000000000000000000000000000",
// "type": "file",
// "name": "test1.c",
// "size": 0
// },{
// "id": "e4fe14c8cda2206bb9606907cf4fca6b30221cf9",
// "type": "dir",
// "name": "test_dir"
// }]
$params = array('p' => $dir);
if ($type) {
$params['t'] = $type == 'dir' ? 'd' : 'f';
}
if ($recursive && $type == 'dir') {
$params['recursive'] = 1;
}
return $this->request('GET', "repos/$repo_id/dir", $params);
}
/**
* Get directory information.
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
*
* @return bool|array Directory properties on success, False on failure
*/
public function directory_info($repo_id, $dir)
{
// sanity checks
if (!is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
$params = array('path' => $dir);
return $this->request('GET', "repos/$repo_id/dir/detail", $params, null, null, '2.1');
}
/**
* Update a file
*
* @param string $repo_id Library identifier
* @param string $filename File name (with path)
* @param array $file File data (data, type, name)
*
* @return bool True on success, False on failure
*/
public function file_update($repo_id, $filename, $file)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
// first get the update link
$result = $this->request('GET', "repos/$repo_id/update-link");
if ($this->is_error() || empty($result)) {
return false;
}
$path = explode('/', $filename);
$fn = array_pop($path);
// then update file
$result = $this->request('POST', $result, null, array(
'filename' => $fn,
'target_file' => $filename,
),
array('file' => $file)
);
return $this->is_error() === false;
}
/**
* Upload a file
*
* @param string $repo_id Library identifier
* @param string $filename File name (with path)
* @param array $file File data (data, type, name)
*
* @return bool True on success, False on failure
*/
public function file_upload($repo_id, $filename, $file)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
// first get upload link
- $result = $this->request('GET', "repos/$repo_id/upload-link");
+ $parent_dir = '/';
+ $result = $this->request('GET', "repos/$repo_id/upload-link/?p=$parent_dir");
if ($this->is_error() || empty($result)) {
return false;
}
$path = explode('/', $filename);
$filename = array_pop($path);
- $dir = '/' . ltrim(implode('/', $path), '/');
+ $dir = ltrim(implode('/', $path), '/');
$file['name'] = $filename;
// then update file
$result = $this->request('POST', $result, null, array(
- 'parent_dir' => $dir
+ 'parent_dir' => $parent_dir,
+ 'relative_path' => $dir
),
array('file' => $file)
);
return $this->is_error() === false;
}
/**
* Delete a file
*
* @param string $repo_id Library identifier
* @param string $filename File name (with path)
*
* @return bool True on success, False on failure
*/
public function file_delete($repo_id, $filename)
{
// sanity check
if ($filename === '' || $filename === '/' || !is_string($filename)) {
$this->status = self::BAD_REQUEST;
return false;
}
$this->request('DELETE', "repos/$repo_id/file", array('p' => $filename));
return $this->is_error() === false;
}
/**
* Copy file(s) (no rename here)
*
* @param string $repo_id Library identifier
* @param string|array $files List of files (without path)
* @param string $src_dir Source directory
* @param string $dest_dir Destination directory
* @param string $dest_repo Destination library (optional)
*
* @return bool True on success, False on failure
*/
public function file_copy($repo_id, $files, $src_dir, $dest_dir, $dest_repo)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($src_dir === '' || !is_string($src_dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dest_dir === '' || !is_string($dest_dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ((!is_array($files) && !strlen($files)) || (is_array($files) && empty($files))) {
$this->status = self::BAD_REQUEST;
return false;
}
if (empty($dest_repo)) {
$dest_repo = $repo_id;
}
$result = $this->request('POST', "repos/$repo_id/fileops/copy", array('p' => $src_dir), array(
'file_names' => implode(':', (array) $files),
'dst_dir' => $dest_dir,
'dst_repo' => $dest_repo,
));
return $this->is_error() === false;
}
/**
* Move a file (no rename here)
*
* @param string $repo_id Library identifier
* @param string $filename File name (with path)
* @param string $dst_dir Destination directory
* @param string $dst_repo Destination library (optional)
*
* @return bool True on success, False on failure
*/
public function file_move($repo_id, $filename, $dst_dir, $dst_repo = null)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($filename === '' || !is_string($filename)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dst_dir === '' || !is_string($dst_dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if (empty($dst_repo)) {
$dst_repo = $repo_id;
}
$result = $this->request('POST', "repos/$repo_id/file", array('p' => $filename), array(
'operation' => 'move',
'dst_dir' => $dst_dir,
'dst_repo' => $dst_repo,
));
return $this->is_error() === false;
}
/**
* Rename a file
*
* @param string $repo_id Library identifier
* @param string $filename File name (with path)
* @param string $new_name New file name (without path)
*
* @return bool True on success, False on failure
*/
public function file_rename($repo_id, $filename, $new_name)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($filename === '' || !is_string($filename)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($new_name === '' || !is_string($new_name)) {
$this->status = self::BAD_REQUEST;
return false;
}
$result = $this->request('POST', "repos/$repo_id/file", array('p' => $filename), array(
'operation' => 'rename',
'newname' => $new_name,
));
return $this->is_error() === false;
}
/**
* Create an empty file
*
* @param string $repo_id Library identifier
* @param string $filename File name (with path)
*
* @return bool True on success, False on failure
*/
public function file_create($repo_id, $filename)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($filename === '' || !is_string($filename)) {
$this->status = self::BAD_REQUEST;
return false;
}
$result = $this->request('POST', "repos/$repo_id/file", array('p' => $filename), array(
'operation' => 'create',
));
return $this->is_error() === false;
}
/**
* Get file info
*
* @param string $repo_id Library identifier
* @param string $filename File name (with path)
*
* @return bool|array File info on success, False on failure
*/
public function file_info($repo_id, $filename)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($filename === '' || !is_string($filename)) {
$this->status = self::BAD_REQUEST;
return false;
}
// sample result:
// "id": "013d3d38fed38b3e8e26b21bb3463eab6831194f",
// "mtime": 1398148877,
// "type": "file",
// "name": "foo.py",
// "size": 22
return $this->request('GET', "repos/$repo_id/file/detail", array('p' => $filename));
}
/**
* Get file content
*
* @param string $repo_id Library identifier
* @param string $filename File name (with path)
*
* @return bool|string File download URI on success, False on failure
*/
public function file_get($repo_id, $filename)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($filename === '' || !is_string($filename)) {
$this->status = self::BAD_REQUEST;
return false;
}
return $this->request('GET', "repos/$repo_id/file", array('p' => $filename));
}
/**
* List libraries (repositories)
*
* @return array|bool List of libraries on success, False on failure
*/
public function library_list()
{
$result = $this->request('GET', "repos");
// sample result
// [{
// "permission": "rw",
// "encrypted": false,
// "mtime": 1400054900,
// "owner": "user@mail.com",
// "id": "f158d1dd-cc19-412c-b143-2ac83f352290",
// "size": 0,
// "name": "foo",
// "type": "repo",
// "virtual": false,
// "desc": "new library",
// "root": "0000000000000000000000000000000000000000"
// }]
return $result;
}
/**
* Get library info
*
* @param string $repo_id Library identifier
*
* @return array|bool Library info on success, False on failure
*/
public function library_info($repo_id)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
return $this->request('GET', "repos/$repo_id");
}
/**
* Create library
*
* @param string $name Library name
* @param string $description Library description
*
* @return bool|array Library info on success, False on failure
*/
public function library_create($name, $description = '')
{
if ($name === '' || !is_string($name)) {
$this->status = self::BAD_REQUEST;
return false;
}
return $this->request('POST', "repos", null, array(
'name' => $name,
'desc' => $description,
));
}
/**
* Rename library
*
* @param string $repo_id Library identifier
* @param string $new_name Library description
*
* @return bool True on success, False on failure
*/
public function library_rename($repo_id, $name, $description = '')
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($name === '' || !is_string($name)) {
$this->status = self::BAD_REQUEST;
return false;
}
// Note: probably by mistake the 'op' is a GET parameter
// maybe changed in future to be consistent with other methods
$this->request('POST', "repos/$repo_id", array('op' => 'rename'), array(
'repo_name' => $name,
'repo_desc' => $description,
));
return $this->is_error() === false;
}
/**
* Delete library
*
* @param string $repo_id Library identifier
*
* @return bool True on success, False on failure
*/
public function library_delete($repo_id)
{
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
$this->request('DELETE', "repos/$repo_id");
return $this->is_error() === false;
}
/**
* Ping the API server
*
* @param string $token If set, auth token will be used
*
* @param bool True on success, False on failure
*/
public function ping($token = null)
{
// can be used to check if token is still valid
if ($token) {
$this->token = $token;
$result = $this->request('GET', 'auth/ping', null, null);
}
// or if api works
else {
$result = $this->request('GET', 'ping', null, null);
}
return $this->is_error() === false;
}
/**
* Share a directory (or library)
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
* @param string $right Permission ('r' or 'rw' or 'admin')
* @param string $mode Mode ('user' or 'group')
* @param string $who Username or Group ID
* @param bool $update Update an existing entry
*
* @return bool True on success, False on failure
*/
public function shared_item_add($repo_id, $dir, $right, $mode, $who, $update = false)
{
// sanity checks
if (!is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($mode != 'user' && $mode != 'group') {
$this->status = self::BAD_REQUEST;
return false;
}
if ($right != 'r' && $right != 'rw' && $right != 'admin') {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dir === '') {
$dir = '/';
}
$post = array(
'permission' => $right,
'share_type' => $mode,
);
$post[$mode == 'group' ? 'group_id' : 'username'] = $who;
$this->request($update ? 'POST' : 'PUT', "repos/$repo_id/dir/shared_items", array('p' => $dir), $post);
return $this->is_error() === false;
}
/**
* Update shared item permissions
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
* @param string $right Permission ('r' or 'rw' or 'admin')
* @param string $mode Mode ('user' or 'group')
* @param string $who Username or Group ID
*
* @return bool True on success, False on failure
*/
public function shared_item_update($repo_id, $dir, $right, $mode, $who)
{
return $this->shared_item_add($repo_id, $dir, $right, $mode, $who, true);
}
/**
* Un-Share a directory (or library)
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
* @param string $mode Mode ('user' or 'group')
* @param string $who Username or Group ID
*
* @return bool True on success, False on failure
*/
public function shared_item_delete($repo_id, $dir, $mode, $who)
{
// sanity checks
if (!is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($mode != 'user' && $mode != 'group') {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dir === '') {
$dir = '/';
}
$get = array(
'share_type' => $mode,
'p' => $dir
);
$get[$mode == 'group' ? 'group_id' : 'username'] = $who;
$this->request('DELETE', "repos/$repo_id/dir/shared_items", $get);
return $this->is_error() === false;
}
/**
* List directory permissions (shares)
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
*
* @return bool|array List of user/group info on success, False on failure
*/
public function shared_item_list($repo_id, $dir)
{
// sanity checks
if (!is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dir === '') {
$dir = '/';
}
// Example result:
// [
// {
// "group_info": { "id": 17, "name": "Group Name" },
// "is_admin": false,
// "share_type": "group",
// "permission": "rw"
// },
// {
// "user_info": { "nickname": "user", "name": "user@domain.com" },
// "share_type": "user",
// "permission": "r"
// }
// ]
return $this->request('GET', "repos/$repo_id/dir/shared_items", array('p' => $dir));
}
/**
* List share (download) links
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
*
* @return bool|array List of shared links on success, False on failure
*/
public function share_link_list($repo_id, $dir)
{
// sanity checks
if (!is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dir === '') {
$dir = '/';
}
// Example result:
// [
// {
// "username": "lian@lian.com",
// "repo_id": "104f6537-b3a5-4d42-b8b5-8e47e494e4cf",
// "ctime": "2017-04-01T02:35:29+00:00",
// "expire_date": "",
// "token": "0c4eb0cb104a43caaeef",
// "view_cnt": 0,
// "link": "https://cloud.seafile.com/d/0c4eb0cb104a43caaeef/",
// "obj_name": "folder",
// "path": "/folder/",
// "is_dir": true,
// "is_expired": false,
// "repo_name": "for-test-web-api"
// }
// ]
return $this->request('GET', "share-links", array('repo_id' => $repo_id, 'path' => $dir), null, null, '2.1');
}
/**
* Create a shared (download) link
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
* @param string $password Password
* @param string $expire Days to expire
*
* @return bool Link info on success, False on failure
*/
public function share_link_add($repo_id, $dir, $password = '', $expire = 0)
{
// sanity checks
if (!is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if (!empty($expire) && !is_numeric($expire)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dir === '') {
$dir = '/';
}
$post = array(
'repo_id' => $repo_id,
'path' => $dir,
);
if (strlen($password)) {
$post['password'] = $password;
}
if ($expire > 0) {
$post['expire_days'] = $expire;
}
$result = $this->request('POST', "share-links", array(), $post, null, '2.1');
// Sample response:
// {
// "token": "0c4eb0cb104a43caaeef",
// "link": "https://cloud.seafile.com/d/db1a50e686/",
// ...
// }
if (is_array($result) && !empty($result['link'])) {
return $result;
}
return false;
}
/**
* Delete a share (download) link
*
* @param string $token Link identifier (token)
*
* @return bool True on success, False on failure
*/
public function share_link_delete($token)
{
// sanity checks
if ($token === '' || !is_string($token)) {
$this->status = self::BAD_REQUEST;
return false;
}
$this->request('DELETE', "share-links/{$token}", null, null, null, '2.1');
return $this->is_error() === false;
}
/**
* List upload links
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
*
* @return bool|array List of upload links on success, False on failure
*/
public function upload_link_list($repo_id, $dir)
{
// sanity checks
if (!is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dir === '') {
$dir = '/';
}
// Example result:
// [
// {
// "username": "lian@lian.com",
// "repo_id": "104f6537-b3a5-4d42-b8b5-8e47e494e4cf",
// "ctime": "2017-04-01T02:35:29+00:00",
// "expire_date": "",
// "token": "0c4eb0cb104a43caaeef",
// "view_cnt": 0,
// "link": "https://cloud.seafile.com/d/0c4eb0cb104a43caaeef/",
// "obj_name": "folder",
// "path": "/folder/",
// "is_dir": true,
// "is_expired": false,
// "repo_name": "for-test-web-api"
// }
// ]
return $this->request('GET', "upload-links", array('repo_id' => $repo_id, 'path' => $dir), null, null, '2.1');
}
/**
* Create an upload link
*
* @param string $repo_id Library identifier
* @param string $dir Directory name (with path)
* @param string $password Password
*
* @return bool Link info on success, False on failure
*/
public function upload_link_add($repo_id, $dir, $password = '')
{
// sanity checks
if (!is_string($dir)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($repo_id === '' || !is_string($repo_id)) {
$this->status = self::BAD_REQUEST;
return false;
}
if ($dir === '') {
$dir = '/';
}
$post = array(
'repo_id' => $repo_id,
'path' => $dir,
);
if (strlen($password)) {
$post['password'] = $password;
}
$result = $this->request('POST', "upload-links", array(), $post, null, '2.1');
// Sample response:
// {
// "token": "0c4eb0cb104a43caaeef",
// "link": "https://cloud.seafile.com/d/db1a50e686/",
// ...
// }
if (is_array($result) && !empty($result['link'])) {
return $result;
}
return false;
}
/**
* Delete an upload link
*
* @param string $token Link identifier (token)
*
* @return bool True on success, False on failure
*/
public function upload_link_delete($token)
{
// sanity checks
if ($token === '' || !is_string($token)) {
$this->status = self::BAD_REQUEST;
return false;
}
$this->request('DELETE', "upload-links/{$token}", null, null, null, '2.1');
return $this->is_error() === false;
}
/**
* List user groups
*
* @return bool|array List of groups on success, False on failure
*/
public function group_list()
{
// Sample result:
// [
// {
// "ctime": 1398134171327948,
// "creator": "user@example.com",
// "msgnum": 0,
// "mtime": 1398231100,
// "id": 1,
// "name": "lian"
// }
// ] },
$result = $this->request('GET', "groups");
if (is_array($result)) {
$result = (array) $result['groups'];
}
return $result;
}
/**
* List users
*
* @param string $search Search keyword
*
* @return bool|array List of users on success, False on failure
*/
public function user_search($search = null)
{
// Sample response:
// [
// {
// 'avatar_url': 'https://cloud.seafile.com/media/avatars/default.png',
// 'contact_email': 'foo@foo.com',
// 'email': 'foo@foo.com',
// 'name': 'foo'
// }
// ]
$result = $this->request('GET', "search-user", array('q' => $search));
if (is_array($result)) {
$result = (array) $result['users'];
}
return $result;
}
/**
* Parse and fix API request URLs
*/
public function mod_url($url)
{
// If Seafile is behind a proxy and different port, it will return
// wrong URL for file uploads/downloads. We force the original URL prefix here
if (stripos($url, $this->url_prefix) !== 0) {
$url = $this->url_prefix . preg_replace('|^(https?://[^/]+)|i', '', $url);
}
return $url;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Oct 1, 5:16 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
54526
Default Alt Text
(48 KB)

Event Timeline