同步算法

最后更新于:2022-04-01 02:23:48

';

服务器组件

最后更新于:2022-04-01 02:23:46

# Components of Seafile Server Seafile server comprises of the following services. - **Ccnet daemon** (ccnet for client side or ccnet-server for server side):networking service daemon. In our initial design, Ccnet worked like a traffic bus. All the network traffic between client, server and internal traffic between different components would go through Ccnet. After further development we found that file transfer is improved by utilizing the Seafile daemon component directly. - **Seafile daemon**:data service daemon - **Seahub**:the website. Seafile server package contains a light-weight Python HTTP server `gunicorn` that serves the website. Seahub runs as an application within gunicorn. - **FileServer**: handles raw file upload/download functions for Seahub. Due to Gunicorn being poor at handling large files, so we wrote this "FileServer" in the C programming language to serve raw file upload/download. - **Controller**: monitors ccnet and Seafile daemons, restarts them if necessary. **The picture below shows how Seafile desktop client syncs files with Seafile server**: ![seafile-sync-arch](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-16_55d04c438a6f9.png) **The picture below shows how Seafile mobile client interacts with Seafile server**: ![mobile-arch](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-16_55d04c43976b8.png) **The picture below shows how Seafile mobile client interacts with Seafile server if the server is configured behind Nginx/Apache**: ![mobile-nginx-arch](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-16_55d04c43a4a1a.png)
';

数据模型

最后更新于:2022-04-01 02:23:43

# Data Model Seafile internally uses a data model similar to GIT's. It consists of `Repo`, `Branch`, `Commit`, `FS`, and `Block`. ### Repo A repo is also called a library. Every repo has an unique id (UUID), and attributes like description, creator, password. ### Branch Unlike git, only two predefined branches is used, i.e., `local` and `master`. In PC client, modifications will first be committed to the `local` branch.Then the `master` branch is downloaded from server, and merged into `local` branch.After that the `local` branch will be uploaded to server. Then the server will fast-forwardits `master` branch to the head commit of the just uploaded branch. When users update a repo on the web, modifications will first be committed to temporary branchon the server, then merged into the `master` branch. ### Commit Like in GIT. ### FS There are two types of FS objects, `SeafDir Object` and `Seafile Object`.`SeafDir Object` represents a directory, and `Seafile Object` represents a file. ### Block A file is further divided into blocks with variable lengths. We use Content Defined Chunking algorithm todivide file into blocks. A clear overview of this algorithm can be found at [http://pdos.csail.mit.edu/papers/lbfs:sosp01/lbfs.pdf](http://pdos.csail.mit.edu/papers/lbfs:sosp01/lbfs.pdf).On average, a block's size is around 1MB. This mechanism makes it possible to deduplicate data between different versions of frequently updated files,improving storage efficiency. It also enables transferring data to/from multiple servers in parallel.
';

Python API

最后更新于:2022-04-01 02:23:41

# Python API - [Seafile Python API](#) - [Install Seafile Server](#) - [Example: Copy Library](#) - [Set Environment Variable](#) - [Copy Library](#) - [List Of Seafile-API](#) # Seafile Python API This tutorial show you how to use seafile-api, and will accomplish a "library copy" work under **Ubuntu** as example. ### Install Seafile Server First of all, make sure you have [Download and Setup Seafile Server](https://github.com/haiwen/seafile/wiki/Download-and-setup-seafile-server) successfully. And your directory layout will be like this: ~~~ # tree . -L 3 . ├── ccnet │ ├── ccnet.conf │ ├── ...... │...... ├── seafile-server-3.0.3 │ ├── seafile │ ├── seafile.sh │ ├── seahub │ ├── seahub.sh │ ├── setup-seafile.sh │ ├── upgrade │ ├── README │ ├── seaf_migrate_3.py │ ├── seaf_migrate_3.sh │ ├── ...... │ ├── ...... │...... ~~~ ### Example: Copy Library In this example, two script files will be used: `seaf_migrate_3.sh` and `seaf_migrate_3.py`. We put them in the **upgrade** directory as you see above. ### Set Environment Variable If you want use Seafile-API, set environment variable first. That's what `seaf_migrate_3.sh` does: 1. get ccnet/seafile config file path and export them; 1. export Python path; 1. call `seaf_migrate_3.py`. Example code ~~~ #!/bin/bash #get path of ccnet.conf SCRIPT=$(readlink -f "$0") # haiwen/seafile-server-3.0.3/upgrade/seaf_migrate_3.sh UPGRADE_DIR=$(dirname "$SCRIPT") # haiwen/seafile-server-3.0.3/upgrade/ INSTALLPATH=$(dirname "$UPGRADE_DIR") # haiwen/seafile-server-3.0.3/ TOPDIR=$(dirname "${INSTALLPATH}") # haiwen/ default_ccnet_conf_dir=${TOPDIR}/ccnet #get path of seafile.conf function read_seafile_data_dir () { seafile_ini=${default_ccnet_conf_dir}/seafile.ini if [[ ! -f ${seafile_ini} ]]; then echo "${seafile_ini} not found. Now quit" exit 1 fi seafile_data_dir=$(cat "${seafile_ini}") if [[ ! -d ${seafile_data_dir} ]]; then echo "Your seafile server data directory \"${seafile_data_dir}\" is invalid or doesn't exits." echo "Please check it first, or create this directory yourself." echo "" exit 1; fi export SEAFILE_CONF_DIR=$seafile_data_dir } export CCNET_CONF_DIR=${default_ccnet_conf_dir} read_seafile_data_dir; export PYTHONPATH=${INSTALLPATH}/seafile/lib/python2.6/site-packages:${INSTALLPATH}/seafile/lib64/python2.6/site-packages:${INSTALLPATH}/seafile/lib/python2.7/site-packages:${INSTALLPATH}/seahub/thirdpart:$PYTHONPATH export PYTHONPATH=${INSTALLPATH}/seafile/lib/python2.7/site-packages:${INSTALLPATH}/seafile/lib64/python2.7/site-packages:$PYTHONPATH function usage () { echo "Usage: `basename $0` <repo-id>" echo "exit." exit 1 } if [ $# != 1 ]; then usage fi python seaf_migrate_3.py $1 ~~~ > **NOTE:**You can get `repo_id` at address bar of Seahub or through [Seafile web API](https://github.com/haiwen/seafile/wiki/Seafile-web-API#list-libraries) ### Copy Library Then `seaf_migrate_3.py` will call Seafile-API to copy library: 1. Get library ID from input. 1. Get origin_repo object. 1. Create a new library, set name, desc and owner. 1. Copy stuffs from old library to new library. Example code ~~~ #!/usr/bin/env python import os import stat import sys from seaserv import seafile_api def count_files_recursive(repo_id, path='/'): num_files = 0 for e in seafile_api.list_dir_by_path(repo_id, path): if stat.S_ISDIR(e.mode): num_files += count_files_recursive(repo_id, os.path.join(path, e.obj_name)) else: num_files += 1 return num_files #Get library ID from input origin_repo_id = sys.argv[1] #Get origin_repo object origin_repo = seafile_api.get_repo(origin_repo_id) username = seafile_api.get_repo_owner(origin_repo_id) #Create a new library, set name, desc and owner new_repo_id = seafile_api.create_repo(name=origin_repo.name, desc=origin_repo.desc, username=username, passwd=None) #Copy stuffs from old library to new library dirents = seafile_api.list_dir_by_path(origin_repo_id, '/') for e in dirents: print "copying: " + e.obj_name obj_name = e.obj_name seafile_api.copy_file(origin_repo_id, '/', obj_name, new_repo_id, '/', obj_name, username, 0, 1) print "*" * 60 print "OK, verifying..." print "Origin library(%s): %d files. New Library(%s): %d files." % ( origin_repo_id[:8], count_files_recursive(origin_repo_id), new_repo_id[:8], count_files_recursive(new_repo_id)) print "*" * 60 ~~~ If you execute script file successfully, you will see these output, and of course a new library at myhome page of Seahub. ~~~ foo@foo:~/haiwen/seafile-server-3.0.3/upgrade$ ./seaf_migrate_test.sh c8bbb088-cbaf-411d-8bd8-9870763f0e5f Loading ccnet config from /home/foo/haiwen/ccnet Loading seafile config from /home/foo/haiwen/seafile-data copying: test.html copying: test-dir-2 copying: test-dir copying: solar.html copying: examples.desktop ************************************************************ OK, verifying... Origin library(c8bbb088): 10 files. New Library(4d6f4837): 10 files. ************************************************************ ~~~ ### List Of Seafile-API This list is based on **seafile-server-3.0.3**, and parameter was omitted. For more infomation about Seafile-API, please see [api.py](https://github.com/haiwen/seafile/blob/master/python/seaserv/api.py). > - seafile_api.add_inner_pub_repo() > - seafile_api.cancel_copy_task() > - seafile_api.change_repo_passwd() > - seafile_api.check_passwd() > - seafile_api.check_permission() > - seafile_api.check_quota() > - seafile_api.check_repo_access_permission() > - seafile_api.copy_file() > - seafile_api.count_inner_pub_repos() > - seafile_api.create_enc_repo() > - seafile_api.create_repo() > - seafile_api.create_virtual_repo() > - seafile_api.del_file() > - seafile_api.delete_repo_token() > - seafile_api.delete_repo_tokens_by_peer_id() > - seafile_api.diff_commits() > - seafile_api.edit_repo() > - seafile_api.generate_repo_token() > - seafile_api.get_commit_list() > - seafile_api.get_copy_task() > - seafile_api.get_decrypt_key() > - seafile_api.get_deleted() > - seafile_api.get_dir_id_by_commit_and_path() > - seafile_api.get_dir_id_by_path() > - seafile_api.get_file_id_by_commit_and_path() > - seafile_api.get_file_id_by_path() > - seafile_api.get_file_revisions() > - seafile_api.get_file_size() > - seafile_api.get_files_last_modified() > - seafile_api.get_group_repo_list() > - seafile_api.get_group_repoids() > - seafile_api.get_group_repos_by_owner() > - seafile_api.get_fileserver_access_token() > - seafile_api.get_inner_pub_repo_list() > - seafile_api.get_orphan_repo_list() > - seafile_api.get_owned_repo_list() > - seafile_api.get_repo() > - seafile_api.get_repo_list() > - seafile_api.get_repo_owner() > - seafile_api.get_repo_size() > - seafile_api.get_share_in_repo_list() > - seafile_api.get_share_out_repo_list() > - seafile_api.get_shared_groups_by_repo() > - seafile_api.get_user_quota() > - seafile_api.get_user_self_usage() > - seafile_api.get_user_share_usage() > - seafile_api.get_virtual_repo() > - seafile_api.get_virtual_repos_by_owner() > - seafile_api.group_share_repo() > - seafile_api.group_unshare_repo() > - seafile_api.is_inner_pub_repo() > - seafile_api.is_password_set() > - seafile_api.is_repo_owner() > - seafile_api.is_valid_filename() > - seafile_api.list_dir_by_commit_and_path() > - seafile_api.list_dir_by_dir_id() > - seafile_api.list_dir_by_path() > - seafile_api.list_file_by_file_id() > - seafile_api.list_repo_tokens() > - seafile_api.list_repo_tokens_by_email() > - seafile_api.move_file() > - seafile_api.post_dir() > - seafile_api.post_empty_file() > - seafile_api.post_file() > - seafile_api.put_file() > - seafile_api.query_fileserver_access_token() > - seafile_api.remove_inner_pub_repo() > - seafile_api.remove_repo() > - seafile_api.remove_share() > - seafile_api.rename_file() > - seafile_api.revert_dir() > - seafile_api.revert_file() > - seafile_api.revert_repo() > - seafile_api.set_group_repo_permission() > - seafile_api.set_passwd() > - seafile_api.set_repo_owner() > - seafile_api.set_share_permission() > - seafile_api.set_user_quota() > - seafile_api.share_repo() > - seafile_api.unset_passwd()
';

Web API

最后更新于:2022-04-01 02:23:39

