from .service import seafserv_threaded_rpc, ccnet_threaded_rpc from pysearpc import SearpcError import json """ General rules for return values and exception handling of Seafile python API: - Read operations return corresponding values. Raises exceptions on parameter errors or I/O errors in seaf-server. - Write or set operations return 0 on success, -1 on error. On error, an exceptioin will be raised. All paths in parameters can be in absolute path format (like '/test') or relative path format (like 'test'). The API can handle both formats. """ REPO_STATUS_NORMAL = 0 REPO_STATUS_READ_ONLY = 1 class SeafileAPI(object): def __init__(self): pass # fileserver token def get_fileserver_access_token(self, repo_id, obj_id, op, username, use_onetime=True): """Generate token for access file/dir in fileserver op: the operation, can be 'view', 'download', 'download-dir', 'downloadblks', 'upload', 'update', 'upload-blks-api', 'upload-blks-aj', 'update-blks-api', 'update-blks-aj' Return: the access token in string """ onetime = 1 if bool(use_onetime) else 0 return seafserv_threaded_rpc.web_get_access_token(repo_id, obj_id, op, username, onetime) def query_fileserver_access_token(self, token): """Get the WebAccess object token: the access token in string Return: the WebAccess object (lib/webaccess.vala) """ return seafserv_threaded_rpc.web_query_access_token(token) def query_zip_progress(self, token): """Query zip progress for download-dir, download-multi token: obtained by get_fileserver_access_token Return: json formated string `{"zipped":, "total":}`, otherwise None. """ return seafserv_threaded_rpc.query_zip_progress(token) def cancel_zip_task(self, token): return seafserv_threaded_rpc.cancel_zip_task(token) # password def is_password_set(self, repo_id, username): """ Return non-zero if True, otherwise 0. """ return seafserv_threaded_rpc.is_passwd_set(repo_id, username) def get_decrypt_key(self, repo_id, username): """ Return: a CryptKey object (lib/crypt.vala) """ return seafserv_threaded_rpc.get_decrypt_key(repo_id, username) def change_repo_passwd(self, repo_id, old_passwd, new_passwd, user): return seafserv_threaded_rpc.change_repo_passwd(repo_id, old_passwd, new_passwd, user) def check_passwd(self, repo_id, magic): return seafserv_threaded_rpc.check_passwd(repo_id, magic) def set_passwd(self, repo_id, user, passwd): return seafserv_threaded_rpc.set_passwd(repo_id, user, passwd) def unset_passwd(self, repo_id, user): return seafserv_threaded_rpc.unset_passwd(repo_id, user) def generate_magic_and_random_key(self, enc_version, repo_id, password): return seafserv_threaded_rpc.generate_magic_and_random_key(enc_version, repo_id, password) # repo manipulation def create_repo(self, name, desc, username, passwd=None, enc_version=2, storage_id=None): return seafserv_threaded_rpc.create_repo(name, desc, username, passwd, enc_version) def create_enc_repo(self, repo_id, name, desc, username, magic, random_key, salt, enc_version): return seafserv_threaded_rpc.create_enc_repo(repo_id, name, desc, username, magic, random_key, salt, enc_version) def get_repo(self, repo_id): """ Return: a Repo object (lib/repo.vala) """ return seafserv_threaded_rpc.get_repo(repo_id) def remove_repo(self, repo_id): return seafserv_threaded_rpc.remove_repo(repo_id) def get_repo_list(self, start, limit, order_by=None): """ Return: a list of Repo objects (lib/repo.vala) """ return seafserv_threaded_rpc.get_repo_list(start, limit, order_by) def count_repos(self): return seafserv_threaded_rpc.count_repos() def edit_repo(self, repo_id, name, description, username): return seafserv_threaded_rpc.edit_repo(repo_id, name, description, username) def is_repo_owner(self, username, repo_id): """ Return 1 if True, otherwise 0. """ return seafserv_threaded_rpc.is_repo_owner(username, repo_id) def set_repo_owner(self, email, repo_id): return seafserv_threaded_rpc.set_repo_owner(email, repo_id) def get_repo_owner(self, repo_id): """ Return: repo owner in string """ return seafserv_threaded_rpc.get_repo_owner(repo_id) def get_owned_repo_list(self, username, ret_corrupted=False, start=-1, limit=-1): """ Return: a list of Repo objects """ return seafserv_threaded_rpc.list_owned_repos(username, 1 if ret_corrupted else 0, start, limit) def search_repos_by_name(self, name): return seafserv_threaded_rpc.search_repos_by_name(name) def get_orphan_repo_list(self): return seafserv_threaded_rpc.get_orphan_repo_list() def get_repo_size(self, repo_id): return seafserv_threaded_rpc.server_repo_size(repo_id) def revert_repo(self, repo_id, commit_id, username): return seafserv_threaded_rpc.revert_on_server(repo_id, commit_id, username) def diff_commits(self, repo_id, old_commit, new_commit, fold_dir_diff = 1): """ Return: a list of DiffEntry objects (lib/repo.vala) """ return seafserv_threaded_rpc.get_diff(repo_id, old_commit, new_commit, fold_dir_diff) def get_commit_list(self, repo_id, offset, limit): """ Return: a list of Commit objects (lib/commit.vala) """ return seafserv_threaded_rpc.get_commit_list(repo_id, offset, limit) def get_commit(self, repo_id, repo_version, cmt_id): """ Get a commit. """ try: ret = seafserv_threaded_rpc.get_commit(repo_id, repo_version, cmt_id) except SearpcError: ret = None return ret def get_system_default_repo_id (self): return seafserv_threaded_rpc.get_system_default_repo_id() def get_org_id_by_repo_id (self, repo_id): return seafserv_threaded_rpc.get_org_id_by_repo_id(repo_id) def set_repo_status (self, repo_id, status): return seafserv_threaded_rpc.set_repo_status(repo_id, status) def get_repo_status (self, repo_id): return seafserv_threaded_rpc.get_repo_status(repo_id) # File property and dir listing def is_valid_filename(self, repo_id, filename): """ Return: 0 on invalid; 1 on valid. """ return seafserv_threaded_rpc.is_valid_filename(repo_id, filename) def get_file_size(self, store_id, version, file_id): return seafserv_threaded_rpc.get_file_size(store_id, version, file_id) def get_dir_size(self, store_id, version, dir_id): """ Return the size of a dir. It needs to recursively calculate the size of the dir. It can cause great delay before returning. Use with caution! """ return seafserv_threaded_rpc.get_dir_size(store_id, version, dir_id) def get_file_id_by_path(self, repo_id, path): """ Returns None if path not found. Only raise exception on parameter or IO error. """ return seafserv_threaded_rpc.get_file_id_by_path(repo_id, path) def get_file_id_by_commit_and_path(self, repo_id, commit_id, path): return seafserv_threaded_rpc.get_file_id_by_commit_and_path(repo_id, commit_id, path) def get_dirent_by_path(self, repo_id, path): """ Return: a Dirent object (lib/dirent.vala) """ return seafserv_threaded_rpc.get_dirent_by_path(repo_id, path) def list_file_by_file_id(self, repo_id, file_id, offset=-1, limit=-1): # deprecated, use list_blocks_by_file_id instead. return seafserv_threaded_rpc.list_file_blocks(repo_id, file_id, offset, limit) def list_blocks_by_file_id(self, repo_id, file_id, offset=-1, limit=-1): """ list block ids of a file. Return: a string containing block list. Each id is seperated by '\n' """ return seafserv_threaded_rpc.list_file_blocks(repo_id, file_id, offset, limit) def get_dir_id_by_path(self, repo_id, path): return seafserv_threaded_rpc.get_dir_id_by_path(repo_id, path) def list_dir_by_dir_id(self, repo_id, dir_id, offset=-1, limit=-1): """ Return: a list of Dirent objects. The objects are sorted as follows: - Directories are always before files - Entries are sorted by names in ascending order """ return seafserv_threaded_rpc.list_dir(repo_id, dir_id, offset, limit) def list_dir_by_path(self, repo_id, path, offset=-1, limit=-1): dir_id = seafserv_threaded_rpc.get_dir_id_by_path(repo_id, path) if dir_id is None: return None return seafserv_threaded_rpc.list_dir(repo_id, dir_id, offset, limit) def list_dir_by_commit_and_path(self, repo_id, commit_id, path, offset=-1, limit=-1): dir_id = seafserv_threaded_rpc.get_dir_id_by_commit_and_path(repo_id, commit_id, path) if dir_id is None: return None return seafserv_threaded_rpc.list_dir(repo_id, dir_id, offset, limit) def get_dir_id_by_commit_and_path(self, repo_id, commit_id, path): return seafserv_threaded_rpc.get_dir_id_by_commit_and_path(repo_id, commit_id, path) def list_dir_with_perm(self, repo_id, dir_path, dir_id, user, offset=-1, limit=-1): return seafserv_threaded_rpc.list_dir_with_perm (repo_id, dir_path, dir_id, user, offset, limit) def mkdir_with_parents (self, repo_id, parent_dir, relative_path, username): return seafserv_threaded_rpc.mkdir_with_parents(repo_id, parent_dir, relative_path, username) def get_file_count_info_by_path(self, repo_id, path): return seafserv_threaded_rpc.get_file_count_info_by_path(repo_id, path) def get_total_storage (self): return seafserv_threaded_rpc.get_total_storage() def get_total_file_number (self): return seafserv_threaded_rpc.get_total_file_number() # file/dir operations def post_file(self, repo_id, tmp_file_path, parent_dir, filename, username): """Add a file to a directory""" return seafserv_threaded_rpc.post_file(repo_id, tmp_file_path, parent_dir, filename, username) def post_empty_file(self, repo_id, parent_dir, filename, username): return seafserv_threaded_rpc.post_empty_file(repo_id, parent_dir, filename, username) def put_file(self, repo_id, tmp_file_path, parent_dir, filename, username, head_id): """Update an existing file head_id: the original commit id of the old file """ return seafserv_threaded_rpc.put_file(repo_id, tmp_file_path, parent_dir, filename, username, head_id) ''' If you want to delete multiple files in a batch, @filename should be in the following format: 'filename1\tfilename2\tfilename3' ''' def del_file(self, repo_id, parent_dir, filename, username): return seafserv_threaded_rpc.del_file(repo_id, parent_dir, filename, username) ''' If you want to move or copy multiple files in a batch, @src_filename and @dst_filename should be in the following format: 'filename1\tfilename2\tfilename3',make sure the number of files in @src_filename and @dst_filename parameters match ''' def copy_file(self, src_repo, src_dir, src_filename, dst_repo, dst_dir, dst_filename, username, need_progress, synchronous=0): return seafserv_threaded_rpc.copy_file(src_repo, src_dir, src_filename, dst_repo, dst_dir, dst_filename, username, need_progress, synchronous) def move_file(self, src_repo, src_dir, src_filename, dst_repo, dst_dir, dst_filename, replace, username, need_progress, synchronous=0): return seafserv_threaded_rpc.move_file(src_repo, src_dir, src_filename, dst_repo, dst_dir, dst_filename, replace, username, need_progress, synchronous) def get_copy_task(self, task_id): return seafserv_threaded_rpc.get_copy_task(task_id) def cancel_copy_task(self, task_id): return seafserv_threaded_rpc.cancel_copy_task(task_id) def rename_file(self, repo_id, parent_dir, oldname, newname, username): return seafserv_threaded_rpc.rename_file(repo_id, parent_dir, oldname, newname, username) def post_dir(self, repo_id, parent_dir, dirname, username): """Add a directory""" return seafserv_threaded_rpc.post_dir(repo_id, parent_dir, dirname, username) def revert_file(self, repo_id, commit_id, path, username): return seafserv_threaded_rpc.revert_file(repo_id, commit_id, path, username) def revert_dir(self, repo_id, commit_id, path, username): return seafserv_threaded_rpc.revert_dir(repo_id, commit_id, path, username) def get_deleted(self, repo_id, show_days, path='/', scan_stat=None, limit=100): """ Get list of deleted paths. @show_days: return deleted path in the last @show_days @path: return deleted files under this path. The path will be recursively traversed. @scan_stat: An opaque status returned by the last call. In the first call, None must be passed. The last entry of the result list contains a 'scan_stat' attribute. In the next call, pass in the returned 'scan_stat'. @limit: Advisory maximum number of commits to traverse. Sometimes more than @limit commits will be traversed. Return a list of DeletedEntry objects (lib/repo.vala). If no more deleted entries can be returned within the given time frame (specified by @show_days) or all deleted entries in the history have been returned, a list with a single entry will be returned. The 'scan_stat' attribute of this entry is set to None. """ return seafserv_threaded_rpc.get_deleted(repo_id, show_days, path, scan_stat, limit) def get_file_revisions(self, repo_id, commit_id, path, limit): """ Get revisions of a file. @commit_id: start traversing from this commit @limit: maximum number of commits to traverse when looking for revisions Return a list of Commit objects (lib/commit.vala) related to the revisions. A few special attributes are added to the commit object: @rev_file_id: id of the file revision @rev_file_size: size of the file revision @rev_renamed_old_path: set if this revision is made by a rename operation. It's set to the old path before rename. @next_start_commit: commit_id for next page. An extra commit which only contains @next_start_commit will be appended to the list. """ return seafserv_threaded_rpc.list_file_revisions(repo_id, commit_id, path, limit) # This api is slow and should only be used for version 0 repos. def get_files_last_modified(self, repo_id, parent_dir, limit): """Get last modification time for files in a dir limit: the max number of commits to analyze """ return seafserv_threaded_rpc.calc_files_last_modified(repo_id, parent_dir, limit) def get_repo_history_limit(self, repo_id): """ Return repo history limit in days. Returns -1 if it's unlimited. """ return seafserv_threaded_rpc.get_repo_history_limit(repo_id) def set_repo_history_limit(self, repo_id, days): """ Set repo history limit in days. Pass -1 if set to unlimited. """ return seafserv_threaded_rpc.set_repo_history_limit(repo_id, days) def check_repo_blocks_missing(self, repo_id, blklist): return seafserv_threaded_rpc.check_repo_blocks_missing(repo_id, blklist) def get_upload_tmp_file_offset (self, repo_id, file_path): return seafserv_threaded_rpc.get_upload_tmp_file_offset (repo_id, file_path) # file lock def check_file_lock(self, repo_id, path, user): """ Always return 0 since CE doesn't support file locking. """ return 0 # share repo to user def share_repo(self, repo_id, from_username, to_username, permission): return seafserv_threaded_rpc.add_share(repo_id, from_username, to_username, permission) def remove_share(self, repo_id, from_username, to_username): return seafserv_threaded_rpc.remove_share(repo_id, from_username, to_username) def set_share_permission(self, repo_id, from_username, to_username, permission): return seafserv_threaded_rpc.set_share_permission(repo_id, from_username, to_username, permission) def share_subdir_to_user(self, repo_id, path, owner, share_user, permission, passwd=''): return seafserv_threaded_rpc.share_subdir_to_user(repo_id, path, owner, share_user, permission, passwd) def unshare_subdir_for_user(self, repo_id, path, owner, share_user): return seafserv_threaded_rpc.unshare_subdir_for_user(repo_id, path, owner, share_user) def update_share_subdir_perm_for_user(self, repo_id, path, owner, share_user, permission): return seafserv_threaded_rpc.update_share_subdir_perm_for_user(repo_id, path, owner, share_user, permission) def get_shared_repo_by_path(self, repo_id, path, shared_to, is_org=False): """ If path is NULL, 'repo_id' represents for the repo we want, otherwise, 'repo_id' represents for the origin repo, return virtual repo """ return seafserv_threaded_rpc.get_shared_repo_by_path(repo_id, path, shared_to, 1 if is_org else 0) def get_share_out_repo_list(self, username, start, limit): """ Get repo list shared by this user. Return: a list of Repo objects """ return seafserv_threaded_rpc.list_share_repos(username, "from_email", start, limit) def get_share_in_repo_list(self, username, start, limit): """ Get repo list shared to this user. """ return seafserv_threaded_rpc.list_share_repos(username, "to_email", start, limit) def list_repo_shared_to(self, from_user, repo_id): """ Get user list this repo is shared to. Return: a list of SharedUser objects (lib/repo.vala) """ return seafserv_threaded_rpc.list_repo_shared_to(from_user, repo_id) def repo_has_been_shared(self, repo_id, including_groups=False): return True if seafserv_threaded_rpc.repo_has_been_shared(repo_id, 1 if including_groups else 0) else False # share repo to group def group_share_repo(self, repo_id, group_id, username, permission): # deprecated, use ``set_group_repo`` return seafserv_threaded_rpc.group_share_repo(repo_id, group_id, username, permission) def set_group_repo(self, repo_id, group_id, username, permission): return seafserv_threaded_rpc.group_share_repo(repo_id, group_id, username, permission) def group_unshare_repo(self, repo_id, group_id, username): # deprecated, use ``unset_group_repo`` return seafserv_threaded_rpc.group_unshare_repo(repo_id, group_id, username) def unset_group_repo(self, repo_id, group_id, username): return seafserv_threaded_rpc.group_unshare_repo(repo_id, group_id, username) def get_shared_group_ids_by_repo(self, repo_id): group_ids = seafserv_threaded_rpc.get_shared_groups_by_repo(repo_id) if not group_ids: return [] ret = [] for group_id in group_ids.split('\n'): if not group_id: continue ret.append(group_id) return ret def list_repo_shared_group(self, from_user, repo_id): # deprecated, use list_repo_shared_group_by_user instead. return seafserv_threaded_rpc.list_repo_shared_group(from_user, repo_id) def get_group_shared_repo_by_path (self, repo_id, path, group_id, is_org=False): """ If path is NULL, 'repo_id' represents for the repo we want, otherwise, 'repo_id' represents for the origin repo, return virtual repo """ return seafserv_threaded_rpc.get_group_shared_repo_by_path(repo_id, path, group_id, 1 if is_org else 0) def get_group_repos_by_user (self, user): """ Return all the repos in all groups that the @user belongs to. """ return seafserv_threaded_rpc.get_group_repos_by_user(user) def get_org_group_repos_by_user (self, user, org_id): return seafserv_threaded_rpc.get_org_group_repos_by_user(user, org_id) def list_repo_shared_group_by_user(self, from_user, repo_id): """ Return: a list of SharedGroup objects (lib/repo.vala) """ return seafserv_threaded_rpc.list_repo_shared_group(from_user, repo_id) def share_subdir_to_group(self, repo_id, path, owner, share_group, permission, passwd=''): return seafserv_threaded_rpc.share_subdir_to_group(repo_id, path, owner, share_group, permission, passwd) def unshare_subdir_for_group(self, repo_id, path, owner, share_group): return seafserv_threaded_rpc.unshare_subdir_for_group(repo_id, path, owner, share_group) def update_share_subdir_perm_for_group(self, repo_id, path, owner, share_group, permission): return seafserv_threaded_rpc.update_share_subdir_perm_for_group(repo_id, path, owner, share_group, permission) def get_group_repoids(self, group_id): """ Return the list of group repo ids """ repo_ids = seafserv_threaded_rpc.get_group_repoids(group_id) if not repo_ids: return [] l = [] for repo_id in repo_ids.split("\n"): if repo_id == '': continue l.append(repo_id) return l def get_group_repo_list(self, group_id): # deprecated, use get_repos_by_group instead. ret = [] for repo_id in self.get_group_repoids(group_id): r = self.get_repo(repo_id) if r is None: continue ret.append(r) return ret def get_repos_by_group(self, group_id): """ Return: a list of Repo objects """ return seafserv_threaded_rpc.get_repos_by_group(group_id) def get_group_repos_by_owner(self, username): """ Get all repos a user share to any group Return: a list of Repo objects """ return seafserv_threaded_rpc.get_group_repos_by_owner(username) def remove_group_repos_by_owner(self, group_id, username): """ Unshare all repos a user shared to a group. """ return seafserv_threaded_rpc.remove_repo_group(group_id, username) def remove_group_repos(self, group_id): """ Remove all repos under group. Return: 0 success; -1 failed """ return seafserv_threaded_rpc.remove_repo_group(group_id, None) def set_group_repo_permission(self, group_id, repo_id, permission): return seafserv_threaded_rpc.set_group_repo_permission(group_id, repo_id, permission) def get_shared_users_for_subdir(self, repo_id, path, from_user): """ Get all users a path is shared to. Return: a list of SharedUser objects. """ return seafserv_threaded_rpc.get_shared_users_for_subdir(repo_id, path, from_user) def get_shared_groups_for_subdir(self, repo_id, path, from_user): """ Get all groups a path is shared to. Return: a list of SharedGroup objects. """ return seafserv_threaded_rpc.get_shared_groups_for_subdir(repo_id, path, from_user) def get_shared_users_by_repo(self, repo_id): users = [] # get users that the repo is shared to shared_users = seafserv_threaded_rpc.get_shared_users_by_repo (repo_id) for user in shared_users: users.append(user.user) # get users in groups that the repo is shared to group_ids = seafserv_threaded_rpc.get_shared_groups_by_repo(repo_id) if not group_ids: return users ids = [] for group_id in group_ids.split('\n'): if not group_id: continue ids.append(int(group_id)) json_ids = json.dumps(ids) group_users = ccnet_threaded_rpc.get_groups_members(json_ids) for user in group_users: if user.user_name not in users: users.append(user.user_name) return users # organization wide repo def add_inner_pub_repo(self, repo_id, permission): return seafserv_threaded_rpc.set_inner_pub_repo(repo_id, permission) def remove_inner_pub_repo(self, repo_id): return seafserv_threaded_rpc.unset_inner_pub_repo(repo_id) def get_inner_pub_repo_list(self): """ Return: a list of Repo objects. """ return seafserv_threaded_rpc.list_inner_pub_repos() def list_inner_pub_repos_by_owner(self, repo_owner): """ Return: a list of Repo objects. """ return seafserv_threaded_rpc.list_inner_pub_repos_by_owner(repo_owner) def count_inner_pub_repos(self): return seafserv_threaded_rpc.count_inner_pub_repos() def is_inner_pub_repo(self, repo_id): return seafserv_threaded_rpc.is_inner_pub_repo(repo_id) # permission checks def check_permission(self, repo_id, user): """ Check repo share permissions. Only check user share, group share and inner-pub shares. Return: 'r', 'rw', or None """ return seafserv_threaded_rpc.check_permission(repo_id, user) def check_permission_by_path(self, repo_id, path, user): """ Check both repo share permission and sub-folder access permissions. This function should be used when updating file/folder in a repo. In CE, this function is equivalent to check_permission. Return: 'r', 'rw', or None """ return seafserv_threaded_rpc.check_permission_by_path(repo_id, path, user) def is_repo_syncable(self, repo_id, user, repo_perm): """ Check if the permission of the repo is syncable. """ return '{"is_syncable":true}' def is_dir_downloadable(self, repo_id, dir_path, user, repo_perm): """ Check if the permission of the dir is downloadable. {"is_downloadable": false, "undownloadable_path":"path"} - is_downloadable: true if the dir is downloadable, false if not. - undownloadable_path: the undownloadable path of the repo if the path is not downloadable. """ return '{"is_downloadable":true}' # token def generate_repo_token(self, repo_id, username): """Generate a token for sync a repo """ return seafserv_threaded_rpc.generate_repo_token(repo_id, username) def delete_repo_token(self, repo_id, token, user): return seafserv_threaded_rpc.delete_repo_token(repo_id, token, user) def list_repo_tokens(self, repo_id): """ Return: a list of RepoTokenInfo objects. """ return seafserv_threaded_rpc.list_repo_tokens(repo_id) def list_repo_tokens_by_email(self, username): return seafserv_threaded_rpc.list_repo_tokens_by_email(username) def delete_repo_tokens_by_peer_id(self, email, peer_id): return seafserv_threaded_rpc.delete_repo_tokens_by_peer_id(email, peer_id) def delete_repo_tokens_by_email(self, email): return seafserv_threaded_rpc.delete_repo_tokens_by_email(email) # quota def get_user_self_usage(self, username): """Get the sum of repos' size of the user""" return seafserv_threaded_rpc.get_user_quota_usage(username) def get_user_share_usage(self, username): # sum (repo_size * number_of_shares) return seafserv_threaded_rpc.get_user_share_usage(username) def get_user_quota(self, username): """ Return: -2 if quota is unlimited; otherwise it must be number > 0. """ return seafserv_threaded_rpc.get_user_quota(username) def set_user_quota(self, username, quota): return seafserv_threaded_rpc.set_user_quota(username, quota) def get_user_share_quota(self, username): return -2 # unlimited def set_user_share_quota(self, username, quota): pass def check_quota(self, repo_id, delta=0): return seafserv_threaded_rpc.check_quota(repo_id, delta) def list_user_quota_usage(self): return seafserv_threaded_rpc.list_user_quota_usage() # virtual repo def create_virtual_repo(self, origin_repo_id, path, repo_name, repo_desc, owner, passwd=''): return seafserv_threaded_rpc.create_virtual_repo(origin_repo_id, path, repo_name, repo_desc, owner, passwd) def get_virtual_repos_by_owner(self, owner): return seafserv_threaded_rpc.get_virtual_repos_by_owner(owner) def get_virtual_repo(self, origin_repo, path, owner): return seafserv_threaded_rpc.get_virtual_repo(origin_repo, path, owner) # Clean trash def clean_up_repo_history(self, repo_id, keep_days): return seafserv_threaded_rpc.clean_up_repo_history(repo_id, keep_days) # Trashed repos def get_trash_repo_list(self, start, limit): return seafserv_threaded_rpc.get_trash_repo_list(start, limit) def del_repo_from_trash(self, repo_id): return seafserv_threaded_rpc.del_repo_from_trash(repo_id) def restore_repo_from_trash(self, repo_id): return seafserv_threaded_rpc.restore_repo_from_trash(repo_id) def get_trash_repos_by_owner(self, owner): return seafserv_threaded_rpc.get_trash_repos_by_owner(owner) def get_trash_repo_owner (self, repo_id): return seafserv_threaded_rpc.get_trash_repo_owner(repo_id) def empty_repo_trash(self): return seafserv_threaded_rpc.empty_repo_trash() def empty_repo_trash_by_owner(self, owner): return seafserv_threaded_rpc.empty_repo_trash_by_owner(owner) # Server config def get_server_config_int (self, group, key): return seafserv_threaded_rpc.get_server_config_int (group, key) def set_server_config_int (self, group, key, value): return seafserv_threaded_rpc.set_server_config_int (group, key, value) def get_server_config_int64 (self, group, key): return seafserv_threaded_rpc.get_server_config_int64 (group, key) def set_server_config_int64 (self, group, key, value): return seafserv_threaded_rpc.set_server_config_int64 (group, key, value) def get_server_config_string (self, group, key): return seafserv_threaded_rpc.get_server_config_string (group, key) def set_server_config_string (self, group, key, value): return seafserv_threaded_rpc.set_server_config_string (group, key, value) def get_server_config_boolean (self, group, key): return bool(seafserv_threaded_rpc.get_server_config_boolean (group, key)) def set_server_config_boolean (self, group, key, value): i_value = 1 if bool(value) else 0 return seafserv_threaded_rpc.set_server_config_boolean (group, key, i_value) def del_org_group_repo(self, repo_id, org_id, group_id): seafserv_threaded_rpc.del_org_group_repo(repo_id, org_id, group_id) def org_get_shared_users_by_repo(self, org_id, repo_id): users = [] # get users that the repo is shared to shared_users = seafserv_threaded_rpc.org_get_shared_users_by_repo(org_id, repo_id) for user in shared_users: users.append(user.user) # get users in groups that the repo is shared to group_ids = seafserv_threaded_rpc.get_org_groups_by_repo(org_id, repo_id) if not group_ids: return users ids = [] for group_id in group_ids.split('\n'): if not group_id: continue ids.append(int(group_id)) json_ids = json.dumps(ids) group_users = ccnet_threaded_rpc.get_groups_members(json_ids) for user in group_users: if user.user_name not in users: users.append(user.user_name) return users def list_org_inner_pub_repos(self, org_id): return seafserv_threaded_rpc.list_org_inner_pub_repos(org_id) def convert_repo_path(self, repo_id, path, user, is_org=False): return seafserv_threaded_rpc.convert_repo_path(repo_id, path, user, 1 if is_org else 0) def publish_event(self, channel, content): return seafserv_threaded_rpc.publish_event(channel, content) def pop_event(self, channel): return seafserv_threaded_rpc.pop_event(channel) seafile_api = SeafileAPI() class CcnetAPI(object): def __init__(self): pass # user management def add_emailuser(self, email, passwd, is_staff, is_active): return ccnet_threaded_rpc.add_emailuser(email, passwd, is_staff, is_active) def remove_emailuser(self, source, email): """ source can be 'DB' or 'LDAP'. - 'DB': remove a user created in local database - 'LDAP': remove a user imported from LDAP """ return ccnet_threaded_rpc.remove_emailuser(source, email) def validate_emailuser(self, email, passwd): """ Verify user's password on login. Can be used to verify DB and LDAP users. The function first verify password with LDAP, then local database. """ return ccnet_threaded_rpc.validate_emailuser(email, passwd) def get_emailuser(self, email): """ Only return local database user or imported LDAP user. It first lookup user from local database, if not found, lookup imported LDAP user. Return: a list of EmailUser objects (ccnet/lib/ccnetobj.vala) The 'source' attribute of EmailUser object is set to 'LDAPImport' for LDAP imported user, and 'DB' for local database user. """ return ccnet_threaded_rpc.get_emailuser(email) def get_emailuser_with_import(self, email): """ The same as get_emailuser() but import the user from LDAP if it was not imported yet. """ return ccnet_threaded_rpc.get_emailuser_with_import(email) def get_emailuser_by_id(self, user_id): """ Get a user from local database with the db index id. """ return ccnet_threaded_rpc.get_emailuser_by_id(user_id) def get_emailusers(self, source, start, limit, is_active=None): """ source: - 'DB': return local db users - 'LDAPImport': return imported LDAP users - 'LDAP': retrieve users directly from LDAP server start: offset to start retrieving, -1 to start from the beginning limit: number of users to get, -1 to get all user from start is_active: True to return only active users; False to return inactive users; None to return all users. Return: a list of EmailUser objects. """ if is_active is True: status = "active" # list active users elif is_active is False: status = "inactive" # list inactive users else: status = "" # list all users return ccnet_threaded_rpc.get_emailusers(source, start, limit, status) def search_emailusers(self, source, email_patt, start, limit): """ Search for users whose name contains @email_patt. source: 'DB' for local db users; 'LDAP' for imported LDAP users. This function cannot search LDAP users directly in LDAP server. """ return ccnet_threaded_rpc.search_emailusers(source, email_patt, start, limit) def search_groups(self, group_patt, start, limit): """ Search for groups whose name contains @group_patt. """ return ccnet_threaded_rpc.search_groups(group_patt, start, limit) def get_top_groups(self, including_org=False): return ccnet_threaded_rpc.get_top_groups(1 if including_org else 0) def get_child_groups(self, group_id): return ccnet_threaded_rpc.get_child_groups(group_id) def get_descendants_groups(self, group_id): return ccnet_threaded_rpc.get_descendants_groups(group_id) def get_ancestor_groups(self, group_id): return ccnet_threaded_rpc.get_ancestor_groups(group_id) def search_ldapusers(self, keyword, start, limit): """ Search for users whose name contains @keyword directly from LDAP server. """ return ccnet_threaded_rpc.search_ldapusers(keyword, start, limit) def count_emailusers(self, source): """ Return the number of active users by source. source: 'DB' for local db users; 'LDAP' for imported LDAP users. """ return ccnet_threaded_rpc.count_emailusers(source) def count_inactive_emailusers(self, source): """ Return the number of inactive users by source. source: 'DB' for local db users; 'LDAP' for imported LDAP users. """ return ccnet_threaded_rpc.count_inactive_emailusers(source) def update_emailuser(self, source, user_id, password, is_staff, is_active): """ source: 'DB' for local db user; 'LDAP' for imported LDAP user. user_id: usually not changed. password: new password in plain text. Only effective for DB users. If '!' is passed, the password won't be updated. is_staff: change superuser status is_active: activate or deactivate user """ return ccnet_threaded_rpc.update_emailuser(source, user_id, password, is_staff, is_active) def update_role_emailuser(self, email, role): return ccnet_threaded_rpc.update_role_emailuser(email, role) def get_superusers(self): """ Return: a list of EmailUser objects. """ return ccnet_threaded_rpc.get_superusers() def get_emailusers_in_list(self, source, user_list): """ @source: 'DB' or 'LDAP' @user_list: json '[user1, user2, user3,...]' """ return ccnet_threaded_rpc.get_emailusers_in_list(source, user_list) # group management def create_group(self, group_name, user_name, gtype=None, parent_group_id=0): """ For CE, gtype is not used and should always be None. """ return ccnet_threaded_rpc.create_group(group_name, user_name, gtype, parent_group_id) def create_org_group(self, org_id, group_name, user_name, parent_group_id=0): return ccnet_threaded_rpc.create_org_group(org_id, group_name, user_name, parent_group_id) def remove_group(self, group_id): """ permission check should be done before calling this function. """ return ccnet_threaded_rpc.remove_group(group_id) def group_add_member(self, group_id, user_name, member_name): """ user_name: unused. """ return ccnet_threaded_rpc.group_add_member(group_id, user_name, member_name) def group_remove_member(self, group_id, user_name, member_name): """ user_name: unused. """ return ccnet_threaded_rpc.group_remove_member(group_id, user_name, member_name) def group_set_admin(self, group_id, member_name): """ No effect if member_name is not in the group. """ return ccnet_threaded_rpc.group_set_admin(group_id, member_name) def group_unset_admin(self, group_id, member_name): """ No effect if member_name is not in the group. """ return ccnet_threaded_rpc.group_unset_admin(group_id, member_name) def set_group_name(self, group_id, group_name): return ccnet_threaded_rpc.set_group_name(group_id, group_name) def quit_group(self, group_id, user_name): return ccnet_threaded_rpc.quit_group(group_id, user_name) def get_groups(self, user_name, return_ancestors=False): """ Get all groups the user belongs to. Return: a list of Group objects (ccnet/lib/ccnetobj.vala) """ return ccnet_threaded_rpc.get_groups(user_name, 1 if return_ancestors else 0) def get_all_groups(self, start, limit, source=None): """ For CE, source is not used and should alwasys be None. """ return ccnet_threaded_rpc.get_all_groups(start, limit, source) def get_group(self, group_id): return ccnet_threaded_rpc.get_group(group_id) def get_group_members(self, group_id): """ Return a list of GroupUser objects (ccnet/lib/ccnetobj.vala) """ return ccnet_threaded_rpc.get_group_members(group_id) def get_members_with_prefix (self, group_id, prefix=None): """ Return a list of GroupUser objects """ return ccnet_threaded_rpc.get_members_with_prefix(group_id, prefix) def check_group_staff(self, group_id, username, in_structure=False): """ Return non-zero value if true, 0 if not true """ return ccnet_threaded_rpc.check_group_staff(group_id, username, 1 if in_structure else 0) def remove_group_user(self, username): return ccnet_threaded_rpc.remove_group_user(username) def is_group_user(self, group_id, user, in_structure=True): """ Return non-zero value if true, 0 if not true If @in_structure is true, return whether user is in descendants groups and @group_id it self """ return ccnet_threaded_rpc.is_group_user(group_id, user, 1 if in_structure else 0) def set_group_creator(self, group_id, user_name): return ccnet_threaded_rpc.set_group_creator(group_id, user_name) # organization management def create_org(self, org_name, url_prefix, creator): return ccnet_threaded_rpc.create_org(org_name, url_prefix, creator) def remove_org(self, org_id): return ccnet_threaded_rpc.remove_org(org_id) def get_all_orgs(self, start, limit): """ Return a list of Organization objects (ccnet/lib/ccnetobj.vala) """ return ccnet_threaded_rpc.get_all_orgs(start, limit) def count_orgs(self): return ccnet_threaded_rpc.count_orgs() def get_org_by_url_prefix(self, url_prefix): """ Return an Organizaion object. """ return ccnet_threaded_rpc.get_org_by_url_prefix(url_prefix) def get_org_by_id(self, org_id): return ccnet_threaded_rpc.get_org_by_id(org_id) def add_org_user(self, org_id, email, is_staff): return ccnet_threaded_rpc.add_org_user(org_id, email, is_staff) def remove_org_user(self, org_id, email): return ccnet_threaded_rpc.remove_org_user(org_id, email) def get_orgs_by_user(self, email): return ccnet_threaded_rpc.get_orgs_by_user(email) def get_org_emailusers(self, url_prefix, start, limit): """ Return a list of EmailUser objects. """ return ccnet_threaded_rpc.get_org_emailusers(url_prefix, start, limit) def add_org_group(self, org_id, group_id): return ccnet_threaded_rpc.add_org_group(org_id, group_id) def remove_org_group(self, org_id, group_id): return ccnet_threaded_rpc.remove_org_group(org_id, group_id) def is_org_group(self, group_id): """ Return non-zero if True, otherwise 0. """ return ccnet_threaded_rpc.is_org_group(group_id) def get_org_id_by_group(self, group_id): return ccnet_threaded_rpc.get_org_id_by_group(group_id) def get_org_groups(self, org_id, start, limit): """ Return a list of int, each int is group id. """ return ccnet_threaded_rpc.get_org_groups(org_id, start, limit) def get_org_top_groups(self, org_id): return ccnet_threaded_rpc.get_org_top_groups(org_id) def org_user_exists(self, org_id, email): """ Return non-zero if True, otherwise 0. """ return ccnet_threaded_rpc.org_user_exists(org_id, email) def is_org_staff(self, org_id, user): """ Return non-zero if True, otherwise 0. """ return ccnet_threaded_rpc.is_org_staff(org_id, user) def set_org_staff(self, org_id, user): return ccnet_threaded_rpc.set_org_staff(org_id, user) def unset_org_staff(self, org_id, user): return ccnet_threaded_rpc.unset_org_staff(org_id, user) def set_org_name(self, org_id, org_name): return ccnet_threaded_rpc.set_org_name(org_id, org_name) def get_primary_id (self, email): return ccnet_threaded_rpc.get_primary_id(email) def set_reference_id (self, primary_id, reference_id): return ccnet_threaded_rpc.set_reference_id(primary_id, reference_id) def get_groups_members(self, group_ids): """ @group_ids: json '[id1, id2, id3,...]' """ return ccnet_threaded_rpc.get_groups_members(group_ids) ccnet_api = CcnetAPI()