Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F58280
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
48 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Oct 1, 5:16 AM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
54526
Default Alt Text
(48 KB)
Attached To
Mode
R26 chwala
Attached
Detach File
Event Timeline
Log In to Comment