# Web API - [Seafile Web API V2](#) - [API Basics](#) - [Status Code](#) - [Quick Start](#) - [Account](#) - [List Accounts(Admin only)](#) - [Get Account Info(Admin only)](#) - [Create Account(Admin only)](#) - [Update Account(Admin only)](#) - [Delete Account(Admin only)](#) - [Check Account Info](#) - [Get Server Information](#) - [Starred Files](#) - [List starred files](#) - [Star A File](#) - [Unstar A File](#) - [User Messages](#) - [List User Messages](#) - [Reply A User Message](#) - [Count Unseen Messages](#) - [Group](#) - [List Groups](#) - [Add A Group](#) - [Delete Group](#) - [Rename Group](#) - [Group Member](#) - [Add A Group Member](#) - [Delete A Group Member](#) - [Group Message](#) - [Get Group Messages](#) - [Get Group Message Detail](#) - [Send A Group Message](#) - [Reply A Group Message](#) - [Get Group Message Replies](#) - [Share](#) - [File Share Link](#) - [List File Share Links](#) - [Create File Share Link](#) - [Delete File Share Link](#) - [List Direntry in Dir Download Link](#) - [Shared Libraries](#) - [List Shared Libraries](#) - [List Be Shared Libraries](#) - [Share A Library](#) - [Unshare A Library](#) - [Shared Files](#) - [List Shared Files](#) - [Download Shared File](#) - [Get Shared File Detail](#) - [Delete Shared File](#) - [Download Private Shared File](#) - [Get Private Shared File Detail](#) - [Library](#) - [Library](#) - [Get Default Library](#) - [Create Default Library](#) - [List Libraries](#) - [Get Library Info](#) - [Get Library Owner](#) - [Get Library History](#) - [Create Library](#) - [Check/Create Sub Library](#) - [Delete Library](#) - [Decrypt Library](#) - [Create Public Library](#) - [Remove Public Library](#) - [Fetch library download info](#) - [List Virtual Libraries](#) - [Search Libraries](#) - [File](#) - [Download File](#) - [Get File Detail](#) - [Get File History](#) - [Download File From a Revision](#) - [Create File](#) - [Rename File](#) - [Lock File](#) - [Unlock File](#) - [Move File](#) - [Copy File](#) - [Revert File](#) - [Delete File](#) - [Upload File](#) - [Get Upload Link](#) - [Upload File](#) - [Update file](#) - [Get Update Link](#) - [Update File](#) - [Get Upload Blocks Link](#) - [Get Update Blocks Link](#) - [Directory](#) - [List Directory Entries](#) - [Create New Directory](#) - [Rename Directory](#) - [Delete Directory](#) - [Download Directory](#) - [Share Directory](#) - [Batch Delete](#) - [Get Avatar](#) - [Get User Avatar](#) - [Get Group Avatar](#) - [Get Thumbnail](#) - [Get Thumbnail Image](#) - [List Group And Contacts](#) - [Get File Activities](#) - [Add Organization](#) # Seafile Web API V2 ### API Basics All API calls must be authenticated with a valid Seafile API key. ~~~ curl -H 'Authorization: Token 24fd3c026886e3121b2ca630805ed425c272cb96' https://cloud.seafile.com/api2/auth/ping/ ~~~ The api key can be retrieved by the obtain auth api. See the [Quick Start](#) for details. For each API, we provide `curl` examples to illustrate the usage. ### Status Code - 200: OK - 201: CREATED - 202: ACCEPTED - 301: MOVED_PERMANENTLY - 400: BAD_REQUEST - 403: FORBIDDEN - 404: NOT_FOUND - 409: CONFLICT - 429: TOO_MANY_REQUESTS - 440: REPO_PASSWD_REQUIRED - 441: REPO_PASSWD_MAGIC_REQUIRED - 500: INTERNAL_SERVER_ERROR - 520: OPERATION_FAILED ### Quick Start **ping** ~~~ curl https://cloud.seafile.com/api2/ping/ "pong" ~~~ **obtain auth token** ~~~ curl -d "username=username@example.com&password=123456" https://cloud.seafile.com/api2/auth-token/ {"token": "24fd3c026886e3121b2ca630805ed425c272cb96"} ~~~ **auth ping** ~~~ curl -H 'Authorization: Token 24fd3c026886e3121b2ca630805ed425c272cb96' https://cloud.seafile.com/api2/auth/ping/ "pong" ~~~ ### Account ### List Accounts **GET**[https://cloud.seafile.com/api2/accounts/](https://cloud.seafile.com/api2/accounts/) **Request parameters** - start (default to 0) - limit (default to 100) - scope (default None, accepted values: 'LDAP' or 'DB') To retrieve all users, just set both `start` and `limit` to `-1`. If scope parameter is passed then accounts will be searched inside the specific scope, otherwise it will be used the old approach: first LDAP and, if no account is found, DB. **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/accounts/ ~~~ **Sample response** ~~~ [ { "email": "foo@foo.com" }, { "email": "bar@bar.com" } ] ~~~ **Errors** - 403 Permission error, only administrator can perform this action ### Get Account Info **GET**[https://cloud.seafile.com/api2/accounts/{email}/](https://cloud.seafile.com/api2/accounts/{email}/) **Request parameters** **Sample request** ~~~ curl -v -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/accounts/user@mail.com/ ~~~ **Sample response** ~~~ { "is_staff": false, "is_active": true, "id": 2, "create_time": 1356061187741686, "usage": 651463187, "total": 107374182400, "email": "user@mail.com" } ~~~ **Errors** - 403 Permission error, only administrator can perform this action ### Check Account Info **GET**[https://cloud.seafile.com/api2/account/info/](https://cloud.seafile.com/api2/account/info/) **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/account/info/ ~~~ **Sample response** ~~~ { "usage": 26038531, "total": 104857600, "email": "user@example.com" } ~~~ **Errors** - 403 Invalid token ### Create Account **PUT**[https://cloud.seafile.com/api2/accounts/{email}/](https://cloud.seafile.com/api2/accounts/{email}/) **Request parameters** - password - is_staff (defaults to False) - is_active (defaults to True) **Sample request** ~~~ curl -v -X PUT -d "password=123456" -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/accounts/newaccount@gmail.com/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 201 CREATED < Location: https://cloud.seafile.com/api2/accounts/newaccount@gmail.com/ ... "success" ~~~ **Success** ~~~ Response code 201(Created) is returned and the Location header provides shared link. ~~~ **Errors** - 403 Permission error, only administrator can perform this action ### Update Account **PUT**[https://cloud.seafile.com/api2/accounts/{email}/](https://cloud.seafile.com/api2/accounts/{email}/) **Request parameters** At least one of followings: - password - is_staff - is_active - name - note - storage **Sample request** ~~~ curl -v -X PUT -d "password=654321&is_staff=true&storage=1073741824" -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/accounts/user@mail.com/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... "success" ~~~ **Success** ~~~ Response code 200(OK) is returned. ~~~ **Errors** - 400 Bad Request, keyword password is required - 403 Permission error, only administrator can perform this action ### Delete Account **DELETE**[https://cloud.seafile.com/api2/accounts/{email}/](https://cloud.seafile.com/api2/accounts/{email}/) **Sample request** ~~~ curl -v -X DELETE -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/accounts/newaccount@gmail.com/ ~~~ **Sample response** ~~~ "success" ~~~ **Errors** - 403 Permission error, only administrator can perform this action ### Get Server Information **GET**[https://cloud.seafile.com/api2/server-info](https://cloud.seafile.com/api2/server-info) *Note*: - No authentication required. - Added in seafile community edition server `4.0.5` or pro edition server `4.0.3` **Sample request** ~~~ curl https://cloud.seafile.com/api2/server-info/ ~~~ **Sample response** Sample response from a seafile community edition server: ~~~ { "version": "4.0.6", "features": [ "seafile-basic", ] } ~~~ Sample response from a seafile pro edition server: ~~~ { "version": "4.0.6", "features": [ "seafile-basic", "seafile-pro", "office-preview", "file-search" ] } ~~~ ### Starred Files ### List starred files **GET**[https://cloud.seafile.com/api2/starredfiles/](https://cloud.seafile.com/api2/starredfiles/) **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e6199b477fd" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/starredfiles/ ~~~ **Sample response** ~~~ [ { "repo": "99b758e6-91ab-4265-b705-925367374cf0", "mtime": 1355198150, "org": -1, "path": "/foo/bar.doc", "dir": false, "size": 0 }, { "repo": "99b758e6-91ab-4265-b705-925367374cf0", "mtime": 1353751237, "org": -1, "path": "/add_folder-blue.png", "dir": false, "size": 3170 } ] ~~~ ### Star A File **POST**[https://cloud.seafile.com/api2/starredfiles/](https://cloud.seafile.com/api2/starredfiles/) **Request parameters** - repo_id (post) - p (post) **Sample request** ~~~ curl -v -d "repo_id=dae8cecc-2359-4d33-aa42-01b7846c4b32&p=/foo.md" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/starredfiles/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 201 CREATED < Location: https://cloud.seafile.com/api2/starredfiles/ ... "success" ~~~ **Success** Response code is 201(Created) and Location header provides url of starred file list. **Errors** - 400 `repo_id` or `p` is missing, or `p` is not valid file path(e.g. /foo/bar/). ### Unstar A File **DELETE**[https://cloud.seafile.com/api2/starredfiles/](https://cloud.seafile.com/api2/starredfiles/) **Request parameters** - repo_id - p **Sample request** ~~~ curl -X DELETE -v -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' 'https://cloud.seafile.com/api2/starredfiles/?repo_id=dae8cecc-2359-4d33-aa42-01b7846c4b32&p=/foo.md' ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... "success" ~~~ **Success** Response code is 200(OK), and a string named "success" is returned. **Errors** - 400 `repo_id` or `p` is missing, or `p` is not valid file path(e.g. /foo/bar/). ### User Messages ### List User Messages **GET**[https://cloud.seafile.com/api2/user/msgs/{id_or_email}/](https://cloud.seafile.com/api2/user/msgs/{id_or_email}/) **Request parameters** - id_or_email **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/user/msgs/2/" ~~~ **Sample response** ~~~ { "to_email": "user@example.com", "next_page": -1, "msgs": [ { "attachments": [ { "path": "/123.md", "repo_id": "c7436518-5f46-4296-97db-2fcba4c8c8db" } ], "timestamp": 1398233096, "from_email": "user@example.com", "msgid": 3, "msg": "another test msg", "nickname": "user" }, { "attachments": [], "timestamp": 1398233067, "from_email": "user@example.com", "msgid": 2, "msg": "a test msg", "nickname": "user" } ] } ~~~ **Errors** - 404 user not found ### Reply A User Message **POST**[https://cloud.seafile.com/api2/user/msgs/{id_or_email}/](https://cloud.seafile.com/api2/user/msgs/{id_or_email}/) **Request parameters** - id_or_email - message **Sample request** ~~~ curl -d "message=this is a user msg reply" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/user/msgs/2/" ~~~ **Sample response** ~~~ { "msgid": 4 } ~~~ **Errors** - 404 user not found ### Count Unseen Messages **GET**[https://cloud.seafile.com/api2/unseen_messages/](https://cloud.seafile.com/api2/unseen_messages/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/unseen_messages/" ~~~ **Sample response** ~~~ { "count": 1 } ~~~ ### Group ### List Groups **GET**[https://cloud.seafile.com/api2/groups/](https://cloud.seafile.com/api2/groups/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/groups/" ~~~ **Sample response** ~~~ { "replynum": 0, "groups": [ { "ctime": 1398134171327948, "creator": "user@example.com", "msgnum": 0, "mtime": 1398231100, "id": 1, "name": "lian" }, { "ctime": 1398236081042441, "creator": "user@example.com", "msgnum": 0, "mtime": 0, "id": 2, "name": "123" } ] } ~~~ ### Add A Group **PUT**[https://cloud.seafile.com/api2/groups/](https://cloud.seafile.com/api2/groups/) **Request parameters** - group_name **Sample request** ~~~ curl -X PUT -d "group_name=newgroup" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/groups/" ~~~ **Sample response** ~~~ {"group_id": 3, "success": true} ~~~ **Errors** - 400 There is already a group with that name. ### Delete Group **DELETE**[https://cloud.seafile.com/api2/groups/{group_id}/](https://cloud.seafile.com/api2/groups/{group_id}/) **Request parameters** None **Sample request** ~~~ curl -X DELETE -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/groups/1/" ~~~ **Success** 200 if everything is fine. **Errors** - 400 if ad group id format - 404 if Group not found - 403 if Forbid to delete group - 520 if Failed to remove group (generic error) ### Rename Group **POST**[https://cloud.seafile.com/api2/groups/{group_id}/](https://cloud.seafile.com/api2/groups/{group_id}/) **Request parameters** - operation (value must be 'rename') - newname (the new name for the group) **Sample request** ~~~ curl -d "operation=rename&newname=pinkfloyd_lovers" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/groups/1/" ~~~ **Success** 200 if everything is fine. **Errors** - 404 if Group not found - 403 if Forbid to rename group - 400 if Newname is missing or if Group name is not valid of if There is already a group with that name or Operation can only be rename. ### Group Member #### Add A Group Member **PUT**[https://cloud.seafile.com/api2/groups/{group_id}/members/](https://cloud.seafile.com/api2/groups/{group_id}/members/) **Request parameters** - user_name **Sample request** ~~~ curl -X PUT -d "user_name=user@example.com"-H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/groups/1/members/" ~~~ **Sample response** ~~~ {"success": true} ~~~ **Errors** - 400 invalid group id - 403 only administrators can add group members - 404 unable to find group #### Delete A Group Member **DELETE**[https://cloud.seafile.com/api2/groups/{group_id}/members/](https://cloud.seafile.com/api2/groups/{group_id}/members/) **Request parameters** - user_name **Sample request** ~~~ curl -X DELETE -d "user_name=user@example.com" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/groups/1/members/" ~~~ **Sample response** ~~~ {"success": true} ~~~ **Errors** - 400 invalid group id - 403 only administrators can remove group members - 404 unable to find group ### Group Message #### Get Group Messages **GET**[https://cloud.seafile.com/api2/group/msgs/{group_id}/](https://cloud.seafile.com/api2/group/msgs/{group_id}/) **Request parameters** - group_id **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/group/msgs/1/" ~~~ **Sample response** ~~~ { "next_page": -1, "msgs": [ { "reply_cnt": 0, "timestamp": 1398230602, "replies": [], "from_email": "user@example.com", "msgid": 1, "msg": "test discuss", "nickname": "user" } ] } ~~~ #### Get Group Message Detail **GET**[https://cloud.seafile.com/api2/group/{group_id}/msg/{msg_id}/](https://cloud.seafile.com/api2/group/{group_id}/msg/{msg_id}/) **Request parameters** - group_id - msg_id **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/group/1/msg/1/" ~~~ **Sample response** ~~~ { "reply_cnt": 2, "timestamp": 1398230602, "replies": [ { "msg": "this is another test", "timestamp": 1398232319, "nickname": "user", "msgid": 1, "from_email": "user@example.com" }, { "msg": "this is another test", "timestamp": 1398232508, "nickname": "user", "msgid": 3, "from_email": "user@example.com" } ], "from_email": "user@example.com", "msgid": 1, "msg": "test discuss", "nickname": "user" } ~~~ **Errors** - 404 message not found #### Send A Group Message **POST**[https://cloud.seafile.com/api2/group/msgs/{group_id}/](https://cloud.seafile.com/api2/group/msgs/{group_id}/) **Request parameters** - message - group_id - repo_id(optional) - path(optional) **Sample request** ~~~ curl -d "message=this is another test&repo_id=c7436518-5f46-4296-97db-2fcba4c8c8db&path=/123.md" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/group/msgs/1/" ~~~ **Sample response** ~~~ { "msgid": 3 } ~~~ #### Reply A Group Message **POST**[https://cloud.seafile.com/api2/group/{group_id}/msg/{msg_id}](https://cloud.seafile.com/api2/group/{group_id}/msg/{msg_id}) **Request parameters** - group_id - msg_id - message **Sample request** ~~~ curl -d "message=this is a reply" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/group/1/msg/1/" ~~~ **Sample response** ~~~ { "msgid": 3 } ~~~ **Errors** - 404 message not found #### Get Group Message Replies **GET**[https://cloud.seafile.com/api2/new_replies/](https://cloud.seafile.com/api2/new_replies/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/new_replies/" ~~~ **Sample response** ~~~ [ { "reply_cnt": 1, "timestamp": 1398231100, "replies": [ { "msg": "@user test reply", "timestamp": 1398234493, "nickname": "123", "msgid": 5, "from_email": "user@example.com" } ], "from_email": "user@example.com", "att": { "repo": "c7436518-5f46-4296-97db-2fcba4c8c8db", "path": "/123.md", "type": "file", "src": "recommend" }, "msgid": 3, "msg": "this is another test", "nickname": "user" } ] ~~~ ### Share ### File Share Link #### List File Share Links **GET**[https://cloud.seafile.com/api2/shared-links/](https://cloud.seafile.com/api2/shared-links/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/shared-links/" ~~~ **Sample response** ~~~ {"fileshares": [{"username": "user@example.com", "repo_id": "a582d3bc-bcf5-421e-9125-741fa56d18d4", "ctime": null, "s_type": "d", "token": "e410827494", "view_cnt": 0, "path": "/123/"}, {"username": "user@example.com", "repo_id": "affc837f-7fdd-4e91-b88a-32caf99897f2", "ctime": null, "s_type": "f", "token": "0ae587a7d1", "view_cnt": 0, "path": "/lian123.md"}]} ~~~ #### Create File Share Link **PUT**[https://cloud.seafile.com/api2/repos/{repo-id}/file/shared-link/](https://cloud.seafile.com/api2/repos/{repo-id}/file/shared-link/) **Request parameters** - repo-id - p (Path to the file) - share_type (optional, `download` or `upload`, default `download`) - password (optional) - expire (optional) **Sample request** Create download link for file ~~~ curl -v -X PUT -d "p=/foo.md" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/afc3b694-7d4c-4b8a-86a4-89c9f3261b12/file/shared-link/ ~~~ Create download link for directory with password and expire date ~~~ curl -v -X PUT -d "password=password&expire=6&p=/123/" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/afc3b694-7d4c-4b8a-86a4-89c9f3261b12/file/shared-link/ ~~~ Create upload link for directory ~~~ curl -v -X PUT -d "share_type=upload&p=/123/" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/afc3b694-7d4c-4b8a-86a4-89c9f3261b12/file/shared-link/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 201 CREATED < Location: https://cloud.seafile.com/f/9b437a7e55/ ... ~~~ **Success** ~~~ Response code 201(Created) is returned and the Location header provides shared link. ~~~ **Errors** - 400 Path is missing - 400 Password(if link is encrypted) is missing - 500 Internal server error #### Delete File Share Link **DELETE**[https://cloud.seafile.com/api2/shared-links/?t=0ae587a7d1](https://cloud.seafile.com/api2/shared-links/?t=0ae587a7d1) **Request parameters** - t **Sample request** ~~~ curl -v -X DELETE -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/shared-links/?t=0ae587a7d1" ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... ~~~ #### List Direntry in Dir Download Link **GET**[https://cloud.seafile.com/api2/d/{token}/dir/](https://cloud.seafile.com/api2/d/{token}/dir/) **Request parameters** - token (upload link token) - p (sub folder path) - password (if link is encrypted) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/d/3af7c46595/dir/?p=/subfolder/" ~~~ **Sample response** ~~~ [{"mtime": 1436846750, "type": "dir", "name": "sadof", "id": "1806dbdb700b7bcd49e6275107c7ccf7b3ea1776"}, {"id": "bdb06f6de972c42893fda590ac954988b562429c", "mtime": 1436431020, "type": "file", "name": "test.mdert", "size": 20}] ~~~ ### Shared Libraries #### List Shared Libraries **GET**[https://cloud.seafile.com/api2/shared-repos/](https://cloud.seafile.com/api2/shared-repos/) **Sample request** ~~~ curl -v -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/shared-repos/ ~~~ **Sample response** ~~~ [{"repo_id": "7d42522b-1f6f-465d-b9c9-879f8eed7c6c", "share_type": "personal", "permission": "rw", "encrypted": false, "user": "user@example.com", "last_modified": 1361072500, "repo_desc": "ff", "group_id": 0, "repo_name": "\u6d4b\u8bd5\u4e2d\u6587pdf"}, {"repo_id": "79bb29cd-b683-4844-abaf-433952723ca5", "share_type": "group", "permission": "rw", "encrypted": false, "user": "user@example.com", "last_modified": 1359182468, "repo_desc": "test", "group_id": 1, "repo_name": "test_enc"}] ~~~ #### List Be Shared Libraries **GET**[https://cloud.seafile.com/api2/beshared-repos/](https://cloud.seafile.com/api2/beshared-repos/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/beshared-repos/" ~~~ **Sample response** ~~~ "[{"user": "user@example.com", "repo_id": "989e3952-9d6f-4427-ab16-4bf9b53212eb", "share_type": "personal", "permission": "rw", "encrypted": false, "repo_desc": "lib shared to imwhatiam", "enc_version": false, "last_modified": 1398218747, "is_virtual": false, "group_id": 0, "repo_name": "lib shared to imwhatiam"}]" ~~~ #### Share A Library **PUT**[https://cloud.seafile.com/api2/shared-repos/{repo-id}/](https://cloud.seafile.com/api2/shared-repos/{repo-id}/) **Request parameters** - share_type ('personal', 'group' or 'public') - user (or users) - group_id - permission If share_type is 'personal' then 'user' or 'users' param are required, if share_type is 'group' then 'group_id' parameter is required. If share_type is 'public' no other params is required. 'user' or 'users' parameters can be a comma separated list of emails, in this case the share will be done for more users at the same time. If a problem is encountered during multiple users sharing then the sharing process is aborted. **Sample request** ~~~ curl -X PUT -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/shared-repos/7d42522b-1f6f-465d-b9c9-879f8eed7c6c/?share_type=group&user=user@example.com&group_id=1&permission=rw" ~~~ **Sample response** ~~~ "success" ~~~ #### Unshare A Library **DELETE**[https://cloud.seafile.com/api2/shared-repos/{repo-id}/](https://cloud.seafile.com/api2/shared-repos/{repo-id}/) **Request parameters** - share_type ('personal', 'group' or 'public') - user - group_id If share_type is 'personal' then 'user' param is required, if share_type is 'group' then 'group_id' parameter is required. If share_type is 'public' no other params is required. **Sample request** ~~~ curl -X DELETE -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/shared-repos/7d42522b-1f6f-465d-b9c9-879f8eed7c6c/?share_type=personal&user=user@example.com&group_id=0" ~~~ **Sample response** ~~~ "success" ~~~ ### Shared Files #### List Shared Files **GET**[https://cloud.seafile.com/api2/shared-files/](https://cloud.seafile.com/api2/shared-files/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/shared-files/" ~~~ **Sample response** ~~~ {"priv_share_in": [{"s_type": "f", "repo_id": "989e3952-9d6f-4427-ab16-4bf9b53212eb", "permission": "r", "to_user": "user@example.com", "token": "94aace406a", "from_user": "user@example.com", "path": "/lib.md"}], "priv_share_out": [{"s_type": "f", "repo_id": "affc837f-7fdd-4e91-b88a-32caf99897f2", "permission": "r", "to_user": "user@example.com", "token": "b7b31bc39b", "from_user": "user@example.com", "path": "/lian123.md"}]} ~~~ #### Download Shared File **GET**[https://cloud.seafile.com/api2/f/{token}/](https://cloud.seafile.com/api2/f/{token}/) **Request parameters** - token(file share token) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/f/ad93cd0d66/" ~~~ **Sample response** ~~~ "http://192.168.1.101:8082/files/89223601/lib.md" ~~~ **Errors** - 404 repo/token/file not found - 520 OPERATION FAILED, fail to get file id by path #### Get Shared File Detail **GET**[https://cloud.seafile.com/api2/f/{token}/detail/](https://cloud.seafile.com/api2/f/{token}/detail/) **Request parameters** - token(file share token) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/f/ad93cd0d66/detail/" ~~~ **Sample response** ~~~ {"repo_id": "989e3952-9d6f-4427-ab16-4bf9b53212eb", "name": "lib.md", "mtime": 1398218747, "path": "/lib.md", "type": "file", "id": "0000000000000000000000000000000000000000", "size": 0} ~~~ **Errors** - 404 repo/token/file not found - 520 OPERATION FAILED, fail to get file id by path #### Delete Shared File **DELETE**[https://cloud.seafile.com/api2/shared-files/?t=0ae587a7d1](https://cloud.seafile.com/api2/shared-files/?t=0ae587a7d1) **Request parameters** - t **Sample request** ~~~ curl -v -X DELETE -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/shared-files/?t=94aace406a" ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... ~~~ #### Download Private Shared File **GET**[https://cloud.seafile.com/api2/s/f/{token}/](https://cloud.seafile.com/api2/s/f/{token}/) **Request parameters** - token(private file share token) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/s/f/c5aa5f0219/" ~~~ **Sample response** ~~~ "http://192.168.1.101:8082/files/6960d5a4/lib.md" ~~~ **Errors** - 404 repo/token/file not found - 520 OPERATION FAILED, fail to get file id by path #### Get Private Shared File Detail **GET**[https://cloud.seafile.com/api2/s/f/{token}/detail/](https://cloud.seafile.com/api2/s/f/{token}/detail/) **Request parameters** - token(private file share token) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/s/f/c5aa5f0219/detail/" ~~~ **Sample response** ~~~ {"repo_id": "989e3952-9d6f-4427-ab16-4bf9b53212eb", "name": "lib.md", "shared_by": "user@example.com", "mtime": 1398218747, "path": "/lib.md", "type": "file", "id": "0000000000000000000000000000000000000000", "size": 0} ~~~ **Errors** - 404 repo/token/file not found - 520 OPERATION FAILED, fail to get file id by path ### Library ### Library #### Get Default Library **GET**[https://cloud.seafile.com/api2/default-repo/](https://cloud.seafile.com/api2/default-repo/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/default-repo/" ~~~ **Sample response** ~~~ { "repo_id": "691b3e24-d05e-43cd-a9f2-6f32bd6b800e", "exists": true } ~~~ #### Create Default Library **POST**[https://cloud.seafile.com/api2/default-repo/](https://cloud.seafile.com/api2/default-repo/) **Sample request** ~~~ curl -X POST -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/default-repo/" ~~~ **Sample response** ~~~ { "repo_id": "691b3e24-d05e-43cd-a9f2-6f32bd6b800e", "exists": true } ~~~ #### List Libraries **GET**[https://cloud.seafile.com/api2/repos/](https://cloud.seafile.com/api2/repos/) **Sample request** ~~~ curl -H 'Authorization: Token 24fd3c026886e3121b2ca630805ed425c272cb96' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/ ~~~ **Sample response** ~~~ [ { "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" }, { "permission": "rw", "encrypted": false, "mtime": 1400054802, "owner": "user@mail.com", "id": "0536b11a-a5fd-4482-9314-728cb3472f54", "size": 0, "name": "foo", "type": "repo", "virtual": false, "desc": "new library", "root": "0000000000000000000000000000000000000000" } ] ~~~ #### Get Library Info **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/](https://cloud.seafile.com/api2/repos/{repo-id}/) **Request parameters** - repo-id **Sample request** ~~~ curl -G -H 'Authorization: Token 24fd3c026886e3121b2ca630805ed425c272cb96' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/632ab8a8-ecf9-4435-93bf-f495d5bfe975/ ~~~ **Sample response** ~~~ { "encrypted": false, "password_need": null, "mtime": null, "owner": "self", "id": "632ab8a8-ecf9-4435-93bf-f495d5bfe975", "size": 1356155, "name": "org", "root": "b5227040de360dd22c5717f9563628fe5510cbce", "desc": "org file", "type": "repo" } ~~~ #### Get Library Owner **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/owner/](https://cloud.seafile.com/api2/repos/{repo-id}/owner/) **Request parameters** - repo-id **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d9b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/owner/ ~~~ **Sample response** ~~~ { "owner": "user@example.com" } ~~~ **Errors** - 403 Permission error, only administrator can perform this action #### Get Library History **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/history/](https://cloud.seafile.com/api2/repos/{repo-id}/history/) **Request parameters** - repo-id **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d9b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/history/ ~~~ **Sample response** ~~~ {"commits": [{"rev_file_size": 0, "rev_file_id": null, "ctime": 1398045167, "creator_name": "imwhatiam123@gmail.com", "creator": "0000000000000000000000000000000000000000", "root_id": "ca2625da6be6e211ddd584615ef3bfaa531e66aa", "rev_renamed_old_path": null, "parent_id": "205c469f0830df09b13024601524058757a43128", "new_merge": false, "repo_id": "691b3e24-d05e-43cd-a9f2-6f32bd6b800e", "desc": "Modified \"api.md\"", "id": "eb62721812e0c3122889b5facde971b353ad176b", "conflict": false, "second_parent_id": null}, {"rev_file_size": 0, "rev_file_id": null, "ctime": 1398045158, "creator_name": "imwhatiam123@gmail.com", "creator": "0000000000000000000000000000000000000000", "root_id": "0b7a31adf4ea8b29ad5a5920420b548da11dd32f", "rev_renamed_old_path": null, "parent_id": "2ba85ee6072efea51a3483843ea7de9b6d1d1eb2", "new_merge": false, "repo_id": "691b3e24-d05e-43cd-a9f2-6f32bd6b800e", "desc": "Added \"api.md\"", "id": "205c469f0830df09b13024601524058757a43128", "conflict": false, "second_parent_id": null}], "page_next": false} ~~~ #### Create Library **POST**[https://cloud.seafile.com/api2/repos/](https://cloud.seafile.com/api2/repos/) **Request parameters** - name - desc (defaults to "new repo") - passwd (needed by encrypt library) **Sample request** ~~~ curl -v -d "name=foo&desc=new library" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/ ~~~ **Sample response** ~~~ { "encrypted": "", "enc_version": 0, "repo_id": "f15811fd-5c19-412c-b143-2ac83f352290", "magic": "", "relay_id": "c5e41170db250ea497075e2911104faf0105b7fb", "repo_version": 1, "relay_addr": "cloud.seafile.com", "token": "c1f3defe9ba408cd7964427ec276843e9d10c23b", "relay_port": "10001", "random_key": "", "email": "user@mail.com", "repo_name": "foo" } ~~~ **Success** Response code 200 and newly created library information are returned. **Errors** - 400 Library name missing. - 520 Operation failed. #### Check/Create Sub Library check if a dir has a corresponding sub_repo, if it does not have, create one **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/dir/sub_repo/?p=/\&name=sub_lib](https://cloud.seafile.com/api2/repos/{repo-id}/dir/sub_repo/?p=/\&name=sub_lib) **Request parameters** - repo-id - p - name **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d9b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/dir/sub_repo/?p=/\&name=sub_lib ~~~ **Sample response** ~~~ {"sub_repo_id": "c0a3283c-013c-4a7c-8f68-006f06fa6dec"} ~~~ **Errors** - 400 Argument missing - 500 INTERNAL SERVER ERROR #### Delete Library **DELETE**[https://cloud.seafile.com/api2/repos/{repo-id}/](https://cloud.seafile.com/api2/repos/{repo-id}/) **Sample request** ~~~ curl -v -X DELETE -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/8f5f2222-72a8-454f-ac40-8397c5a556a8/ ~~~ **Sample response** "success" **Errors** - 400 Library does not exist. - 403 Only library owner can perform this operation. #### Decrypt Library **POST**[https://cloud.seafile.com/api2/repos/{repo-id}/](https://cloud.seafile.com/api2/repos/{repo-id}/) **Request parameters** - password **Sample request** ~~~ curl -v -d "password=123" -H 'Authorization: Token e6a33d61954f219a96b60f635cf02717964e4385' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/0c2465a5-4753-4660-8a22-65abec9ec8d0/ ~~~ **Sample response** "success" **Errors** - 400 Incorrect password - 409 Repo is not encrypt - 500 Internal server error #### Create Public Library **POST**[https://cloud.seafile.com/api2/repos/{repo-id}/public/](https://cloud.seafile.com/api2/repos/{repo-id}/public/) **Request parameters** - repo-id **Sample request** ~~~ curl -X POST -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d9b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/public/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... ~~~ **Success** ~~~ Response code is 200(OK), and a string "success" is returned. ~~~ **Errors** - 404 Repo not found - 403 Forbid to access this repo - 500 INTERNAL SERVER ERROR, Unable to make repo public #### Remove Public Library **DELETE**[https://cloud.seafile.com/api2/repos/{repo-id}/public/](https://cloud.seafile.com/api2/repos/{repo-id}/public/) **Request parameters** - repo-id **Sample request** ~~~ curl -X DELETE -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d9b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/public/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... ~~~ **Success** ~~~ Response code is 200(OK), and a string "success" is returned. ~~~ **Errors** - 404 Repo not found - 403 Forbid to access this repo - 500 INTERNAL SERVER ERROR, Unable to remove public repo #### Fetch library download info **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/download-info/](https://cloud.seafile.com/api2/repos/{repo-id}/download-info/) **Request parameters** - repo-id **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d9b477fd' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/download-info/ ~~~ **Sample response** ~~~ { "applet_root": "https://localhost:13420", "relay_addr": "localhost", "token": "46acc4d9ca3d6a5c7102ef379f82ecc1edc629e1", "repo_id": "dae8cecc-2359-4d33-aa42-01b7846c4b32", "relay_port": "10002", "encrypted": "", "repo_name": "test", "relay_id": "8e4b13b49ca79f35732d9f44a0804940d985627c", "email": "user@example.com" } ~~~ #### List Virtual Libraries **GET**[https://cloud.seafile.com/api2/virtual-repos/](https://cloud.seafile.com/api2/virtual-repos/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/virtual-repos/" ~~~ **Sample response** ~~~ {"virtual-repos": [ {"virtual_perm": "rw", "store_id": null, "worktree_invalid": false, "encrypted": false, "origin_repo_name": "lian", "last_modify": 0, "no_local_history": false, "head_branch": null, "last_sync_time": 0, "id": "51344de8-456f-4dc7-ac08-718827994252", "size": 0, "share_permission": null, "worktree_changed": false, "worktree_checktime": 0, "origin_path": "/lian", "is_virtual": true, "origin_repo_id": "a582d3bc-bcf5-421e-9125-741fa56d18d4", "version": 1, "random_key": null, "is_original_owner": true, "shared_email": null, "enc_version": 0, "head_cmmt_id": "bc666fdc60d2352b9f6a0324ac64168d43724eed", "desc": null, "index_corrupted": false, "magic": null, "name": "lian", "worktree": null, "auto_sync": false, "relay_id": null}, {"virtual_perm": "rw", "store_id": null, "worktree_invalid": false, "encrypted": false, "origin_repo_name": "lian", "last_modify": 0, "no_local_history": false, "head_branch": null, "last_sync_time": 0, "id": "c0a3283c-013c-4a7c-8f68-006f06fa6dec", "size": 0, "share_permission": null, "worktree_changed": false, "worktree_checktime": 0, "origin_path": "/", "is_virtual": true, "origin_repo_id": "a582d3bc-bcf5-421e-9125-741fa56d18d4", "version": 1, "random_key": null, "is_original_owner": true, "shared_email": null, "enc_version": 0, "head_cmmt_id": "ff18229aadc9acc73ad481278d5b4c42b3353aa0", "desc": null, "index_corrupted": false, "magic": null, "name": "123", "worktree": null, "auto_sync": false, "relay_id": null} ] } ~~~ #### Search Libraries **GET**[https://cloud.seafile.com/api2/search/](https://cloud.seafile.com/api2/search/) **Request parameters** - q - per_page (optional) **Sample request** ~~~ curl -G -H 'Authorization: Token 24fd3c026886e3121b2ca630805ed425c272cb96' -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/search/?q=keyword ~~~ **Sample response** ~~~ { "has_more": false, "total": 3, "results": [ { "repo_id": "691b3e24-d05e-43cd-a9f2-6f32bd6b800e", "name": "api.md", "oid": "8ea78453bb474359cd9d8e2c4c4d8d9cbdcef0a2", "last_modified": 1398045167, "fullpath": "/api.md", "size": 18939 }, { "repo_id": "c5509062-9bca-4933-a7e0-c6da1d5f82be", "name": "home.md", "oid": "dda57aaffa5179829e064c7d0c142f47a8a65d3b", "last_modified": 1397096831, "fullpath": "/home.md", "size": 1954 }, { "repo_id": "c5509062-9bca-4933-a7e0-c6da1d5f82be", "name": "\u5e38\u89c1\u5b89\u88c5\u95ee\u9898.md", "oid": "8573f982eeb478b932a55ec13218f4f90a7c5a27", "last_modified": 1397188959, "fullpath": "/\u5e38\u89c1\u5b89\u88c5\u95ee\u9898.md", "size": 1050 } ] } ~~~ **Errors** - 404 Search not supported. - 400 Missing argument q. ### File #### Download File **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo](https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo) **Request parameters** - repo-id - p **Sample request** ~~~ curl -v -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/?p=/foo.c ~~~ **Sample response** ~~~ "https://cloud.seafile.com:8082/files/adee6094/foo.c" ~~~ **Errors** - 400 Path is missing - 404 File not found - 520 Operation failed. #### Get File Detail **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/file/detail/?p=/foo.c](https://cloud.seafile.com/api2/repos/{repo-id}/file/detail/?p=/foo.c) - repo-id - p **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd3606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/detail/?p=/foo.c ~~~ **Sample response** ~~~ { "id": "013d3d38fed38b3e8e26b21bb3463eab6831194f", "mtime": 1398148877, "type": "file", "name": "foo.py", "size": 22 } ~~~ **Errors** - 400 Path is missing - 520 Operation failed. #### Get File History **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/file/history/?p=/foo.c](https://cloud.seafile.com/api2/repos/{repo-id}/file/history/?p=/foo.c) **Request parameters** - repo-id - p **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd3606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/history/?p=/foo.c ~~~ **Sample response** ~~~ { "commits": [ { "rev_file_size": 0, "repo_id": "a582d3bc-bcf5-421e-9125-741fa56d18d4", "ctime": 1398149763, "creator_name": "user@example.com", "creator": "0000000000000000000000000000000000000000", "root_id": "b64d413d9894c9206beac3faf9c2a0d75b4a8ebf", "rev_renamed_old_path": null, "parent_id": "8e546762e1657ab22dad83e9cb1e5ea31a767c9a", "new_merge": false, "version": 1, "conflict": false, "desc": "Added \"foo.c\"", "id": "9464f7499bfa7363d563282361339eaf96a93318", "rev_file_id": "0000000000000000000000000000000000000000", "second_parent_id": null }, { "rev_file_size": 0, "repo_id": "a582d3bc-bcf5-421e-9125-741fa56d18d4", "ctime": 1398146059, "creator_name": "user@example.com", "creator": "0000000000000000000000000000000000000000", "root_id": "572413414257c76039897e00aeb35f819471206b", "rev_renamed_old_path": null, "parent_id": "f977bdb0ebb205645c3b42216c2817e511c3f68f", "new_merge": false, "version": 1, "conflict": false, "desc": "Added \"foo.c\"", "id": "a1ec20709675f4dc8db825cdbca296be245d189b", "rev_file_id": "0000000000000000000000000000000000000000", "second_parent_id": null } ] } ~~~ **Errors** - 400 Path is missing - 404 File not found #### Download File From a Revision **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/file/revision/?p=/foo.c&commit_id=a1ec20709675f4dc8db825cdbca296be245d189b](https://cloud.seafile.com/api2/repos/{repo-id}/file/revision/?p=/foo.c&commit_id=a1ec20709675f4dc8db825cdbca296be245d189b) **Request parameters** - repo-id - p - commit_id **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd3606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/revision/?p=/foo.c\&commit_id=a1ec20709675f4dc8db825cdbca296be245d189b ~~~ **Sample response** ~~~ "https://cloud.seafile.com:8082/files/adee6094/foo.c" ~~~ **Errors** - 400 Path is missing - 404 Revision not found #### Create File **POST**[https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo.c](https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo.c) **Request parameters** - repo-id - p - operation **Sample request** ~~~ curl -v -d "operation=create" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/?p=/foo.c ~~~ **Sample response** ~~~ ... < HTTP/1.1 201 CREATED ... "success" ~~~ **Success** Response code is 201, and a string `"success"` is returned. **Errors** - 403 FORBIDDEN, You do not have permission to move file - 520 OPERATION FAILED, fail to create file #### Rename File **POST**[https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo.c](https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo.c) **Request parameters** - repo-id - p - operation - newname **Sample request** ~~~ curl -v -d "operation=rename&newname=newfoo.c" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/?p=/foo.c ~~~ **Sample response** ~~~ ... < HTTP/1.1 301 MOVED PERMANENTLY ... "success" ~~~ **Success** Response code is 301, and a string `"success"` is returned. **Errors** - 400 BAD REQUEST, Path is missing or invalid(e.g. p=/) or newname is missing(newname too long) - 403 FORBIDDEN, You do not have permission to rename file - 404 NOT FOUND, repo not found - 409 CONFLICT, the newname is the same to the old - 520 OPERATION FAILED, fail to rename file #### Lock File **PUT**[https://cloud.seafile.com/api2/repos/{repo-id}/file/](https://cloud.seafile.com/api2/repos/{repo-id}/file/) **Request parameters** - repo-id - p - operation **Sample request** ~~~ curl -v -X PUT -d "operation=lock&p=/foo.c" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... "success" ~~~ **Success** Response code is 200, and a string `"success"` is returned. **Errors** - 400 BAD REQUEST, Path is missing or invalid(e.g. p=/) - 403 FORBIDDEN, You do not have permission to lock file - 404 NOT FOUND, repo not found - 520 OPERATION FAILED, fail to lock file #### Unlock File **PUT**[https://cloud.seafile.com/api2/repos/{repo-id}/file/](https://cloud.seafile.com/api2/repos/{repo-id}/file/) **Request parameters** - repo-id - p - operation **Sample request** ~~~ curl -v -X PUT -d "operation=unlock&p=/foo.c" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... "success" ~~~ **Success** Response code is 200, and a string `"success"` is returned. **Errors** - 400 BAD REQUEST, Path is missing or invalid(e.g. p=/) - 403 FORBIDDEN, You do not have permission to lock file - 404 NOT FOUND, repo not found - 520 OPERATION FAILED, fail to unlock file #### Move File **POST**[https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo.c](https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo.c) **Request parameters** - repo-id - p - operation - dst_repo - dst_dir **Sample request** ~~~ curl -v -d "operation=move&dst_repo=affc837f-7fdd-4e91-b88a-32caf99897f2&dst_dir=/" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/?p=/foo.c ~~~ **Sample response** ~~~ ... < HTTP/1.1 301 MOVED PERMANENTLY ... "success" ~~~ **Success** Response code is 301, and a string `"success"` is returned. **Errors** - 400 BAD REQUEST, Path is missing or invalid(e.g. p=/) - 403 FORBIDDEN, You do not have permission to move file - 404 NOT FOUND, repo not found - 500 INTERNAL SERVER ERROR #### Copy File **POST**[https://cloud.seafile.com/api2/repos/{repo_id}/fileops/copy/](https://cloud.seafile.com/api2/repos/{repo_id}/fileops/copy/) **Request parameters** - p: source folder path, defaults to `"/"` - file_names: list of file/folder names to copy. Multiple file/folder names can be seperated by `:`. - dst_repo: the destination repo id - dst_dir: the destination folder in `dst_repo` **Sample request** ~~~ curl -d "dst_repo=73ddb2b8-dda8-471b-b7a7-ca742b07483c&dst_dir=/&file_names=foo.c" -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/repos/c7436518-5f46-4296-97db-2fcba4c8c8db/fileops/copy/ ~~~ **Sample response** ~~~ "success" ~~~ **Errors** - 400 missing argument - 403 You do not have permission to copy file - 404 repo not found - 502 failed to copy file #### Revert File **PUT**[https://cloud.seafile.com/api2/repos/{repo_id}/file/revert/](https://cloud.seafile.com/api2/repos/{repo_id}/file/revert/) **Request parameters** - repo_id - p - commit_id **Sample request** ~~~ curl -v -X PUT -d "commit_id=a1ec20709675f4dc8db825cdbca296be245d189b&p=/foo.c" -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/8f5f2222-72a8-454f-ac40-8397c5a556a8/file/revert/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... {"ret": 0} ~~~ **Success** ~~~ Response code 200(OK) is returned. ~~~ **Errors** - 400 Path is missing #### Delete File **DELETE**[https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo](https://cloud.seafile.com/api2/repos/{repo-id}/file/?p=/foo) **Request parameters** - repo-id - p **Sample request** ~~~ curl -X DELETE -v -H 'Authorization: Token f2210dacd3606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/file/?p=/foo.c ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... "success" ~~~ **Errors** - 400 Path is missing - 520 Operation failed. **Note** This can also be used to delete directory. #### Upload File ##### Get Upload Link **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/upload-link/](https://cloud.seafile.com/api2/repos/{repo-id}/upload-link/) **Request parameters** - repo-id **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" https://cloud.seafile.com/api2/repos/99b758e6-91ab-4265-b705-925367374cf0/upload-link/ ~~~ **Sample response** ~~~ "http://cloud.seafile.com:8082/upload-api/ef881b22" ~~~ **Errors** ~~~ 500 Run out of quota ~~~ ##### Upload File After getting the upload link, POST to this link for uploading files. **POST**[http://cloud.seafile.com:8082/upload-api/ef881b22](http://cloud.seafile.com:8082/upload-api/ef881b22) **Errors** ~~~ 400 Bad request 440 Invalid filename 441 File already exists 500 Internal server error ~~~ **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -F file=@test.txt -F filename=test.txt -F parent_dir=/ http://cloud.seafile.com:8082/upload-api/ef881b22 ~~~ **Sample response** ~~~ "adc83b19e793491b1c6ea0fd8b46cd9f32e592fc" ~~~ **Note** For python client uploading, see [https://cloud.seafile.com/f/1b0ade6edc/](https://cloud.seafile.com/f/1b0ade6edc/) #### Update file ##### Get Update Link **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/update-link/](https://cloud.seafile.com/api2/repos/{repo-id}/update-link/) **Request parameters** - repo-id **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" https://cloud.seafile.com/api2/repos/99b758e6-91ab-4265-b705-925367374cf0/update-link/ ~~~ **Sample response** ~~~ "http://cloud.seafile.com:8082/update-api/ef881b22" ~~~ **Errors** ~~~ 500 Run out of quota ~~~ ##### Update File After getting the upload link, POST to this link for uploading files. **POST**[http://cloud.seafile.com:8082/update-api/ef881b22](http://cloud.seafile.com:8082/update-api/ef881b22) **Request parameters** - target_file **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -F file=@test.txt -F filename=test.txt -F target_file=/test.txt http://cloud.seafile.com:8082/upload-api/ef881b22 ~~~ **Returns** The id of the updated file **Sample response** ~~~ "adc83b19e793491b1c6ea0fd8b46cd9f32e592fc" ~~~ **Errors** - 400 Bad request - 440 Invalid filename - 500 Internal server error #### Get Upload Blocks Link **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/upload-blks-link/](https://cloud.seafile.com/api2/repos/{repo-id}/upload-blks-link/) **Request parameters** - repo-id **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" https://cloud.seafile.com/api2/repos/99b758e6-91ab-4265-b705-925367374cf0/upload-blks-link/ ~~~ **Sample response** ~~~ "https://cloud.seafile.com/seafhttp/upload-blks-api/c1e6823d" ~~~ **Errors** - 403 Can not access repo - 520 above quota #### Get Update Blocks Link **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/update-blks-link/](https://cloud.seafile.com/api2/repos/{repo-id}/update-blks-link/) **Request parameters** - repo-id **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" https://cloud.seafile.com/api2/repos/99b758e6-91ab-4265-b705-925367374cf0/update-blks-link/ ~~~ **Sample response** ~~~ "https://cloud.seafile.com/seafhttp/update-blks-api/c1e6823d" ~~~ **Errors** - 403 Can not access repo - 520 above quota ### [Directory]() #### List Directory Entries **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/dir/](https://cloud.seafile.com/api2/repos/{repo-id}/dir/) - repo-id - p (optional): The path to a directory. If `p` is missing, then defaults to '/' which is the top directory. - oid (optional) **Sample request** ~~~ curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d9b477fd" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/repos/99b758e6-91ab-4265-b705-925367374cf0/dir/?p=/foo ~~~ **Sample response** If oid is the latest oid of the directory, returns `"uptodate"` , else returns ~~~ [ { "id": "0000000000000000000000000000000000000000", "type": "file", "name": "test1.c", "size": 0 }, { "id": "e4fe14c8cda2206bb9606907cf4fca6b30221cf9", "type": "dir", "name": "test_dir" } ] ~~~ **Errors** - 404 The path is not exist. - 440 Repo is encrypted, and password is not provided. - 520 Operation failed.. #### Create New Directory **POST**[https://cloud.seafile.com/api2/repos/{repo-id}/dir/](https://cloud.seafile.com/api2/repos/{repo-id}/dir/) - repo-id - p - operation=mkdir (post) **Sample request** ~~~ curl -d "operation=mkdir" -v -H 'Authorization: Tokacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/dir/?p=/foo ~~~ **Sample response** ~~~ ... < HTTP/1.0 201 CREATED < Location: https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/dir/?p=/foo ... "success" ~~~ **Success** Response code 201(Created) is returned, and Location header provides the url of created directory. **Errors** - 400 Path is missing or invalid(e.g. p=/) - 520 Operation failed. **Notes** Newly created directory will be renamed if the name is duplicated. #### Rename Directory **POST**[https://cloud.seafile.com/api2/repos/{repo-id}/dir/](https://cloud.seafile.com/api2/repos/{repo-id}/dir/) **Parameters** - p (path) - operation=rename (post) - newname (the new name for directory) **Sample request** ~~~ curl -d "operation=rename&newname=pinkfloyd_newfolder" -v -H 'Authorization: Tokacd9c6ccb8133606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/dir/?p=/foo ~~~ **Success** Response code 200 if everything is ok **Errors** - 403 if You do not have permission to rename a folder - 400 if newname is not given - 520 if Failed to rename directory (generic problem) **Notes** If the new name is the same of the old name no operation will be done. #### Delete Directory **DELETE**[https://cloud.seafile.com/api2/repos/{repo-id}/dir/](https://cloud.seafile.com/api2/repos/{repo-id}/dir/) - repo-id - p **Sample request** ~~~ curl -X DELETE -v -H 'Authorization: Token f2210dacd3606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/dir/?p=/foo ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... "success" ~~~ **Success** Response code is 200(OK), and a string `"success"` is returned. **Errors** - 400 Path is missing or invalid(e.g. p=/) - 520 Operation failed. **Note** This can also be used to delete file. #### Download Directory **GET**[https://cloud.seafile.com/api2/repos/{repo-id}/dir/download/?p=/foo](https://cloud.seafile.com/api2/repos/{repo-id}/dir/download/?p=/foo) - repo-id - p **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd3606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/dir/?p=/foo ~~~ **Sample response** ~~~ "https://cloud.seafile.com:8082/files/adee6094/foo" ~~~ **Errors** - 400 Path is missing or invalid(e.g. p=/), or unable to download directory, size is too large - 404 Repo(path) not found(exist) - 520 Operation failed. #### Share Directory **POST**[https://cloud.seafile.com/api2/repos/{repo-id}/dir/share/](https://cloud.seafile.com/api2/repos/{repo-id}/dir/share/) - repo-id - emails - s_type - path - perm **Sample request** ~~~ curl -v -X POST -d "emails=user@example.com&s_type=d&path=/dir&perm=r" -H 'Authorization: Token f2210dacd3606d94ff8e61d99b477fd' -H 'Accept: application/json; charset=utf-8; indent=4' https://cloud.seafile.com/api2/repos/dae8cecc-2359-4d33-aa42-01b7846c4b32/dir/share/ ~~~ **Sample response** ~~~ ... < HTTP/1.0 200 OK ... ~~~ **Success** Response code is 200(OK). #### Batch Delete Pipelining over HTTP/1.1 can be used to delete multiple files and directories without losing performance. A sample request looks like `curl -X DELETE https://cloud.seafile.com/api2/repos/{repo-id}/dir/?p=/foo http://cloud.seafile.com/api2/repos/{repo-id}/dir/?p=/bar`. This code snippet shows how to use Python client to batch delete multiple files and directories. See [http://cloud.seafile.com/f/f7fd5d5b9d/](http://cloud.seafile.com/f/f7fd5d5b9d/) ### Get Avatar ### Get User Avatar **GET**[https://cloud.seafile.com/api2/avatars/user/{user}/resized/{size}/](https://cloud.seafile.com/api2/avatars/user/{user}/resized/{size}/) **Request parameters** - user - size **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/avatars/user/user@example.com/resized/80/ ~~~ **Sample response** ~~~ { "url": "http://127.0.0.1:8000/media/avatars/default.png", "is_default": true, "mtime": 0 } ~~~ ### Get Group Avatar **GET**[https://cloud.seafile.com/api2/avatars/group/{group_id}/resized/{size}/](https://cloud.seafile.com/api2/avatars/group/{group_id}/resized/{size}/) **Request parameters** - group_id - size **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/avatars/group/1/resized/80/ ~~~ **Sample response** ~~~ { "url": "http://127.0.0.1:8000/media/avatars/groups/default.png", "is_default": true, "mtime": 0 } ~~~ ### Get Thumbnail ### Get Thumbnail Image **GET**[https://cloud.seafile.com/api2/repos/{repo_id}/thumbnail/](https://cloud.seafile.com/api2/repos/{repo_id}/thumbnail/) **Request parameters** - repo_id - p - size **Sample request** ~~~ curl -H 'Authorization: Token 40f9a510a0629430865dc199a3880898ad2e48fc' https://cloud.seafile.com/api2/repos/fbead5d0-4817-4446-92f3-7ac8e6a8e5f5/thumbnail/?p=/5.jpg\&size=123 > thumbnail.png ~~~ ### List Group And Contacts **GET**[https://cloud.seafile.com/api2/groupandcontacts/](https://cloud.seafile.com/api2/groupandcontacts/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/groupandcontacts/" ~~~ **Sample response** ~~~ { "contacts": [ { "msgnum": 0, "mtime": 0, "lastmsg": null, "email": "user@example.com", "name": "123" } ], "umsgnum": 0, "replynum": 0, "groups": [ { "ctime": 1398134171327948, "creator": "user@example.com", "msgnum": 0, "mtime": 0, "lastmsg": null, "id": 1, "name": "lian" } ], "gmsgnum": 0, "newreplies": [] } ~~~ ### Get File Activities **GET**[https://cloud.seafile.com/api2/events/](https://cloud.seafile.com/api2/events/) **Sample request** ~~~ curl -H 'Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd' "https://cloud.seafile.com/api2/events/" ~~~ **Sample response** ~~~ {"more_offset": 16, "events":[{"repo_id": "6f3d28a4-73ae-4d01-a727-26774379dcb9", "author": "mysnowls@163.com", "nick": "lins05", "time": 1398078909, "etype": "repo-update", "repo_name": "Downloads", "desc": "Added \"seafile-cli_3.0.2_i386.tar.gz\"."},{"repo_id": "6f3d28a4-73ae-4d01-a727-26774379dcb9", "author": "mysnowls@163.com", "nick": "lins05", "time": 1398075540, "etype": "repo-update", "repo_name": "Downloads", "desc": "Added \"seafile-server_3.0.0_x86-64.tar.gz\"."}], "more": false} ~~~ ### Add Organization **POST**[https://cloud.seafile.com/api2/organization/](https://cloud.seafile.com/api2/organization/) **Request parameters** - username - password - org_name - prefix - quota - member_limit **Sample request** ~~~ curl -v -X POST -d "username=example@example.com&password=example&org_name=example&prefix=example&quota=100&member_limit=10" -H "Authorization: Token ccdff90e4d1efe76b2b3d91c06b027a5cff189d4" -H 'Accept: application/json; indent=4' https://cloud.seafile.com/api2/organization/ ~~~ **Sample response** ~~~ "success" ~~~
';

