2020-06-08 15:05:33 +08:00
#!/usr/bin/env python3
2019-09-23 18:21:54 +08:00
#-*- coding:utf-8 -*-
2013-10-31 10:50:03 +08:00
# pylint: disable=E1121
2013-02-03 11:05:20 +08:00
'''
2013-02-13 12:57:02 +08:00
seaf-cli is command line interface for seafile client.
2013-02-03 11:05:20 +08:00
Subcommands:
2013-02-18 10:47:18 +08:00
2017-04-29 09:25:31 +08:00
init: create config files for seafile client
start: start and run seafile client as daemon
stop: stop seafile client
2018-06-09 08:17:21 +08:00
list: list local libraries
2017-04-29 09:25:31 +08:00
status: show syncing status
download: download a library from seafile server
(using libary id)
download-by-name: download a library from seafile server
(using library name)
sync: synchronize an existing folder with a library in
seafile server
desync: desynchronize a library with seafile server
create: create a new library
2013-02-03 11:05:20 +08:00
2013-02-18 10:47:18 +08:00
Detail
======
Seafile client stores all its configure information in a config dir. The default location is `~/.ccnet`. All the commands below accept an option `-c <config-dir>`.
2013-02-03 11:05:20 +08:00
init
----
2013-02-18 11:21:11 +08:00
Initialize seafile client. This command initializes the config dir. It also creates sub-directories `seafile-data` and `seafile` under `parent-dir`. `seafile-data` is used to store internal data, while `seafile` is used as the default location put downloaded libraries.
2013-02-03 11:05:20 +08:00
2013-02-18 10:47:18 +08:00
seaf-cli init [-c <config-dir>] -d <parent-dir>
2013-02-03 11:05:20 +08:00
start
-----
2018-08-10 18:42:55 +08:00
Start seafile client. This command starts `seaf-daemon`, which manages all the files.
2013-02-03 11:05:20 +08:00
2013-02-18 10:47:18 +08:00
seaf-cli start [-c <config-dir>]
2013-02-03 11:05:20 +08:00
2013-02-13 12:57:02 +08:00
stop
----
Stop seafile client.
2013-02-03 11:05:20 +08:00
2013-02-18 10:47:18 +08:00
seaf-cli stop [-c <config-dir>]
2013-02-16 21:34:07 +08:00
2017-04-29 09:25:31 +08:00
Download by id
2013-02-19 11:52:48 +08:00
--------
2017-04-29 09:25:31 +08:00
Download a library from seafile server (using library id)
2013-02-13 12:57:02 +08:00
2018-05-25 18:29:21 +08:00
seaf-cli download -l <library-id> -s <seahub-server-url> -d <parent-directory> -u <username> -p <password> [-a <2fa-code>]
2013-02-03 11:05:20 +08:00
2017-04-29 09:25:31 +08:00
Download by name
--------
Download a library from seafile server (using library name)
2018-05-25 18:29:21 +08:00
seaf-cli download -L <library-name> -s <seahub-server-url> -d <parent-directory> -u <username> -p <password> [-a <2fa-code>]
2017-04-29 09:25:31 +08:00
2013-02-03 11:05:20 +08:00
sync
----
2013-02-13 12:57:02 +08:00
Synchronize a library with an existing folder.
2013-02-03 11:05:20 +08:00
2018-05-25 18:29:21 +08:00
seaf-cli sync -l <library-id> -s <seahub-server-url> -d <existing-folder> -u <username> -p <password> [-a <2fa-code>]
2013-02-03 11:05:20 +08:00
desync
------
2013-02-13 12:57:02 +08:00
Desynchronize a library from seafile server
2013-02-03 11:05:20 +08:00
2013-02-18 10:47:18 +08:00
seaf-cli desync -d <existing-folder>
2013-02-03 11:05:20 +08:00
2013-07-06 13:59:07 +08:00
create
------
Create a new library
2018-05-25 18:29:21 +08:00
seaf-cli create -s <seahub-server-url> -n <library-name> -u <username> -p <password> [-a <2fa-code>] -t <description> [-e <library-password>]
2013-07-06 13:59:07 +08:00
2013-02-03 11:05:20 +08:00
'''
import argparse
2013-02-13 12:57:02 +08:00
import os
2014-07-09 19:42:50 +08:00
import json
2013-02-03 11:05:20 +08:00
import subprocess
2018-08-10 18:42:55 +08:00
import re
2013-02-13 12:57:02 +08:00
import sys
2013-02-03 11:05:20 +08:00
import time
2013-02-20 15:13:47 +08:00
import getpass
2018-08-10 18:42:55 +08:00
import random
2019-09-23 18:21:54 +08:00
import urllib.request, urllib.parse, urllib.error
import urllib.request, urllib.error, urllib.parse
from urllib.parse import urlparse
2013-02-03 11:05:20 +08:00
2018-08-10 18:42:55 +08:00
from os.path import abspath, dirname, exists, isdir, join
2013-02-03 11:05:20 +08:00
import seafile
2014-10-27 07:49:52 +08:00
if 'HOME' in os.environ:
DEFAULT_CONF_DIR = "%s/.ccnet" % os.environ['HOME']
2019-11-07 15:31:12 +08:00
DEFAULT_USER_CONF_DIR = "%s/.seafile.conf" % os.environ['HOME']
2014-10-27 07:49:52 +08:00
else:
DEFAULT_CONF_DIR = None
2019-11-07 15:31:12 +08:00
DEFAULT_USER_CONF_DIR = None
2013-02-13 12:57:02 +08:00
seafile_datadir = None
seafile_worktree = None
2013-02-03 11:05:20 +08:00
def _check_seafile():
2018-08-10 18:42:55 +08:00
''' Check seafile daemon have been installed '''
2013-02-03 11:05:20 +08:00
dirs = os.environ['PATH'].split(':')
def exist_in_path(prog):
''' Check whether 'prog' exists in system path '''
for d in dirs:
if d == '':
2013-02-13 12:57:02 +08:00
continue
2018-08-10 18:42:55 +08:00
path = join(d, prog)
if exists(path):
2013-02-13 12:57:02 +08:00
return True
2013-02-03 11:05:20 +08:00
2018-08-10 18:42:55 +08:00
progs = ['seaf-daemon']
2013-02-03 11:05:20 +08:00
for prog in progs:
if not exist_in_path(prog):
2019-09-23 18:21:54 +08:00
print("%s not found in PATH. Have you installed seafile?" % prog)
2013-02-03 11:05:20 +08:00
sys.exit(1)
2024-01-20 15:01:05 +08:00
def _check_daemon_running():
2024-04-10 18:20:09 +08:00
import fcntl
pidfile = os.path.join(seafile_datadir, 'seaf-daemon.pid')
with open(pidfile, 'w') as f:
try:
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
fcntl.flock(f, fcntl.LOCK_UN)
except:
print("The seafile data directory %s is already used by another Seafile client instance. Please use another seafile data directory."%seafile_datadir)
sys.exit(1)
2024-01-20 15:01:05 +08:00
2018-08-10 18:42:55 +08:00
def get_rpc_client(confdir):
return seafile.RpcClient(join(seafile_datadir, 'seafile.sock'))
2013-02-03 11:05:20 +08:00
def _config_valid(conf):
2013-02-16 21:34:07 +08:00
''' Check config directory valid '''
2013-02-03 11:05:20 +08:00
2018-08-10 18:42:55 +08:00
if not exists(conf) or not isdir(conf):
2019-09-23 18:21:54 +08:00
print("%s not exists" % conf)
2013-02-03 11:05:20 +08:00
return False
seafile_ini = conf + "/seafile.ini"
2018-08-10 18:42:55 +08:00
if not exists(seafile_ini):
2019-09-23 18:21:54 +08:00
print("Could not load %s" % seafile_ini)
2013-02-03 11:05:20 +08:00
return False
2013-02-13 12:57:02 +08:00
with open(seafile_ini) as f:
for line in f:
global seafile_datadir, seafile_worktree
seafile_datadir = line.strip()
2018-08-10 18:42:55 +08:00
seafile_worktree = join(
dirname(seafile_datadir), "seafile")
2013-02-13 12:57:02 +08:00
break
if not seafile_datadir or not seafile_worktree:
2019-09-23 18:21:54 +08:00
print("Could not load seafile_datadir and seafile_worktree")
2013-02-13 12:57:02 +08:00
return False
2013-02-03 11:05:20 +08:00
return True
2016-04-27 06:26:35 +08:00
2016-05-27 14:03:06 +08:00
def _conf_dir(args):
2016-04-27 06:26:35 +08:00
''' Determine and return the value of conf_dir '''
conf_dir = DEFAULT_CONF_DIR
if args.confdir:
conf_dir = args.confdir
2018-08-10 18:42:55 +08:00
conf_dir = abspath(conf_dir)
2016-04-27 06:26:35 +08:00
if not _config_valid(conf_dir):
2019-09-23 18:21:54 +08:00
print("Invalid config directory")
2016-04-27 06:26:35 +08:00
sys.exit(1)
else:
2018-08-10 18:42:55 +08:00
get_device_id(conf_dir)
2016-04-27 06:26:35 +08:00
return conf_dir
2019-11-07 15:31:12 +08:00
def _user_config_valid(conf):
2019-11-07 17:36:15 +08:00
if exists(conf):
return True
return False
2019-11-07 15:31:12 +08:00
def _parse_user_config(conf):
try:
from configparser import ConfigParser
from configparser import NoOptionError
except ImportError:
from ConfigParser import ConfigParser
from ConfigParser import NoOptionError
cfg = ConfigParser()
cfg.read(conf)
if len(cfg.sections()) < 1 or cfg.sections()[0] != 'account':
return None, None
try:
server = cfg.get('account', 'server')
user = cfg.get('account', 'user')
return server,user
except NoOptionError:
return None, None
2016-04-27 06:26:35 +08:00
2013-03-11 11:18:14 +08:00
def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False):
'''Run a program and wait it to finish, and return its exit code. The
standard output of this program is supressed.
'''
with open(os.devnull, 'w') as devnull:
if suppress_stdout:
stdout = devnull
else:
stdout = sys.stdout
if suppress_stderr:
stderr = devnull
else:
stderr = sys.stderr
proc = subprocess.Popen(argv,
cwd=cwd,
stdout=stdout,
stderr=stderr,
env=env)
return proc.wait()
def get_env():
env = dict(os.environ)
ld_library_path = os.environ.get('SEAFILE_LD_LIBRARY_PATH', '')
if ld_library_path:
env['LD_LIBRARY_PATH'] = ld_library_path
return env
def urlopen(url, data=None, headers=None):
if data:
2019-09-23 18:21:54 +08:00
data = urllib.parse.urlencode(data).encode('utf-8')
2013-03-11 11:18:14 +08:00
headers = headers or {}
2019-09-23 18:21:54 +08:00
req = urllib.request.Request(url, data=data, headers=headers)
resp = urllib.request.urlopen(req)
2013-03-11 11:18:14 +08:00
return resp.read()
2014-04-30 14:39:03 +08:00
SEAF_CLI_VERSION = ""
2018-08-10 18:42:55 +08:00
def randstring(size):
random.seed(time.time())
s = ''
while len(s) < size:
s += '%x' % random.randint(0, 255)
return s[:size]
device_id = None
def get_device_id(conf_dir):
global device_id
if device_id:
return device_id
idfile = join(seafile_datadir, 'id')
ccnet_conf = join(conf_dir, 'ccnet.conf')
if exists(idfile):
with open(idfile, 'r') as fp:
device_id = fp.read().strip()
return device_id
# Id file doesn't exist. We either migrate it from ccnet.conf ID
# (for existing data), or create it.
if exists(ccnet_conf):
# migrate from existing ccnet.conf ID
with open(ccnet_conf, 'r') as fp:
for line in fp:
m = re.search('ID = (.*)', line)
if m:
device_id = m.group(1)
print('Migrating device id from ccnet conf')
break
if not device_id:
# create a new id
print('New device id created')
device_id = randstring(40)
with open(idfile, 'w') as fp:
fp.write(device_id)
return device_id
2014-04-30 14:39:03 +08:00
2018-05-25 18:29:21 +08:00
def get_token(url, username, password, tfa, conf_dir):
2014-04-30 14:39:03 +08:00
platform = 'linux'
2018-08-10 18:42:55 +08:00
device_id = get_device_id(conf_dir)
2021-07-13 10:29:38 +08:00
device_name = 'terminal-' + os.uname()[1][:25]
2014-04-30 14:39:03 +08:00
client_version = SEAF_CLI_VERSION
platform_version = ''
data = {
'username': username,
'password': password,
'platform': platform,
'device_id': device_id,
'device_name': device_name,
'client_version': client_version,
'platform_version': platform_version,
}
2018-05-25 18:29:21 +08:00
if tfa:
headers = {
'X-SEAFILE-OTP': tfa,
}
else:
headers = None
token_json = urlopen("%s/api2/auth-token/" % url, data=data, headers=headers)
2020-06-08 15:05:33 +08:00
tmp = json.loads(token_json.decode('utf8'))
2013-03-11 11:18:14 +08:00
token = tmp['token']
return token
2016-04-21 15:39:09 +08:00
def get_repo_download_info(url, token):
2013-03-11 11:18:14 +08:00
headers = { 'Authorization': 'Token %s' % token }
repo_info = urlopen(url, headers=headers)
2020-06-08 15:05:33 +08:00
return json.loads(repo_info.decode('utf8'))
2013-02-03 11:05:20 +08:00
2023-01-25 00:43:30 +08:00
def get_value_from_user_config(args, section, key):
user_config = args.C
if not user_config:
user_config = DEFAULT_USER_CONF_DIR
else:
user_config = abspath(user_config)
if _user_config_valid(user_config):
try:
from configparser import ConfigParser
from configparser import NoOptionError
except ImportError:
from ConfigParser import ConfigParser
from ConfigParser import NoOptionError
cfg = ConfigParser()
cfg.read(user_config)
if len(cfg.sections()) < 1 or cfg.sections()[0] != 'account':
return None
try:
token = cfg.get(section, key)
return token
except NoOptionError:
return None
else:
return None
def get_token_from_args_or_config(args):
if args.token:
return args.token
else:
return get_value_from_user_config(args, 'account', 'token')
2013-02-13 12:57:02 +08:00
def seaf_init(args):
2016-04-27 05:59:01 +08:00
''' Initialize config directories'''
2013-02-03 11:05:20 +08:00
2013-02-13 12:57:02 +08:00
ccnet_conf_dir = DEFAULT_CONF_DIR
if args.confdir:
ccnet_conf_dir = args.confdir
if args.dir:
seafile_path = args.dir
2013-02-27 20:14:27 +08:00
else:
2019-09-23 18:21:54 +08:00
print("Must specify the parent path for put seafile-data")
2013-02-27 20:14:27 +08:00
sys.exit(0)
2018-08-10 18:42:55 +08:00
seafile_path = abspath(seafile_path)
2013-02-03 11:05:20 +08:00
2018-08-10 18:42:55 +08:00
if exists(ccnet_conf_dir):
2019-09-23 18:21:54 +08:00
print("%s already exists" % ccnet_conf_dir)
2013-02-03 11:05:20 +08:00
sys.exit(0)
2018-08-10 18:42:55 +08:00
os.mkdir(ccnet_conf_dir)
logsdir = join(ccnet_conf_dir, 'logs')
if not exists(logsdir):
os.mkdir(logsdir)
2013-02-03 11:05:20 +08:00
2018-08-10 18:42:55 +08:00
if not exists(seafile_path):
2019-09-23 18:21:54 +08:00
print("%s not exists" % seafile_path)
2013-02-13 12:57:02 +08:00
sys.exit(0)
seafile_ini = ccnet_conf_dir + "/seafile.ini"
seafile_data = seafile_path + "/seafile-data"
2018-08-10 18:42:55 +08:00
with open(seafile_ini, 'w') as fp:
fp.write(seafile_data)
2018-08-21 10:35:19 +08:00
if not exists(seafile_data):
os.mkdir(seafile_data)
2019-09-23 18:21:54 +08:00
print("Writen seafile data directory %s to %s" % (seafile_data, seafile_ini))
2013-02-03 11:05:20 +08:00
def seaf_start_all(args):
2018-08-10 18:42:55 +08:00
''' Start seafile daemon '''
2013-02-03 11:05:20 +08:00
seaf_start_seafile(args)
def seaf_start_seafile(args):
''' start seafile daemon '''
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2013-02-03 11:05:20 +08:00
2024-01-20 15:01:05 +08:00
_check_daemon_running()
2019-09-23 18:21:54 +08:00
print("Starting seafile daemon ...")
2013-10-31 10:50:03 +08:00
2013-02-13 12:57:02 +08:00
cmd = [ "seaf-daemon", "--daemon", "-c", conf_dir, "-d", seafile_datadir,
"-w", seafile_worktree ]
2013-03-11 11:18:14 +08:00
if run_argv(cmd, env=get_env()) != 0:
2019-09-23 18:21:54 +08:00
print('Failed to start seafile daemon')
2013-03-11 11:18:14 +08:00
sys.exit(1)
2024-06-26 18:50:33 +08:00
seafile_rpc = get_rpc_client(conf_dir)
i = 0
while True:
try:
seafile_rpc.seafile_set_config_int("delete_confirm_threshold", 1000000)
except Exception as e:
if i > 3:
break;
i += 1
time.sleep(1)
continue
else:
break
2019-09-23 18:21:54 +08:00
print("Started: seafile daemon ...")
2013-02-03 11:05:20 +08:00
2013-02-19 11:52:48 +08:00
def seaf_stop(args):
2016-04-27 05:59:01 +08:00
'''Stop seafile daemon '''
2013-02-19 11:52:48 +08:00
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2013-02-19 11:52:48 +08:00
2018-08-10 18:42:55 +08:00
seafile_rpc = get_rpc_client(conf_dir)
2013-02-19 11:52:48 +08:00
try:
2018-08-10 18:42:55 +08:00
# TODO: add shutdown rpc in seaf-daemon
seafile_rpc.shutdown()
2013-02-19 11:52:48 +08:00
except:
# ignore NetworkError("Failed to read from socket")
pass
2013-02-03 11:05:20 +08:00
2013-02-16 21:34:07 +08:00
def seaf_list(args):
'''List local libraries'''
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2013-02-16 21:34:07 +08:00
2018-08-10 18:42:55 +08:00
seafile_rpc = get_rpc_client(conf_dir)
2013-02-16 21:34:07 +08:00
repos = seafile_rpc.get_repo_list(-1, -1)
2021-02-22 12:28:21 +08:00
if args.json:
repo_list = []
for repo in repos:
repo_dict = {'name':repo.name, 'id':repo.id, 'path':repo.worktree}
repo_list.append(repo_dict)
json_str = json.dumps(repo_list, ensure_ascii=False)
print(json_str)
else:
print("Name\tID\tPath")
for repo in repos:
print(repo.name, repo.id, repo.worktree)
2013-02-16 21:34:07 +08:00
2016-03-12 08:02:40 +08:00
def seaf_list_remote(args):
'''List remote libraries'''
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2016-03-12 08:02:40 +08:00
2023-01-25 00:43:30 +08:00
server_from_config = get_value_from_user_config(args, 'account', 'server')
user_from_config = get_value_from_user_config(args, 'account', 'user')
2019-11-07 18:34:26 +08:00
url = args.server
if not url and server_from_config:
url = server_from_config
2016-03-12 08:02:40 +08:00
if not url:
2019-09-23 18:21:54 +08:00
print("Seafile server url need to be presented")
2016-03-12 08:02:40 +08:00
sys.exit(1)
2018-08-10 18:42:55 +08:00
seafile_rpc = get_rpc_client(conf_dir)
2016-03-12 08:02:40 +08:00
username = args.username
2019-11-07 18:34:26 +08:00
if not username and user_from_config:
2021-02-22 12:28:21 +08:00
username = user_from_config
2016-03-12 08:02:40 +08:00
if not username:
2019-09-23 18:21:54 +08:00
username = input("Enter username: ")
2016-03-12 08:02:40 +08:00
2023-01-25 00:43:30 +08:00
token = get_token_from_args_or_config(args)
2021-09-07 15:58:14 +08:00
password = None
tfa = args.tfa
if not token:
password = args.password
if not password:
password = getpass.getpass("Enter password for user %s : " % username)
# curl -d 'username=<USERNAME>&password=<PASSWORD>' http://127.0.0.1:8000/api2/auth-token
token = get_token(url, username, password, tfa, conf_dir)
2016-03-12 08:02:40 +08:00
2016-04-21 15:39:09 +08:00
repos = get_repo_download_info("%s/api2/repos/" % (url), token)
printed = {}
2021-02-22 12:28:21 +08:00
if args.json:
repo_list = []
for repo in repos:
if repo['id'] in printed:
continue
printed[repo['id']] = repo['id']
repo_dict = {'name': repo['name'], 'id':repo['id']}
repo_list.append(repo_dict)
json_str = json.dumps(repo_list, ensure_ascii=False)
print(json_str)
else:
print("Name\tID")
for repo in repos:
if repo['id'] in printed:
continue
2016-03-12 08:02:40 +08:00
2021-02-22 12:28:21 +08:00
printed[repo['id']] = repo['id']
print(repo['name'], repo['id'])
2016-03-12 08:02:40 +08:00
2014-12-15 17:40:14 +08:00
def get_base_url(url):
parse_result = urlparse(url)
scheme = parse_result.scheme
netloc = parse_result.netloc
if scheme and netloc:
return '%s://%s' % (scheme, netloc)
return None
2013-02-16 21:34:07 +08:00
2013-02-13 12:57:02 +08:00
def seaf_download(args):
'''Download a library from seafile server '''
2013-02-03 11:05:20 +08:00
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2013-02-03 11:05:20 +08:00
2013-02-13 12:57:02 +08:00
repo = args.library
2013-02-03 11:05:20 +08:00
if not repo:
2019-09-23 18:21:54 +08:00
print("Library id is required")
2013-02-03 11:05:20 +08:00
sys.exit(1)
2023-01-25 00:43:30 +08:00
server_from_config = get_value_from_user_config(args, 'account', 'server')
user_from_config = get_value_from_user_config(args, 'account', 'user')
2019-11-07 15:31:12 +08:00
2013-02-13 12:57:02 +08:00
url = args.server
2019-11-07 15:31:12 +08:00
if not url and server_from_config:
url = server_from_config
2013-02-03 11:05:20 +08:00
if not url:
2019-09-23 18:21:54 +08:00
print("Seafile server url need to be presented")
2013-02-03 11:05:20 +08:00
sys.exit(1)
2013-02-13 12:57:02 +08:00
download_dir = seafile_worktree
if args.dir:
2018-08-10 18:42:55 +08:00
download_dir = abspath(args.dir)
2013-02-03 11:05:20 +08:00
2018-08-10 18:42:55 +08:00
seafile_rpc = get_rpc_client(conf_dir)
2013-02-03 11:05:20 +08:00
2013-02-19 11:52:48 +08:00
username = args.username
2019-11-07 15:31:12 +08:00
if not username and user_from_config:
username = user_from_config
2013-02-03 11:05:20 +08:00
if not username:
2019-09-23 18:21:54 +08:00
username = input("Enter username: ")
2023-01-25 00:43:30 +08:00
token = get_token_from_args_or_config(args)
2021-09-07 15:58:14 +08:00
password = None
2018-05-25 18:29:21 +08:00
tfa = args.tfa
2021-09-07 15:58:14 +08:00
if not token:
password = args.password
if not password:
password = getpass.getpass("Enter password for user %s : " % username)
# curl -d 'username=<USERNAME>&password=<PASSWORD>' http://127.0.0.1:8000/api2/auth-token
token = get_token(url, username, password, tfa, conf_dir)
2013-02-03 11:05:20 +08:00
2016-04-21 15:39:09 +08:00
tmp = get_repo_download_info("%s/api2/repos/%s/download-info/" % (url, repo), token)
2013-02-20 10:52:55 +08:00
2013-02-03 11:05:20 +08:00
encrypted = tmp['encrypted']
2013-10-31 10:50:03 +08:00
magic = tmp.get('magic', None)
enc_version = tmp.get('enc_version', None)
random_key = tmp.get('random_key', None)
2013-02-03 11:05:20 +08:00
clone_token = tmp['token']
email = tmp['email']
repo_name = tmp['repo_name']
2014-04-21 19:11:35 +08:00
version = tmp.get('repo_version', 0)
2019-07-24 10:49:44 +08:00
repo_salt = tmp.get('salt', None)
2019-07-24 14:25:20 +08:00
permission = tmp.get('permission', None)
2013-02-03 11:05:20 +08:00
2019-07-24 14:25:20 +08:00
is_readonly = 0
if permission == 'r':
is_readonly = 1
2014-12-15 17:40:14 +08:00
more_info = None
2019-07-24 14:25:20 +08:00
more_info_dict = {}
2015-07-06 16:40:51 +08:00
base_url = get_base_url(url)
if base_url:
2019-07-24 14:25:20 +08:00
more_info_dict.update({'server_url': base_url})
2019-05-27 12:13:58 +08:00
if repo_salt:
more_info_dict.update({'repo_salt': repo_salt})
2019-07-24 14:25:20 +08:00
more_info_dict.update({'is_readonly': is_readonly})
more_info = json.dumps(more_info_dict)
2014-12-15 17:40:14 +08:00
2019-09-23 18:21:54 +08:00
print("Starting to download ...")
print("Library %s will be downloaded to %s" % (repo, download_dir))
2013-02-20 10:52:55 +08:00
if encrypted == 1:
2017-07-14 22:59:47 +08:00
repo_passwd = args.libpasswd if args.libpasswd else getpass.getpass("Enter password for the library: ")
2013-02-20 10:52:55 +08:00
else:
repo_passwd = None
2013-10-31 10:50:03 +08:00
2013-02-13 12:57:02 +08:00
seafile_rpc.download(repo,
2014-04-21 19:11:35 +08:00
version,
2019-09-23 18:21:54 +08:00
repo_name,
download_dir,
2013-02-13 12:57:02 +08:00
clone_token,
2013-02-20 10:52:55 +08:00
repo_passwd, magic,
2014-12-15 17:40:14 +08:00
email, random_key, enc_version, more_info)
2013-10-31 10:50:03 +08:00
2013-02-03 11:05:20 +08:00
2016-03-12 08:02:40 +08:00
def seaf_download_by_name(args):
'''Download a library defined by name from seafile server'''
id = None
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2016-03-12 08:02:40 +08:00
libraryname = args.libraryname
if not libraryname:
2019-09-23 18:21:54 +08:00
print("Library name is required")
2016-03-12 08:02:40 +08:00
sys.exit(1)
2023-01-25 00:43:30 +08:00
server_from_config = get_value_from_user_config(args, 'account', 'server')
user_from_config = get_value_from_user_config(args, 'account', 'user')
2019-11-07 18:34:26 +08:00
url = args.server
if not url and server_from_config:
url = server_from_config
2016-03-12 08:02:40 +08:00
if not url:
2019-09-23 18:21:54 +08:00
print("Seafile server url need to be presented")
2016-03-12 08:02:40 +08:00
sys.exit(1)
2018-08-10 18:42:55 +08:00
seafile_rpc = get_rpc_client(conf_dir)
2016-03-12 08:02:40 +08:00
username = args.username
2019-11-07 18:34:26 +08:00
if not username and user_from_config:
username = user_from_config;
2016-03-12 08:02:40 +08:00
if not username:
2019-09-23 18:21:54 +08:00
username = input("Enter username: ")
2016-03-12 08:02:40 +08:00
args.username = username
2023-01-25 00:43:30 +08:00
token = get_token_from_args_or_config(args)
2021-09-07 15:58:14 +08:00
password = None
tfa = args.tfa
if not token:
password = args.password
if not password:
password = getpass.getpass("Enter password for user %s : " % username)
args.password = password
# curl -d 'username=<USERNAME>&password=<PASSWORD>' http://127.0.0.1:8000/api2/auth-token
token = get_token(url, username, password, tfa, conf_dir)
2016-03-12 08:02:40 +08:00
2016-04-21 15:39:09 +08:00
tmp = get_repo_download_info("%s/api2/repos/" % (url), token)
2016-03-12 08:02:40 +08:00
for i in tmp:
if libraryname == i['name']:
id = i['id']
if not id:
2019-09-23 18:21:54 +08:00
print("Defined library name not found")
2016-03-12 08:02:40 +08:00
sys.exit(1)
args.library = id
seaf_download(args)
2013-02-03 11:05:20 +08:00
def seaf_sync(args):
2013-02-13 12:57:02 +08:00
''' synchronize a library from seafile server '''
2013-02-03 11:05:20 +08:00
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2013-02-03 11:05:20 +08:00
2013-02-16 21:34:07 +08:00
repo = args.library
2013-02-03 11:05:20 +08:00
if not repo:
2019-09-23 18:21:54 +08:00
print("Library id is required")
2013-02-16 21:34:07 +08:00
sys.exit(1)
2023-01-25 00:43:30 +08:00
server_from_config = get_value_from_user_config(args, 'account', 'server')
user_from_config = get_value_from_user_config(args, 'account', 'user')
2019-11-07 15:31:12 +08:00
2013-02-16 21:34:07 +08:00
url = args.server
2019-11-07 15:31:12 +08:00
if not url and server_from_config:
url = server_from_config
2013-02-16 21:34:07 +08:00
if not url:
2019-09-23 18:21:54 +08:00
print("Seafile server url is required")
2013-02-03 11:05:20 +08:00
sys.exit(1)
2013-02-16 21:34:07 +08:00
folder = args.folder
if not folder:
2019-09-23 18:21:54 +08:00
print("The local directory is required")
2013-10-31 10:50:03 +08:00
sys.exit(1)
2018-08-10 18:42:55 +08:00
folder = abspath(folder)
if not exists(folder):
2019-09-23 18:21:54 +08:00
print("The local directory does not exists")
2013-10-31 10:50:03 +08:00
sys.exit(1)
2013-02-16 21:34:07 +08:00
2018-08-10 18:42:55 +08:00
seafile_rpc = get_rpc_client(conf_dir)
2013-02-03 11:05:20 +08:00
2013-02-19 11:52:48 +08:00
username = args.username
2019-11-07 15:31:12 +08:00
if not username and user_from_config:
username = user_from_config;
2013-02-16 21:34:07 +08:00
if not username:
2019-09-23 18:21:54 +08:00
username = input("Enter username: ")
2021-09-07 15:58:14 +08:00
password = None
2023-01-25 00:43:30 +08:00
token = get_token_from_args_or_config(args)
2018-05-25 18:29:21 +08:00
tfa = args.tfa
2021-09-07 15:58:14 +08:00
if not token:
password = args.password
if not password:
password = getpass.getpass("Enter password for user %s : " % username)
token = get_token(url, username, password, tfa, conf_dir)
2013-02-16 21:34:07 +08:00
2016-04-21 15:39:09 +08:00
tmp = get_repo_download_info("%s/api2/repos/%s/download-info/" % (url, repo), token)
2013-02-16 21:34:07 +08:00
encrypted = tmp['encrypted']
2013-10-31 10:50:03 +08:00
magic = tmp.get('magic', None)
enc_version = tmp.get('enc_version', None)
random_key = tmp.get('random_key', None)
2013-02-16 21:34:07 +08:00
clone_token = tmp['token']
email = tmp['email']
repo_name = tmp['repo_name']
2014-04-21 19:11:35 +08:00
version = tmp.get('repo_version', 0)
2019-07-24 10:49:44 +08:00
repo_salt = tmp.get('salt', None)
2019-07-24 14:25:20 +08:00
permission = tmp.get('permission', None)
2013-02-16 21:34:07 +08:00
2019-07-24 14:25:20 +08:00
is_readonly = 0
if permission == 'r':
is_readonly = 1
2014-12-15 17:40:14 +08:00
more_info = None
2019-07-24 14:25:20 +08:00
more_info_dict = {}
2015-07-06 16:40:51 +08:00
base_url = get_base_url(url)
if base_url:
2019-07-24 14:25:20 +08:00
more_info_dict.update({'server_url': base_url})
2019-05-27 12:13:58 +08:00
if repo_salt:
more_info_dict.update({'repo_salt': repo_salt})
2019-07-24 14:25:20 +08:00
more_info_dict.update({'is_readonly': is_readonly})
more_info = json.dumps(more_info_dict)
2014-12-15 17:40:14 +08:00
2019-09-23 18:21:54 +08:00
print("Starting to download ...")
2013-02-20 10:52:55 +08:00
if encrypted == 1:
2017-07-14 22:59:47 +08:00
repo_passwd = args.libpasswd if args.libpasswd else getpass.getpass("Enter password for the library: ")
2013-02-20 10:52:55 +08:00
else:
repo_passwd = None
2013-02-16 21:34:07 +08:00
seafile_rpc.clone(repo,
2014-04-21 19:11:35 +08:00
version,
2019-09-23 18:21:54 +08:00
repo_name,
2013-02-20 10:52:55 +08:00
folder,
2013-02-16 21:34:07 +08:00
clone_token,
2013-02-20 10:52:55 +08:00
repo_passwd, magic,
2014-12-15 17:40:14 +08:00
email, random_key, enc_version, more_info)
2013-02-03 11:05:20 +08:00
def seaf_desync(args):
2013-02-16 21:34:07 +08:00
'''Desynchronize a library from seafile server'''
2013-02-03 11:05:20 +08:00
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2013-02-03 11:05:20 +08:00
2013-02-16 21:34:07 +08:00
repo_path = args.folder
if not repo_path:
2019-09-23 18:21:54 +08:00
print("Must specify the local path of the library")
2013-02-03 11:05:20 +08:00
sys.exit(1)
2018-08-10 18:42:55 +08:00
repo_path = abspath(repo_path)
2013-02-03 11:05:20 +08:00
2018-08-10 18:42:55 +08:00
seafile_rpc = get_rpc_client(conf_dir)
2013-02-18 11:21:11 +08:00
2013-02-16 21:34:07 +08:00
repos = seafile_rpc.get_repo_list(-1, -1)
repo = None
for r in repos:
2019-09-23 18:21:54 +08:00
if r.worktree == repo_path:
2013-02-16 21:34:07 +08:00
repo = r
break
2013-02-03 11:05:20 +08:00
2019-09-23 18:21:54 +08:00
if repo is not None:
2019-10-29 15:50:20 +08:00
if sys.version_info[0] == 2:
repo.name = repo.name.encode('utf8')
2019-09-23 18:21:54 +08:00
print("Desynchronize %s" % repo.name)
2013-02-16 21:34:07 +08:00
seafile_rpc.remove_repo(repo.id)
else:
2019-09-23 18:21:54 +08:00
print("%s is not a library" % args.folder)
2013-02-03 11:05:20 +08:00
2014-11-03 08:06:40 +08:00
def seaf_config(args):
'''Configure the seafile client'''
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2014-11-03 08:06:40 +08:00
config_key = args.key
if not config_key:
2019-09-23 18:21:54 +08:00
print("Must specify configuration key")
2014-11-03 08:06:40 +08:00
sys.exit(1)
config_value = args.value
2018-08-10 18:42:55 +08:00
seafile_rpc = get_rpc_client(conf_dir)
2014-11-03 08:06:40 +08:00
if config_value:
# set configuration key
seafile_rpc.seafile_set_config(config_key, config_value)
else:
# print configuration key
val = seafile_rpc.seafile_get_config(config_key)
2019-09-23 18:21:54 +08:00
print("%s = %s" % (config_key, val))
2014-11-03 08:06:40 +08:00
2013-02-17 15:49:53 +08:00
def seaf_status(args):
'''Show status'''
2013-02-18 11:21:11 +08:00
2016-05-27 14:03:06 +08:00
conf_dir = _conf_dir(args)
2013-02-18 11:21:11 +08:00
2018-08-10 18:42:55 +08:00
seafile_rpc = get_rpc_client(conf_dir)
2013-02-17 15:49:53 +08:00
tasks = seafile_rpc.get_clone_tasks()
2019-10-17 14:54:10 +08:00
print('# {:<50s}\t{:<20s}\t{:<20s}'.format('Name', 'Status', 'Progress'))
2013-02-17 15:49:53 +08:00
for task in tasks:
2019-10-29 15:50:20 +08:00
if sys.version_info[0] == 2:
task.repo_name = task.repo_name.encode('utf8')
2013-02-17 15:49:53 +08:00
if task.state == "fetch":
tx_task = seafile_rpc.find_transfer_task(task.repo_id)
2019-10-17 14:54:10 +08:00
try:
print('{:<50s}\t{:<20s}\t{:<.1f}%, {:<.1f}KB/s'.format(task.repo_name, 'downloading',
tx_task.block_done / tx_task.block_total * 100,
tx_task.rate / 1024.0))
except ZeroDivisionError: pass
2013-02-17 15:49:53 +08:00
elif task.state == "error":
2019-10-17 14:54:10 +08:00
err = seafile_rpc.sync_error_id_to_str(task.error)
print('{:<50s}\t{:<20s}\t{:<20s}'.format(task.repo_name, 'error', err))
2013-02-21 14:43:07 +08:00
elif task.state == 'done':
2013-02-18 11:21:11 +08:00
# will be shown in repo status
pass
2013-02-17 15:49:53 +08:00
else:
2019-10-17 14:54:10 +08:00
print('{:<50s}\t{:<20s}'.format(task.repo_name, task.state))
2013-02-17 15:49:53 +08:00
repos = seafile_rpc.get_repo_list(-1, -1)
for repo in repos:
2013-04-11 14:27:14 +08:00
auto_sync_enabled = seafile_rpc.is_auto_sync_enabled()
if not auto_sync_enabled or not repo.auto_sync:
2019-10-17 14:54:10 +08:00
print('{:<50s}\t{:<20s}'.format(repo.name, 'auto sync disabled'))
2013-02-18 11:21:11 +08:00
continue
2019-10-17 14:54:10 +08:00
task = seafile_rpc.get_repo_sync_task(repo.id)
2019-10-24 13:45:49 +08:00
if task is None:
2019-10-17 14:54:10 +08:00
print('{:<50s}\t{:<20s}'.format(repo.name, 'waiting for sync'))
elif task.state == 'uploading':
tx_task = seafile_rpc.find_transfer_task(repo.id)
try:
print('{:<50s}\t{:<20s}\t{:<.1f}%, {:<.1f}KB/s'.format(repo.name, 'uploading',
tx_task.block_done / tx_task.block_total * 100,
tx_task.rate / 1024.0))
except ZeroDivisionError: pass
elif task.state == 'downloading':
tx_task = seafile_rpc.find_transfer_task(repo.id)
try:
if tx_task.rt_state == 'data':
print('{:<50s}\t{:<20s}\t{:<.1f}%, {:<.1f}KB/s'.format(repo.name, 'downloading files',
tx_task.block_done / tx_task.block_total * 100,
tx_task.rate / 1024.0))
if tx_task.rt_state == 'fs':
print('{:<50s}\t{:<20s}\t{:<.1f}%'.format(repo.name, 'downloading file list',
tx_task.fs_objects_done / tx_task.fs_objects_total * 100))
except ZeroDivisionError: pass
elif task.state == 'error':
2019-10-28 14:40:09 +08:00
err = seafile_rpc.sync_error_id_to_str(task.error)
print('{:<50s}\t{:<20s}\t{:<20s}'.format(repo.name, 'error', err))
2013-02-17 15:49:53 +08:00
else:
2019-10-17 14:54:10 +08:00
print('{:<50s}\t{:<20s}'.format(repo.name, task.state))
2013-07-06 13:59:07 +08:00
def create_repo(url, token, args):
headers = { 'Authorization': 'Token %s' % token }
data = {
'name': args.name,
'desc': args.desc,
}
2013-12-03 21:21:57 +08:00
if args.libpasswd:
data['passwd'] = args.libpasswd
repo_info_json = urlopen(url, data=data, headers=headers)
2020-06-08 15:05:33 +08:00
repo_info = json.loads(repo_info_json.decode('utf8'))
2013-12-03 21:21:57 +08:00
return repo_info['repo_id']
2013-07-06 13:59:07 +08:00
def seaf_create(args):
'''Create a library'''
2018-11-27 18:19:06 +08:00
conf_dir = _conf_dir(args)
2013-07-06 13:59:07 +08:00
2023-01-25 00:43:30 +08:00
server_from_config = get_value_from_user_config(args, 'account', 'server')
user_from_config = get_value_from_user_config(args, 'account', 'user')
2019-11-07 18:34:26 +08:00
2013-07-06 13:59:07 +08:00
# check username and password
username = args.username
2019-11-07 18:34:26 +08:00
if not username and user_from_config:
username = user_from_config;
2013-07-06 13:59:07 +08:00
if not username:
2019-09-23 18:21:54 +08:00
username = input("Enter username: ")
2013-07-06 13:59:07 +08:00
2019-11-07 18:34:26 +08:00
url = args.server
if not url and server_from_config:
url = server_from_config
2013-07-06 13:59:07 +08:00
if not url:
2019-09-23 18:21:54 +08:00
print("Seafile server url need to be presented")
2013-07-06 13:59:07 +08:00
sys.exit(1)
2023-01-25 00:43:30 +08:00
token = get_token_from_args_or_config(args)
2021-09-07 15:58:14 +08:00
password = None
tfa = args.tfa
if not token:
password = args.password
if not password:
password = getpass.getpass("Enter password for user %s " % username)
# curl -d 'username=<USERNAME>&password=<PASSWORD>' http://127.0.0.1:8000/api2/auth-token
token = get_token(url, username, password, tfa, conf_dir)
2013-07-06 13:59:07 +08:00
2013-12-03 21:21:57 +08:00
repo_id = create_repo("%s/api2/repos/" % (url), token, args)
2019-09-23 18:21:54 +08:00
print(repo_id)
2013-07-06 13:59:07 +08:00
2013-02-03 11:05:20 +08:00
def main():
''' Main entry '''
_check_seafile()
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(title='subcommands', description='')
2014-10-27 07:49:52 +08:00
confdir_required = DEFAULT_CONF_DIR is None
2013-02-16 21:34:07 +08:00
# init
parser_init = subparsers.add_parser('init', help='Initialize config directory')
2013-02-13 12:57:02 +08:00
parser_init.set_defaults(func=seaf_init)
2014-10-27 07:49:52 +08:00
parser_init.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2013-02-13 12:57:02 +08:00
parser_init.add_argument('-d', '--dir', help='the parent directory to put seafile-data', type=str)
2013-02-03 11:05:20 +08:00
2013-02-16 21:34:07 +08:00
# start
2013-02-03 11:05:20 +08:00
parser_start = subparsers.add_parser('start',
2018-08-10 18:42:55 +08:00
help='Start seafile daemon')
2013-02-03 11:05:20 +08:00
parser_start.set_defaults(func=seaf_start_all)
2014-10-27 07:49:52 +08:00
parser_start.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2013-02-13 12:57:02 +08:00
2013-02-19 11:52:48 +08:00
# stop
parser_stop = subparsers.add_parser('stop',
2018-08-10 18:42:55 +08:00
help='Stop seafile daemon')
2013-02-19 11:52:48 +08:00
parser_stop.set_defaults(func=seaf_stop)
2014-10-27 07:49:52 +08:00
parser_stop.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2013-02-16 21:34:07 +08:00
# list
2014-08-10 17:32:11 +08:00
parser_list = subparsers.add_parser('list', help='List local libraries')
2013-02-16 21:34:07 +08:00
parser_list.set_defaults(func=seaf_list)
2014-10-27 07:49:52 +08:00
parser_list.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2021-02-22 12:28:21 +08:00
parser_list.add_argument('--json', help='output json format result', action='store_true')
2013-02-18 11:21:11 +08:00
2016-03-12 08:02:40 +08:00
# list-remote
parser_download = subparsers.add_parser('list-remote', help='List remote libraries')
parser_download.set_defaults(func=seaf_list_remote)
parser_download.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2019-11-07 18:34:26 +08:00
parser_download.add_argument('-C', help='the user config directory', type=str)
2016-03-12 08:02:40 +08:00
parser_download.add_argument('-s', '--server', help='URL for seafile server', type=str)
parser_download.add_argument('-u', '--username', help='username', type=str)
parser_download.add_argument('-p', '--password', help='password', type=str)
2021-09-07 15:58:14 +08:00
parser_download.add_argument('-T', '--token', help='token', type=str)
2018-05-25 18:29:21 +08:00
parser_download.add_argument('-a', '--tfa', help='two-factor authentication', type=str)
2021-02-22 12:28:21 +08:00
parser_download.add_argument('--json', help='output json format result', action='store_true')
2016-03-12 08:02:40 +08:00
2013-02-17 15:49:53 +08:00
# status
2014-08-10 17:32:11 +08:00
parser_status = subparsers.add_parser('status', help='Show syncing status')
2013-02-17 15:49:53 +08:00
parser_status.set_defaults(func=seaf_status)
2014-10-27 07:49:52 +08:00
parser_status.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2013-02-16 21:34:07 +08:00
# download
2013-02-13 12:57:02 +08:00
parser_download = subparsers.add_parser('download',
help='Download a library from seafile server')
parser_download.set_defaults(func=seaf_download)
2014-10-27 07:49:52 +08:00
parser_download.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2019-11-07 18:34:26 +08:00
parser_download.add_argument('-C', help='the user config directory', type=str)
2013-02-17 15:49:53 +08:00
parser_download.add_argument('-l', '--library', help='library id', type=str)
2013-02-13 12:57:02 +08:00
parser_download.add_argument('-s', '--server', help='URL for seafile server', type=str)
parser_download.add_argument('-d', '--dir', help='the directory to put the library', type=str)
2013-02-19 11:52:48 +08:00
parser_download.add_argument('-u', '--username', help='username', type=str)
2013-02-13 12:57:02 +08:00
parser_download.add_argument('-p', '--password', help='password', type=str)
2021-09-07 15:58:14 +08:00
parser_download.add_argument('-T', '--token', help='token', type=str)
2018-05-25 18:29:21 +08:00
parser_download.add_argument('-a', '--tfa', help='two-factor authentication', type=str)
2017-06-01 00:14:21 +08:00
parser_download.add_argument('-e', '--libpasswd', help='library password', type=str)
2013-02-03 11:05:20 +08:00
2016-03-12 08:02:40 +08:00
# download-by-name
parser_download = subparsers.add_parser('download-by-name',
help='Download a library defined by name from seafile server')
parser_download.set_defaults(func=seaf_download_by_name)
parser_download.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2019-11-07 18:34:26 +08:00
parser_download.add_argument('-C', help='the user config directory', type=str)
2016-03-12 08:02:40 +08:00
parser_download.add_argument('-L', '--libraryname', help='library name', type=str)
parser_download.add_argument('-s', '--server', help='URL for seafile server', type=str)
parser_download.add_argument('-d', '--dir', help='the directory to put the library', type=str)
parser_download.add_argument('-u', '--username', help='username', type=str)
parser_download.add_argument('-p', '--password', help='password', type=str)
2021-09-07 15:58:14 +08:00
parser_download.add_argument('-T', '--token', help='token', type=str)
2018-05-25 18:29:21 +08:00
parser_download.add_argument('-a', '--tfa', help='two-factor authentication', type=str)
2017-07-14 22:59:47 +08:00
parser_download.add_argument('-e', '--libpasswd', help='library password', type=str)
2016-03-12 08:02:40 +08:00
2013-02-16 21:34:07 +08:00
# sync
2013-02-03 11:05:20 +08:00
parser_sync = subparsers.add_parser('sync',
2013-02-13 12:57:02 +08:00
help='Sync a library with an existing foler')
2013-02-03 11:05:20 +08:00
parser_sync.set_defaults(func=seaf_sync)
2014-10-27 07:49:52 +08:00
parser_sync.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2019-11-07 15:31:12 +08:00
parser_sync.add_argument('-C', help='the user config directory', type=str)
2013-02-17 15:49:53 +08:00
parser_sync.add_argument('-l', '--library', help='library id', type=str)
2013-02-13 12:57:02 +08:00
parser_sync.add_argument('-s', '--server', help='URL for seafile server', type=str)
2013-02-19 11:52:48 +08:00
parser_sync.add_argument('-u', '--username', help='username', type=str)
2013-02-13 12:57:02 +08:00
parser_sync.add_argument('-p', '--password', help='password', type=str)
2021-09-07 15:58:14 +08:00
parser_sync.add_argument('-T', '--token', help='token', type=str)
2018-05-25 18:29:21 +08:00
parser_sync.add_argument('-a', '--tfa', help='two-factor authentication', type=str)
2013-02-13 12:57:02 +08:00
parser_sync.add_argument('-d', '--folder', help='the existing local folder', type=str)
2017-07-14 22:59:47 +08:00
parser_sync.add_argument('-e', '--libpasswd', help='library password', type=str)
2013-02-03 11:05:20 +08:00
2013-02-16 21:34:07 +08:00
# desync
2013-02-03 11:05:20 +08:00
parser_desync = subparsers.add_parser('desync',
2013-02-13 12:57:02 +08:00
help='Desync a library with seafile server')
2013-02-03 11:05:20 +08:00
parser_desync.set_defaults(func=seaf_desync)
2014-10-27 07:49:52 +08:00
parser_desync.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2013-02-13 12:57:02 +08:00
parser_desync.add_argument('-d', '--folder', help='the local folder', type=str)
2013-02-03 11:05:20 +08:00
2013-07-06 13:59:07 +08:00
# create
parser_create = subparsers.add_parser('create',
help='Create a library')
parser_create.set_defaults(func=seaf_create)
parser_create.add_argument('-n', '--name', help='library name', type=str)
parser_create.add_argument('-t', '--desc', help='library description', type=str)
parser_create.add_argument('-e', '--libpasswd', help='library password', type=str)
parser_create.add_argument('-s', '--server', help='URL for seafile server', type=str)
parser_create.add_argument('-u', '--username', help='username', type=str)
parser_create.add_argument('-p', '--password', help='password', type=str)
2021-09-07 15:58:14 +08:00
parser_create.add_argument('-T', '--token', help='token', type=str)
2018-05-25 18:29:21 +08:00
parser_create.add_argument('-a', '--tfa', help='two-factor authentication', type=str)
2014-10-27 07:49:52 +08:00
parser_create.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
2019-11-07 18:34:26 +08:00
parser_create.add_argument('-C', help='the user config directory', type=str)
2013-07-06 13:59:07 +08:00
2018-08-10 18:42:55 +08:00
# config
2014-11-03 08:12:34 +08:00
parser_config = subparsers.add_parser('config',
2014-11-03 08:06:40 +08:00
help='Configure seafile client')
2014-11-03 08:12:34 +08:00
parser_config.set_defaults(func=seaf_config)
parser_config.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required)
parser_config.add_argument('-k', '--key', help='configuration key', type=str)
parser_config.add_argument('-v', '--value', help='configuration value (if provided, key is set to this value)', type=str, required=False)
2014-11-03 08:06:40 +08:00
2013-03-08 11:14:36 +08:00
if len(sys.argv) == 1:
2019-09-23 18:21:54 +08:00
print(parser.format_help())
2013-03-08 11:14:36 +08:00
return
2013-02-03 11:05:20 +08:00
args = parser.parse_args()
args.func(args)
if __name__ == '__main__':
main()
2018-08-10 18:42:55 +08:00
# print('device id is {}'.format(get_device_id(DEFAULT_CONF_DIR)))