编程规范

最后更新于:2022-04-01 02:23:36

# Code Standard The source code of seafile is ISO/IEC 9899:1999 (E) (a.k.a. C99) compatible. #### Indent - Use only spaces, and indent 4 spaces at a time. #### Inline - Define functions inline only when they are sufficiently small. #### Const - We are using keyword `const` in the source.Please look into the code for detail.
';

开发环境

最后更新于:2022-04-01 02:23:34

# Setup Develop Environment ### Preparation Package names are according to Ubuntu 12.04. For other Linux distros, please find their corresponding names yourself. - libevent-dev (2.0 or later ) - libcurl4-openssl-dev (1.0.0 or later) - libglib2.0-dev (2.28 or later) - uuid-dev - intltool (0.40 or later) - libsqlite3-dev (3.7 or later) - libmysqlclient-dev (5.5 or later) - libarchive-dev - libtool - libjansson-dev - valac - libfuse-dev - python-dateutil The following libraries need to be compiled from source. - [libzdb](http://www.tildeslash.com/libzdb/dist/libzdb-2.12.tar.gz) - [libevhtp](https://github.com/ellzey/libevhtp/archive/1.1.6.zip) libzdb relies on two packages: `re2c` and `flex`.libevhtp can be build by `cmake .; make; sudo make install`. libevhtp's version should be 1.1.6 or 1.1.7. '''Seahub''' is the web front end of Seafile. It's written in the Django framework. Seahub requires Python 2.6(2.7) installed on your server, and it needs the following python libraries: - [Django1.5](https://www.djangoproject.com/download/1.5.2/tarball/) - [Djblets](https://github.com/djblets/djblets/tarball/release-0.6.14) - sqlite3 - simplejson (python-simplejson) - PIL (aka. python imaging library, python-image) or Pillow - chardet ### Download & Compile Clone [libsearpc](https://github.com/haiwen/libsearpc/), [ccnet](https://github.com/haiwen/ccnet/), [seafile](https://github.com/haiwen/seafile/), [seahub](https://github.com/haiwen/seahub/) to ~/dev (or wherever you want). Complie libsearpc with ~~~ cd ~/dev/libsearpc ./autogen.sh ./configure make make install ~~~ Compile ccnet with ~~~ cd ~/dev/ccnet ./autogen.sh ./configure --disable-client --enable-server # `export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig` if libsearpc is not found make make install ~~~ Compile seafile with ~~~ cd ~/dev/seafile ./autogen.sh ./configure --disable-client --enable-server make make install ~~~ ### Run seafile Run seafile with ~~~ cd ~/dev/seafile/tests/basic ./seafile.sh 2 ~~~ Or you can start ccnet, seafile and fileserver manually by: ~~~ ccnet-server -c ~/dev/seafile/test/basic/conf2/ -D all -f - seaf-server -c ~/dev/seafile/test/basic/conf2/ -d ~/dev/seafile/test/basic/conf2/seafile-data/ -f -l - fileserver -c ~/dev/seafile/test/basic/conf2/ -d ~/dev/seafile/test/basic/conf2/seafile-data/ -f ~~~ ### Prepare seahub Go to seahub ~~~ cd ~/dev/seahub ~~~ Download django-1.5 to thirdpart. And create and modify setenv.sh from templates ~~~ cp setenv.sh.template setenv.sh ~~~ Create database ~~~ . setenv.sh python manage.py syncdb ~~~ Create admin account (assume seafile is under ~/dev/seafile) ~~~ python tools/seahub-admin.py ~/dev/seafile/tests/basic/conf2 ~~~ Start seahub ~~~ ./run-seahub.sh.template ~~~
';

Server

最后更新于:2022-04-01 02:23:32

# Server ### Preparation The following list is all the libraries you need to install on your machine. '''You should install all of them before you build seafile'''. Package names are according to Ubuntu 12.04. For other Linux distros, please find their corresponding names yourself. - libevent-dev (2.0 or later ) - libcurl4-openssl-dev (1.0.0 or later) - libglib2.0-dev (2.28 or later) - uuid-dev - intltool (0.40 or later) - libsqlite3-dev (3.7 or later) - libmysqlclient-dev (5.5 or later) - libarchive-dev - libtool - libjansson-dev - valac - libfuse-dev The following libraries need to be compiled from source. - libzdb [[http://www.tildeslash.com/libzdb/dist/libzdb-2.12.tar.gz](http://www.tildeslash.com/libzdb/dist/libzdb-2.12.tar.gz)] - libevhtp [[https://github.com/ellzey/libevhtp/archive/1.1.6.zip](https://github.com/ellzey/libevhtp/archive/1.1.6.zip)] libzdb relies on two packages: `re2c` and `flex`.libevhtp can be build by `cmake .; make; sudo make install`. libevhtp's version should be 1.1.6 or 1.1.7. '''Seahub''' is the web front end of Seafile. It's written in the [[http://djangoproject.com](http://djangoproject.com) django] framework. Seahub requires Python 2.6(2.7) installed on your server, and it needs the following python libraries: - [[https://www.djangoproject.com/download/1.5.2/tarball/](https://www.djangoproject.com/download/1.5.2/tarball/) django 1.5] - [[https://github.com/djblets/djblets/tarball/release-0.6.14](https://github.com/djblets/djblets/tarball/release-0.6.14) djblets] - sqlite3 - simplejson (python-simplejson) - PIL (aka. python imaging library, python-image) - chardet - gunicorn The module '''argparser''' is required by the `seafile-admin` script which you'll see later. If you use Python 2.7, '''argparser''' is distributed with python's standard library, so you don't need to install it. But if you use Python 2.6, you should install it manually. Before continue, make sure you have all the above libraries available in your system. ### Prepare the directory layout In the following sections, you'll be guided to build and setup the seafile server step by step. Seafile server is consisted of several components. In order for them to function correctly, you must: - Follow our instructions step by step - Make sure your directory layout is exactly the same with the guide in each step. First create the top level directory. In the following sections, we'll use "/data/haiwen" as the top level directory. ~~~mkdir /data/haiwen/ cd /data/haiwen/ mkdir seafile-server cd seafile-server ~~~ The currently layout is: ~~~haiwen/ └── seafile-server ~~~ ### Get the source First you should get the latest source of libsearpc/ccnet/seafile/seahub Download the source tarball of the latest tag from - [[https://github.com/haiwen/libsearpc/tags](https://github.com/haiwen/libsearpc/tags)] - [[https://github.com/haiwen/ccnet/tags](https://github.com/haiwen/ccnet/tags)] - [[https://github.com/haiwen/seafile/tags](https://github.com/haiwen/seafile/tags)] - [[https://github.com/haiwen/seahub/tags](https://github.com/haiwen/seahub/tags)] For example, if the latest released seafile client is 2.0.3, then just use the '''v2.0.3-server''' tags of the four projects. You should get four tarballs: - libsearpc-2.0.3-server.tar.gz - ccnet-2.0.3-server.tar.gz - seafile-2.0.3-server.tar.gz - seahub-2.0.3-server.tar.gz Create a folder `haiwen/src`, and uncompress libsearpc/ccnet/seafile source to it. ~~~cd haiwen/seafile-server mkdir src cd src tar xf /path/to/libsearpc-2.0.3-server.tar.gz tar xf /path/to/ccnet-2.0.3-server.tar.gz tar xf /path/to/seafile-2.0.3-server.tar.gz ~~~ And uncompress seahub tarball to `haiwen/seafile-server`: ~~~cd haiwen/seafile-server tar xf /path/to/seahub-2.0.3-server.tar.gz mv seahub-2.0.3-server seahub ~~~ So far, The current directory layout is: ~~~haiwen/ └── seafile-server └── seahub └── src ├── libsearpc-2.0.3-server ├── ccnet-2.0.3-server ├── seafile-2.0.3-server ├── ... (other files) ~~~ ### Building To build seafile server, you need first build '''libsearpc''' and '''ccnet'''. ##### libsearpc ~~~cd libsearpc-${version} ./autogen.sh ./configure make make install ~~~ ##### ccnet ~~~cd ccnet-${version} ./autogen.sh ./configure --disable-client --enable-server # `export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig` if libsearpc is not found make make install ~~~ ##### seafile ~~~cd seafile-${version} ./autogen.sh ./configure --disable-client --enable-server make make install ~~~ ### Deploy Seafile Server ### Components of the Seafile Server The seafile server consists of the following components: | Process Name | Functionality | |-----|-----| | ccnet-server | underlying networking | | seaf-server | data management | | Seahub | website front-end of seafile server | | fileserver | handles raw file upload/download for Seahub | [[images/server-arch.png]] - '''ccnet''' stores its configuration and metadata is a directory named `ccnet`. - '''seaf-server''' store its configuration and data in a directory, normally named `seafile-data`. - '''seahub''' is written in Django. If you have any experience with Django, you should know the `syncdb` command must be run to create all the database tables. - An '''admin account''' has to be created, so that you, the admin, can login with this account to manage the server. These are the essential steps to create the configuration: - ensure seafile is already installed and all the python libraries seahub needs are installed. - create the ccnet configuration with the '''ccnet-init''' program - create the seafile configuration with '''seaf-server-init''' program - run Django '''syncdb''' command for seahub - create an admin account for the seafile server To create the configurations, you can either: - use the seafile-admin script(see below) - [[create server configuration by hand]] ### Create Configurations with the seafile-admin script `seafile-admin` should have been installed to system path after you have built and installed Seafile from source. ~~~usage: seafile-admin [-h] {setup,start,stop,reset-admin} ... optional arguments: -h, --help show this help message and exit subcommands: {setup,start,stop,reset-admin} setup setup the seafile server start start the seafile server stop stop the seafile server reset-admin reset seafile admin account ~~~ Go to the top level directory(in this guide it's '''/data/haiwen/'''), and run '''seafile-admin setup''' to create all the configuration: ~~~cd /data/haiwen export PYTHONPATH=/data/haiwen/seafile-server/seahub/thirdpart seafile-admin setup ~~~ The script would ask you a series of questions, and create all the configuration for you. | Name | Usage | Default | Requirement | |-----|-----|-----|-----| | server name | The name of the server that would be shown on the client | | 3 ~ 15 letters or digits | | ip or domain | The ip address or domain name of the server | | Make sure to use the right ip or domain, or the client would have trouble connecting it | | ccnet port | the tcp port used by ccnet | 10001 | | | seafile port | tcp port used by seafile | 12001 | | | seafile fileserver port | tcp port used by seafile fileserver | 8082 | | | admin email | Email address of the admin account | | | | admin password | password of the admin account | | | This is a screenshot of the '''seafile-admin setup''' command:[[images/seafile-admin-1.png]] And a screenshot after setup is finished successfully:[[images/seafile-admin-2.png]] At this time, the directory layout would be like this: ~~~haiwen/ └── ccnet # ccnet config directory └── ccnet.conf # ccnet config file └── seafile-data # seafile configuration and data └── seafile.conf # seafile config file └── seahub-data/ # seahub data └── seahub.db # seahub sqlite3 database └── seahub_settings.py # custom settings for seahub └── seafile-server └── seahub/ └── seafile-{VERSION} # seafile source code ~~~ ### Start the Seafile Server After configuration successfully created, run '''seafile-admin start''' in the top directory to start the all components of Seafile. ( '''You should always run the seafile-admin script in the top directory''' ). ~~~cd /data/haiwen # go to the top level directory seafile-admin start ~~~ At this moment, all the components should be running and seahub can be visited at '''[http://yourserver-ip-or-domain:8000](http://yourserver-ip-or-domain:8000)''' '''Note''' You may want to deploy seahub with nginx or apache. In this case, follow the instructions on [[Deploy Seafile Web With Nginx/Apache]]. ### Stop the Seafile Server To stop seafile server, run '''seafile-admin stop'''. ~~~cd /data/haiwen # go to the top level directory seafile-admin stop ~~~ ### Upgrade the Seafile Server When you want to upgrade to a new vesrion of seafile server, you need to: - Stop the seafile server if it's running ~~~cd /data/haiwen seafile-admin stop ~~~ - Get and latest source code and build libsearpc/ccnet/seafile, just as what you do in a fresh setup. - Run the upgrade script. The upgrade script mainly updates database used by seafile for you. For example, create a new database table that is used in the latest seafile server but not in the previous version. ### Get and compile the latest libsearpc/ccnet/seafile See the '''Building''' section above. ### Get the new seahub tarball and uncompress it ~~~cd haiwen/seafile-server mv seahub/ seahub-old # move away the old seahub folder tar xf /path/to/new/seahub-x.x.x-server.tar.gz mv seahub-x.x.x-server seahub ~~~ ### Do the upgrade - copy the scripts/upgrade/ subdir outside The upgrade scripts is distributed in the `scripts/upgrade` subdir of seafile source code, we need to copy it to '''seafile-server''' directory before run the scripts. ~~~cd /data/haiwen/seafile-server cp -rf seafile-{version}/scripts/upgrade . ~~~ #### Continuous Upgrade (like from 1.1 to 1.2) Continuous upgrade means to upgrade from one version of seafile server to the next version. For example, upgrading from 1.1.0 to 1.2.0 is a continuous upgrade. '''Note:''' Minor upgrade, like upgrade from 1.3.0 to 1.3.1, is documented in a separate section below. Say you are upgrading from 1.1.0 to 1.2.0, you should run the script '''upgrade_1.1_1.2.sh''' in `seafile-server` directory. ~~~cd /data/haiwen/seafile-server ./upgrade/upgrade_1.1_1.2.sh ~~~ #### Non-continous version upgrade(like from 1.1 to 1.3) If you upgrade a few versions at once, e.g. from 1.1.0 to 1.3.0. The procedure is: - upgrade from 1.1.0 to 1.2.0 - upgrade from 1.2.0 to 1.3.0 Just run the upgrade scripts in sequence. #### Minor Upgrade (like from 1.3.0 to 1.3.1) Minor upgrade Minor upgrade is like an upgrade from 1.3.0 to 1.3.1. For this type of upgrade, you only need to update the avatar link: ~~~cd /data/haiwen/seafile-server/seahub/media cp -rf avatars/* ../../../seahub-data/avatars/ rm -rf avatars ln -s ../../../seahub-data/avatars ~~~ ### Problems Report If you encounter any problem when building/deploying Seafile, please leave us a message or [[https://github.com/haiwen/seafile/issues](https://github.com/haiwen/seafile/issues) open an issue].
';

Max OS X

最后更新于:2022-04-01 02:23:29

# Mac OS X ### Setup development environment 1. Install xcode 1. Install macports Modify file `/opt/local/share/macports/Tcl/port1.0/portconfigure.tcl`, change the line ~~~ default configure.ldflags {-L${prefix}/lib} ~~~ to ~~~ default configure.ldflags {"-L${prefix}/lib -Xlinker -headerpad_max_install_names"} ~~~ 1. Install following libraries and tools using `port` ~~~ autoconf,intltool,automake, pkgconfig,libtool,glib2,ossp-uuid,libevent,vala,openssl, git-core ~~~ 1. Install python ~~~ port install python27 port select python python27 export PATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin:$PATH ~~~ Then download and install pip from [http://pypi.python.org/pypi/pip](http://pypi.python.org/pypi/pip) 1. Set pkg config environment ~~~ export PKG_CONFIG_PATH=/opt/local/lib/pkgconfig:/usr/local/lib/pkgconfig ~~~ ### Compiling libsearpc Download [libsearpc](https://github.com/haiwen/libsearpc), then: ~~~ ./autogen.sh LDFLAGS="-Xlinker -headerpad_max_install_names" ./configure make sudo make install ~~~ ### Compiling ccnet Download [ccnet](https://github.com/haiwen/ccnet), then: ~~~ ./autogen.sh CFLAGS="-Wall" LDFLAGS="-L/opt/local/lib -Xlinker -headerpad_max_install_names" ./configure make sudo make install ~~~ ### Compiling seafile 1. Download [seafile](https://github.com/haiwen/seafile) 1. Install python libs and tools ~~~ sudo pip-2.7 install py2app web.py mako simplejson ~~~ 1. Compile ~~~ ./autogen.sh LDFLAGS="-L/opt/local/lib -Xlinker -headerpad_max_install_names -framework CoreServices" ./configure make sudo make install ~~~ ### Packaging 1. seafileweb. First setup python path: ~~~ export PYTHONPATH=.:/usr/local/lib/python2.7/site-packages ~~~ This path is where pyccnet and pysearpc installed. ~~~ ./setupmac.sh web ~~~ This will generate `seafileweb.app`, and copy it to `gui/mac/seafile` 1. ccnet, seaf-daemon: ~~~ ./setupmac.sh dylib ~~~ This will copy ccnet, seaf-daemon and other libraries to gui/mac/seafile, and use `install_name_tool` to modify the library paths in ccnet, seaf-daemon. 1. Compile seafile.app: ~~~ ./setupmac.sh 10.6 or ./setupmac.sh 10.7 ~~~ After compiling, it will copy seafile.app to `${top_dir}/../seafile-${VERSION}`. You can also compiling seafile.app in xcode. 1. Go to seafile-${VERSION} and see if it can run correctly. 1. Construct dmg using dropdmg. Use `dmg-backgroud.jpg` as dmg background, add link of `/Application` to seafile-${VERSION}, then packaging seafile-${VERSION} to seafile-${VERSION}.dmg. ### Problem you may encounter 1. If `install_name_tool` reports "malformed object" "unknown load command", It may be the version of xcode command line tools incompatible with `install_name_tool`. 1. If xcode can't find glib, Corrects xcode's "build settings/search paths/header search".
';

Windows

最后更新于:2022-04-01 02:23:27

# Windows
';

Linux

最后更新于:2022-04-01 02:23:25

# Linux #### Preparation The following list is what you need to install on your development machine. **You should install all of them before you build seafile**. Package names are according to Ubuntu 12.04. For other Linux distros, please find their corresponding names yourself. - autoconf/automake/libtool - libevent-dev ( 2.0 or later ) - libcurl4-openssl-dev (1.0.0 or later) - libgtk2.0-dev ( 2.24 or later) - uuid-dev - intltool (0.40 or later) - libsqlite3-dev (3.7 or later) - valac (only needed if you build from git repo) - libjansson-dev - libqt4-dev - valac - cmake - libfuse-dev (for seafile >= 2.1) - python-simplejson (for seaf-cli) ~~~ sudo apt-get install autoconf automake libtool libevent-dev libcurl4-openssl-dev libgtk2.0-dev uuid-dev intltool libsqlite3-dev valac libjansson-dev libqt4-dev cmake libfuse-dev ~~~ For a fresh Fedora 20 installation, the following will install all dependencies via YUM: ~~~ $ sudo yum install wget gcc libevent-devel openssl-devel gtk2-devel libuuid-devel sqlite-devel jansson-devel intltool cmake qt-devel fuse-devel libtool vala gcc-c++ ~~~ #### Building First you should get the latest source of libsearpc/ccnet/seafile/seafile-client: Download the source tarball of the latest tag from - [https://github.com/haiwen/libsearpc/tags](https://github.com/haiwen/libsearpc/tags) (use v3.0-latest) - [https://github.com/haiwen/ccnet/tags](https://github.com/haiwen/ccnet/tags) - [https://github.com/haiwen/seafile/tags](https://github.com/haiwen/seafile/tags) - [https://github.com/haiwen/seafile-client/tags](https://github.com/haiwen/seafile-client/tags) For example, if the latest released seafile client is 3.0.2, then just use the **v3.0.2** tags of the four projects. You should get four tarballs: - libsearpc-v3.0-latest.tar.gz - ccnet-3.0.2.tar.gz - seafile-3.0.2.tar.gz - seafile-client-3.0.2.tar.gz ~~~ export version=3.0.2 alias wget='wget --content-disposition -nc' wget https://github.com/haiwen/libsearpc/archive/v3.0-latest.tar.gz wget https://github.com/haiwen/ccnet/archive/v${version}.tar.gz wget https://github.com/haiwen/seafile/archive/v${version}.tar.gz wget https://github.com/haiwen/seafile-client/archive/v${version}.tar.gz ~~~ Now uncompress them: ~~~ tar xf libsearpc-v3.0-latest.tar.gz tar xf ccnet-${version}.tar.gz tar xf seafile-${version}.tar.gz tar xf seafile-client-${version}.tar.gz ~~~ To build Seafile client, you need first build **libsearpc** and **ccnet**, **seafile**. ##### set paths ~~~ export PREFIX=/usr export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH" export PATH="$PREFIX/bin:$PATH" ~~~ ##### libsearpc ~~~ cd libsearpc-${version} ./autogen.sh ./configure --prefix=$PREFIX make sudo make install ~~~ ##### ccnet ~~~ cd ccnet-${version} ./autogen.sh ./configure --prefix=$PREFIX make sudo make install ~~~ ##### seafile ~~~ cd seafile-${version}/ ./autogen.sh ./configure --prefix=$PREFIX --disable-gui make sudo make install ~~~ #### seafile-client ~~~ cd seafile-client-${version} cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PREFIX . make sudo make install ~~~ #### custom prefix when installing to a custom `$PREFIX`, i.e. `/opt`, you may need a script to set the path variables correctly ~~~ cat >$PREFIX/bin/seafile-applet.sh <<END #!/bin/bash export LD_LIBRARY_PATH="$PREFIX/lib:$LD_LIBRARY_PATH" export PATH="$PREFIX/bin:$PATH" exec seafile-applet $@ END cat >$PREFIX/bin/seaf-cli.sh <<END export LD_LIBRARY_PATH="$PREFIX/lib:$LD_LIBRARY_PATH" export PATH="$PREFIX/bin:$PATH" export PYTHONPATH=$PREFIX/lib/python2.7/site-packages exec seaf-cli $@ END chmod +x $PREFIX/bin/seafile-applet.sh $PREFIX/bin/seaf-cli.sh ~~~ you can now start the client with `$PREFIX/bin/seafile-applet.sh`.
';

编译 Seafile

最后更新于:2022-04-01 02:23:23

# How to Build Seafile You can build Seafile from our source code package or from the Github repo directly. Client - [Linux](#) - [Max OS X](#) Server - [Build Seafile server](#)
';

开发文档

最后更新于:2022-04-01 02:23:20

# Develop Documents - [How to Build Seafile](#) - [How to Setup Develop Envirnoment](#) - [Seafile Code Standard](#) Seafile Open API - [Seafile Web API](#) - [Seafile Python API](#) Seafile Implement Detail - [Seafile Data Model](#) - [Seafile Server Components](#) - [Seafile Sync algorithm](#)
';

日志和审计

最后更新于:2022-04-01 02:23:18

# Access log and auditing In pro edition, Seafile offers four auditing logs in system admin panel: - Login log - File access log - File update log - Permission change log The logging feature is turned off by default. See [config options for pro edition](#) for how to turn it on. ### file access log Access log (under directory logs/stats-logs) records the following information - file download via Web - file download via API (including mobile clients and cloud file browser) - file sync via desktop clients The format is: ~~~ user, operation type, ip/device, date, library, path. ~~~ ### file update log The format is: ~~~ user, date, library, path, detail ~~~ ### permission change log The format is: ~~~ user, grant to, operation, permission, library, folder, date ~~~
';

安全特性

最后更新于:2022-04-01 02:23:16

# 安全机制 ### 客户端和服务器间的通信加密 Seafile 在服务器配置了 HTTPS 后,客户端会自动使用 HTTPS 协议和服务器通信。 ### 加密资料库如何工作? 当你创建一个加密资料库,你将为其提供一个密码。所有资料库中的数据在上传到服务器之前都将用密码进行加密。 加密流程: 1. 生成一个32字节长的加密的强随机数。它将被用作文件加密键(“文件键”)。 1. 用用户提供的密码对文件键进行加密。我们首先用PBKDF2算法从密码中获取到一个键/值对,然后用AES 256/CBC来加密文件键,所得结果被称之为“加密的文件键”。加密的文件键将会被发送到服务器并保存下来。当你需要访问那部分数据,你可以从加密的文件键中解密出文件键。 1. 所有的文件数据都将用AES 256/CBC加密的文件键进行加密。我们用PBKDF2算法从文件键中获取键/值对。加密完成后,数据将会被传送到服务器端。 上述加密过程即可在桌面客户端执行也可在网站浏览器中执行。浏览器端加密功能可在服务器端使用。当你从加密的资料库中上传和下载时,如下过程将会发生: - 服务器端发回加密的数据,浏览器将会在客户端用JavaScript解密它们。 - 浏览器在客户端用JavaScript加密后,将加密后的数据发回服务器。服务器端直接保存加密后的结果。 在上述过程中,你的密码将不会在服务器端传输。 当你同步一个加密资料库到桌面客户端或者在网站浏览器中浏览一个资料库,桌面客户端/浏览器需要确认你的密码。当你创建一个资料库,一个“魔力标志”将会在密码和资料库id中获得。这个标志和资料库一起存储到服务器端。客户端用这个标志检查你的密码是否正确在你同步和浏览资料库之前。魔力标志是通过PBKDF2算法经过1000次迭代产生,所以它将非常安全抵抗蛮力破解。 为了最大安全性,纯文本的密码也不会保存在客户端。客户端只保存从“文件键”获得的键/值对,它用来解密数据。所以如果你忘记密码,你将不能恢复和访问服务器端的数据。
';

安全选项

最后更新于:2022-04-01 02:23:13

# 安全和审计 ### 安全特性 - [安全特性](#) ### 访问日志和审计 - [访问日志和审计](#)
';

FUSE 扩展

最后更新于:2022-04-01 02:23:11

# FUSE扩展 在Seafile系统上文件被分割成数据块,这意味着在你的Seafile服务器上存储的并不是完整的文件而是数据块。这种设计能够方便有效的运用数据去重技术。 然而,有时系统管理员想要直接访问服务器上的文件,你可以使用seaf-fuse来做到这点。 `Seaf-fuse`是一种[FUSE](http://fuse.sourceforge.net)虚拟文件系统的实现. 一句话来说就是,它挂载所有的Seafile文件到一个目录(它被称为'''挂载点'''),所以你可以像访问服务器上的正常目录一样来访问由Seafile服务器管理的所有文件。 `注意:` - 加密的目录不可以被seaf-fuse来访问。 - Seaf-fuse的当前实现是只读访问,这意味着你不能通过挂载的目录来修改文件。 - 对于debian/centos系统,你需要在“fuse”组才有权限来挂载一个FUSE目录。 ### 如何启动seaf-fuse 假设你想挂载到`/data/seafile-fuse`. #### 创建一个目录作为挂载点 ~~~mkdir -p /data/seafile-fuse ~~~ #### 用脚本来启动seaf-fuse `注意:` 在启动seaf-fuse之前, 你应该已经通过执行`./seafile.sh start`启动好Seafile服务器。 ~~~./seaf-fuse.sh start /data/seafile-fuse ~~~ #### 停止seaf-fuse ~~~./seaf-fuse.sh stop ~~~ ### 挂载目录的内容 #### 顶层目录 现在你可以列出`/data/seafile-fuse`目录的内容 ~~~$ ls -lhp /data/seafile-fuse drwxr-xr-x 2 root root 4.0K Jan 1 1970 abc@abc.com/ drwxr-xr-x 2 root root 4.0K Jan 1 1970 foo@foo.com/ drwxr-xr-x 2 root root 4.0K Jan 1 1970 plus@plus.com/ drwxr-xr-x 2 root root 4.0K Jan 1 1970 sharp@sharp.com/ drwxr-xr-x 2 root root 4.0K Jan 1 1970 test@test.com/ ~~~ - 顶层目录包含许多子目录,每个子目录对应一个用户 - 文件和目录的时间戳不会被保存 #### 每个用户的目录 ~~~$ ls -lhp /data/seafile-fuse/abc@abc.com drwxr-xr-x 2 root root 924 Jan 1 1970 5403ac56-5552-4e31-a4f1-1de4eb889a5f_Photos/ drwxr-xr-x 2 root root 1.6K Jan 1 1970 a09ab9fc-7bd0-49f1-929d-6abeb8491397_My Notes/ ~~~ 从上面的列表可以看出,在用户目录下有一些子目录,每个子目录代表此用户的一个资料库,并且以'''{库id}-{库名字}'''的格式来命名。 #### 资料库的目录 ~~~$ ls -lhp /data/seafile-fuse/abc@abc.com/5403ac56-5552-4e31-a4f1-1de4eb889a5f_Photos/ -rw-r--r-- 1 root root 501K Jan 1 1970 image.png -rw-r--r-- 1 root root 501K Jan 1 1970 sample.jpng ~~~ #### 如果出现"Permission denied"的错误 如果你运行`./seaf-fuse.sh start`时,遇到"Permission denied"的错误信息, 很有可能你没有在“fuse用户组”解决方法: - 把你的用户加到fuse组 ~~~sudo usermod -a -G fuse ~~~ - 退出shell重新登陆 - 现在试着再一次执行`./seaf-fuse.sh start <path>`。
';

WebDAV 扩展

最后更新于:2022-04-01 02:23:09

# WebDAV扩展 Seafile WebDAV Server(SeafDAV)在Seafile Server 2.1.0版本中被加入. 在下面的维基中, 我们假设你将Seafile安装到`/data/haiwen`目录下。 ### SeafDAV配置 SeafDAV配置文件是`/data/haiwen/conf/seafdav.conf`. 如果它还没有被创建,你可以自行创建它。 ~~~[WEBDAV] # 默认值是false。改为true来使用SeafDAV server。 enabled = true port = 8080 # 如果fastcgi将被使用则更改fastcgi的值为true。 fastcgi = false # 如果你将seafdav部署到nginx/apache,你需要更改“share_name”的值。 share_name = / ~~~ 每次配置文件被修改后,你需要重启Seafile服务器使之生效。 ~~~./seafile.sh restart ~~~ ### 示例配置 1: No nginx/apache 你的WebDAV客户端将在地址`[http://example.com:8080](http://example.com:8080)`访问WebDAV服务器。 ~~~[WEBDAV] enabled = true port = 8080 fastcgi = false share_name = / ~~~ ### 示例配置 2: With Nginx/Apache 你的WebDAV客户端将在地址`[http://example.com/seafdav](http://example.com/seafdav)`访问WebDAV服务器。 ~~~[WEBDAV] enabled = true port = 8080 fastcgi = true share_name = /seafdav ~~~ 在上面的配置中,'''share_name'''的值被改为'''/seafdav''', 它是你指定给seafdav服务器的地址后缀。 #### Nginx 无 HTTPS 相应的Nginx配置如下 (无 https): ~~~ location /seafdav { fastcgi_pass 127.0.0.1:8080; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; client_max_body_size 0; access_log /var/log/nginx/seafdav.access.log; error_log /var/log/nginx/seafdav.error.log; } ~~~ #### Nginx 有 HTTPS Nginx配置为https: ~~~ location /seafdav { fastcgi_pass 127.0.0.1:8080; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; client_max_body_size 0; fastcgi_param HTTPS on; access_log /var/log/nginx/seafdav.access.log; error_log /var/log/nginx/seafdav.error.log; } ~~~ #### Apache 首先编辑 `apache2.conf` 文件, 添加如下这行到文件结尾(或者根据你的Linux发行版将其添加到 `httpd.conf`): ~~~FastCGIExternalServer /var/www/seafdav.fcgi -host 127.0.0.1:8080 ~~~ 注意, `/var/www/seafdav.fcgi` 仅仅只是一个占位符, 实际在你的系统并不需要有此文件。 第二, 修改Apache配置文件 (site-enabled/000-default): #### Apache 无 HTTPS 根据你的Apache配置当你[将要部署 Seafile 和 Apache|已经部署 Seafile 和 Apache], 加入Seafdav的相关配置: ~~~ ServerName www.myseafile.com DocumentRoot /var/www Alias /media /home/user/haiwen/seafile-server/seahub/media RewriteEngine On # # seafile fileserver # ProxyPass /seafhttp http://127.0.0.1:8082 ProxyPassReverse /seafhttp http://127.0.0.1:8082 RewriteRule ^/seafhttp - [QSA,L] # # seafile webdav # RewriteCond %{HTTP:Authorization} (.+) RewriteRule ^(/seafdav.*)$ /seafdav.fcgi$1 [QSA,L,e=HTTP_AUTHORIZATION:%1] RewriteRule ^(/seafdav.*)$ /seafdav.fcgi$1 [QSA,L] # # seahub # RewriteRule ^/(media.*)$ /$1 [QSA,L,PT] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /seahub.fcgi$1 [QSA,L,E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] ~~~ #### Apache 有 HTTPS 根据你的apache配置当你[配置Seafile网站和Apache并启用Https](#), 加入seafdav的相关配置: ~~~ ServerName www.myseafile.com DocumentRoot /var/www Alias /media /home/user/haiwen/seafile-server/seahub/media SSLEngine On SSLCertificateFile /etc/ssl/cacert.pem SSLCertificateKeyFile /etc/ssl/privkey.pem RewriteEngine On # # seafile fileserver # ProxyPass /seafhttp http://127.0.0.1:8082 ProxyPassReverse /seafhttp http://127.0.0.1:8082 RewriteRule ^/seafhttp - [QSA,L] # # seafile webdav # RewriteCond %{HTTP:Authorization} (.+) RewriteRule ^(/seafdav.*)$ /seafdav.fcgi$1 [QSA,L,e=HTTP_AUTHORIZATION:%1] RewriteRule ^(/seafdav.*)$ /seafdav.fcgi$1 [QSA,L] # # seahub # RewriteRule ^/(media.*)$ /$1 [QSA,L,PT] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /seahub.fcgi$1 [QSA,L,E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] ~~~ ### 关于客户端的注意事项 ### Windows 在Windows平台,我们推荐使用webdav客户端软件例如Cyberduck或BitKinex.webdav对于Windows浏览器的支持实现并不是十分可用,因为: ~~~ Windows 浏览器需要利用HTTP数字认证。但是由于Seafile在服务器端不存储纯文本密码,所以它不支持这个特性。HTTP基本认证只被HTTPS支持(这是合理的)。但是浏览器不支持自我签署的证书。 ~~~ 结论就是如果你有一个合法的ssl证书,你应该能过通过Windows浏览器来访问seafdav。否则你应该使用客户端软件。Windows XP被声明不支持HTTPS webdav. ### Linux 在Linux平台你有更多的选择。你可以利用文件管理器例如Nautilus来连接webdav服务器,或者在命令行使用davfs2。 使用davfs2 ~~~sudo apt-get install davfs2 sudo mount -t davfs -o uid= https://example.com/seafdav /media/seafdav/ ~~~ -o选项设置挂载目录的拥有者为,使得非root用户拥有可写权限。 我们建议对于davfs2,禁用锁操作。你需要编辑/etc/davfs2/davfs2.conf ~~~ use_locks 0 ~~~ ### Mac OS X Finder对于WebDAV的支持不稳定而且较慢. 所以我们建议使用webdav客户端软件如Cyberduck. ### 常见问题 ### 客户端无法连接seafdav服务器 默认, seafdav是未被启用的。检查你是否在`seafdav.conf`中设置`enabled = true`。 如果没有,更改配置文件并重启seafle服务器。 ### 客户端得到"Error: 404 Not Found"错误 如果你将SeafDAV部署在Nginx/Apache, 请确保像上面的配置文件一样更改`share_name`的值。重启Seafile服务器后重新测试。
';

WebDAV 和 FUSE 扩展

最后更新于:2022-04-01 02:23:06

# WebDAV和FUSE扩展 Seafile WebDAV和FUSE扩展使得Seafile能够很容易的与第三方应用协调工作。例如,你可以在IOS上通过WebDAV接口访问Seafile上的文件。
';

Seafile GC

最后更新于:2022-04-01 02:23:04

# Seafile GC Seafile 利用存储去重技术来减少存储资源的利用。简单来说,这包含如下两层含义: - 不同版本的文件或许会共享一些数据块。 - 不同的资料库也或许会共享一些数据块。 运用这项技术之后,在你删除一个资料库时,会导致底层数据块不会被立即删除,因此 Seafile 服务器端没用的数据块将会增多。 通过运行**垃圾回收**程序,可以清理无用的数据块,释放无用数据块所占用的存储空间。 垃圾回收程序将会清理如下两种无用数据块: 1. 未被资料库所引用的数据块即数据块属于被删除的资料库。 1. 设置了历史长度限制的资料库的过期数据块。 **如果使用社区版服务器,运行垃圾回收程序之前,请先在服务器端停掉 Seafile 程序。这是因为垃圾回收程序,会错误的删除刚刚写入 Seafile 的新的数据块。对于专业版,3.1.11 及之后的版本,支持在线垃圾回收即如果使用 MySQL 或 PostgreSQL 数据库,你不需要暂停 Seafile 程序来进行垃圾回收。** ### 4.1.1 及之后的版本 从社区版 4.1.1 和 专业版 4.1.0开始, 我们改善了垃圾回收的命令参数和执行结果输出。 ### Dry-run 模式 如果仅为了查看有多少垃圾可以回收而不进行删除操作,用 dry-run 选项: ~~~ seaf-gc.sh --dry-run [repo-id1] [repo-id2] ... ~~~ 运行输出如下所示: ~~~ [03/19/15 19:41:49] seafserv-gc.c(115): GC version 1 repo My Library(ffa57d93) [03/19/15 19:41:49] gc-core.c(394): GC started. Total block number is 265. [03/19/15 19:41:49] gc-core.c(75): GC index size is 1024 Byte. [03/19/15 19:41:49] gc-core.c(408): Populating index. [03/19/15 19:41:49] gc-core.c(262): Populating index for repo ffa57d93. [03/19/15 19:41:49] gc-core.c(308): Traversed 5 commits, 265 blocks. [03/19/15 19:41:49] gc-core.c(440): Scanning unused blocks. [03/19/15 19:41:49] gc-core.c(472): GC finished. 265 blocks total, about 265 reachable blocks, 0 blocks can be removed. [03/19/15 19:41:49] seafserv-gc.c(115): GC version 1 repo aa(f3d0a8d0) [03/19/15 19:41:49] gc-core.c(394): GC started. Total block number is 5. [03/19/15 19:41:49] gc-core.c(75): GC index size is 1024 Byte. [03/19/15 19:41:49] gc-core.c(408): Populating index. [03/19/15 19:41:49] gc-core.c(262): Populating index for repo f3d0a8d0. [03/19/15 19:41:49] gc-core.c(308): Traversed 8 commits, 5 blocks. [03/19/15 19:41:49] gc-core.c(264): Populating index for sub-repo 9217622a. [03/19/15 19:41:49] gc-core.c(308): Traversed 4 commits, 4 blocks. [03/19/15 19:41:49] gc-core.c(440): Scanning unused blocks. [03/19/15 19:41:49] gc-core.c(472): GC finished. 5 blocks total, about 9 reachable blocks, 0 blocks can be removed. [03/19/15 19:41:49] seafserv-gc.c(115): GC version 1 repo test2(e7d26d93) [03/19/15 19:41:49] gc-core.c(394): GC started. Total block number is 507. [03/19/15 19:41:49] gc-core.c(75): GC index size is 1024 Byte. [03/19/15 19:41:49] gc-core.c(408): Populating index. [03/19/15 19:41:49] gc-core.c(262): Populating index for repo e7d26d93. [03/19/15 19:41:49] gc-core.c(308): Traversed 577 commits, 507 blocks. [03/19/15 19:41:49] gc-core.c(440): Scanning unused blocks. [03/19/15 19:41:49] gc-core.c(472): GC finished. 507 blocks total, about 507 reachable blocks, 0 blocks can be removed. [03/19/15 19:41:50] seafserv-gc.c(124): === Repos deleted by users === [03/19/15 19:41:50] seafserv-gc.c(145): === GC is finished === [03/19/15 19:41:50] Following repos have blocks to be removed: repo-id1 repo-id2 repo-id3 ~~~ 如果在参数中指定资料库 ID,则程序只检查指定的资料库,否则所有的资料库将会被检查。 在程序输出的结尾,你会看到 "repos have blocks to be removed" 部分,这部分内容会列出含有可回收垃圾块的资料库的 ID,后续你可以运行程序不加 --dry-run 选项来回收这些资料库的垃圾数据块。 ### 删除垃圾数据块 运行垃圾回收程序,不加 --dry-run 选项来删除垃圾数据块: ~~~ seaf-gc.sh [repo-id1] [repo-id2] ... ~~~ 如果在参数中指定资料库 ID, 则程序只检查和删除指定的资料库。 正如前面所说,有两种类型的垃圾数据块可被回收,有时仅删除第一类无用数据块(属于删除的资料库)便可达到回收的目的,这种情况下,垃圾回收程序将不会检查未被删除的资料库,加入 “-r” 选项便可实现这个功能: ~~~ seaf-gc.sh -r ~~~ **Seafile 4.1.1 及之后的版本,被用户删除的资料库不会直接从系统中删除,它们会被转移到系统管理员界面的**垃圾箱**。垃圾箱中的资料库,只有在从垃圾箱中清除以后,它们的数据块才可被回收。** ### 3.1.2 及之后版本 运行垃圾回收程序 ~~~ ./seaf-gc.sh run ~~~ 程序结束之后,运行以下命令,检查是否误删了还在使用的数据块,如果误删,会显示警告信息。 ~~~ ./seaf-gc.sh verify ~~~ 可以通过 `dry-run` 选项,设置在运行垃圾回收程序前,进行完整性检查 程序将会显示 *所有的数据块数量* 和 *将要被删除的数据块数量* ~~~ ./seaf-gc.sh dry-run ~~~ 如果资料库已损坏,因为无法判断数据块是否还在被其他资料库使用,所以垃圾回收程序将会停止运行。 可以通过 `force` 选项,强制删除已损坏资料库的数据。通过将已损坏资料库的数据块标记为“未使用”,来将其删除。 ~~~ ./seaf-gc.sh force ~~~ ### 3.1.2 及之前版本 运行垃圾回收程序 ~~~ cd seafile-server-{version}/seafile export LD_LIBRARY_PATH=./lib:${LD_LIBRARY_PATH} ./bin/seafserv-gc -c ../../ccnet -d ../../seafile-data ~~~ 如果你[源码编译安装 Seafile 服务器](#),仅仅运行 ~~~ seafserv-gc -c ../../ccnet -d ../../seafile-data ~~~ 当垃圾回收程序结束后,你也可以检查是否一些有用的数据块被错误的删除: ~~~ seafserv-gc -c ../../ccnet -d ../../seafile-data --verify ~~~ 如果一些有用的数据块丢失,它将会打印一些警告信息。 如果你想在真正删除一些数据块之前,做一些常规检查,可以使用--dry-run选项 ~~~ seafserv-gc -c ../../ccnet -d ../../seafile-data --dry-run ~~~ 这将会向你展示数据块总数量和将被删除数据块数量。 如果在服务器端一些库的元数据被毁坏,垃圾回收程序将会停止处理,因为它无法识别是否一个数据块被一些毁坏的资料库所使用。如果你不想保留毁坏库的数据块,可以运行垃圾回收程序并使用--ignore-errors或-i选项。 ~~~ seafserv-gc -c ../../ccnet -d ../../seafile-data --ignore-errors ~~~ 这将会屏蔽毁坏资料库的数据块为无用状态并删除掉它们。
';