lbry-sdk/lbrynet/daemon/DaemonCLI.py

228 lines
6.9 KiB
Python
Raw Normal View History

2016-11-11 19:40:19 +01:00
import json
2017-01-03 20:13:01 +01:00
import os
2017-01-09 20:03:25 +01:00
import sys
import colorama
2017-05-28 22:02:22 +02:00
from docopt import docopt
from collections import OrderedDict
2017-01-09 20:03:25 +01:00
from lbrynet import conf
from lbrynet.core import utils
from lbrynet.daemon.auth.client import JSONRPCException, LBRYAPIClient
from lbrynet.daemon.Daemon import LOADING_WALLET_CODE, Daemon
from lbrynet.core.system_info import get_platform
2016-11-11 19:40:19 +01:00
from jsonrpc.common import RPCError
from urllib2 import URLError, HTTPError
from httplib import UNAUTHORIZED
2016-07-06 09:02:55 +02:00
2017-05-28 22:02:22 +02:00
def remove_brackets(key):
if key.startswith("<") and key.endswith(">"):
return str(key[1:-1])
return key
def set_flag_vals(flag_names, parsed_args):
kwargs = OrderedDict()
for key, arg in parsed_args.iteritems():
if arg is None:
continue
elif key.startswith("--"):
if remove_brackets(key[2:]) not in kwargs:
k = remove_brackets(key[2:])
elif key in flag_names:
if remove_brackets(flag_names[key]) not in kwargs:
k = remove_brackets(flag_names[key])
2017-05-28 22:02:22 +02:00
elif remove_brackets(key) not in kwargs:
k = remove_brackets(key)
kwargs[k] = guess_type(arg, k)
2017-05-28 22:02:22 +02:00
return kwargs
2017-01-09 20:03:25 +01:00
def main():
2017-05-28 22:02:22 +02:00
if len(sys.argv[1:]):
method, args = sys.argv[1], sys.argv[2:]
else:
print_help()
return
if method in ['help', '--help', '-h']:
if len(args) == 1:
print_help_for_command(args[0])
else:
print_help()
return
2017-01-09 20:03:25 +01:00
elif method in ['version', '--version']:
print utils.json_dumps_pretty(get_platform(get_ip=False))
return
2017-05-28 22:02:22 +02:00
if method not in Daemon.callable_methods:
if method not in Daemon.deprecated_methods:
print_error("\"%s\" is not a valid command." % method)
return
new_method = Daemon.deprecated_methods[method]._new_command
print_error("\"%s\" is deprecated, using \"%s\"." % (method, new_method))
method = new_method
2017-05-28 22:02:22 +02:00
fn = Daemon.callable_methods[method]
if hasattr(fn, "_flags"):
flag_names = fn._flags
else:
flag_names = {}
parsed = docopt(fn.__doc__, args)
kwargs = set_flag_vals(flag_names, parsed)
colorama.init()
2017-01-09 20:03:25 +01:00
conf.initialize_settings()
api = LBRYAPIClient.get_client()
try:
status = api.status()
except URLError as err:
if isinstance(err, HTTPError) and err.code == UNAUTHORIZED:
print_error("Daemon requires authentication, but none was provided.",
suggest_help=False)
else:
print_error("Could not connect to daemon. Are you sure it's running?",
suggest_help=False)
2017-01-09 20:03:25 +01:00
return 1
2017-07-19 17:42:17 +02:00
status_code = status['startup_status']['code']
if status_code != "started" and method not in Daemon.allowed_during_startup:
2017-01-09 20:03:25 +01:00
print "Daemon is in the process of starting. Please try again in a bit."
message = status['startup_status']['message']
if message:
if (
status['startup_status']['code'] == LOADING_WALLET_CODE
and status['blockchain_status']['blocks_behind'] > 0
2017-01-09 20:03:25 +01:00
):
message += '. Blocks left: ' + str(status['blockchain_status']['blocks_behind'])
2017-01-09 20:03:25 +01:00
print " Status: " + message
return 1
2017-01-11 21:31:08 +01:00
# TODO: check if port is bound. Error if its not
2017-05-28 22:02:22 +02:00
try:
result = api.call(method, **kwargs)
if isinstance(result, basestring):
# printing the undumped string is prettier
print result
2017-01-09 20:03:25 +01:00
else:
2017-05-28 22:02:22 +02:00
print utils.json_dumps_pretty(result)
except (RPCError, KeyError, JSONRPCException, HTTPError) as err:
if isinstance(err, HTTPError):
error_body = err.read()
try:
error_data = json.loads(error_body)
except ValueError:
print (
"There was an error, and the response was not valid JSON.\n" +
"Raw JSONRPC response:\n" + error_body
)
return 1
print_error(error_data['error']['message'] + "\n", suggest_help=False)
2017-12-13 19:56:44 +01:00
if 'data' in error_data['error'] and 'traceback' in error_data['error']['data']:
print "Here's the traceback for the error you encountered:"
print "\n".join(error_data['error']['data']['traceback'])
print_help_for_command(method)
elif isinstance(err, RPCError):
print_error(err.msg, suggest_help=False)
# print_help_for_command(method)
2017-05-28 22:02:22 +02:00
else:
print_error("Something went wrong\n", suggest_help=False)
2017-12-13 22:43:49 +01:00
print str(err)
2017-01-09 20:03:25 +01:00
2017-05-28 22:02:22 +02:00
return 1
def guess_type(x, key=None):
2017-05-28 22:02:22 +02:00
if not isinstance(x, (unicode, str)):
return x
if key in ('uri', 'channel_name', 'name', 'file_name', 'download_directory'):
return x
2017-03-23 22:44:06 +01:00
if x in ('true', 'True', 'TRUE'):
return True
if x in ('false', 'False', 'FALSE'):
return False
if '.' in x:
try:
return float(x)
except ValueError:
# not a float
pass
try:
return int(x)
except ValueError:
return x
2017-01-09 20:03:25 +01:00
def print_help_suggestion():
print "See `{} help` for more information.".format(os.path.basename(sys.argv[0]))
def print_error(message, suggest_help=True):
error_style = colorama.Style.BRIGHT + colorama.Fore.RED
print error_style + "ERROR: " + message + colorama.Style.RESET_ALL
2017-01-09 20:03:25 +01:00
if suggest_help:
print_help_suggestion()
2017-05-28 22:02:22 +02:00
def print_help():
commands = Daemon.callable_methods.keys()
2017-01-04 23:15:08 +01:00
print "\n".join([
"NAME",
" lbrynet-cli - LBRY command line client.",
"",
"USAGE",
" lbrynet-cli <command> [<args>]",
"",
"EXAMPLES",
2017-06-08 21:24:58 +02:00
" lbrynet-cli commands # list available commands",
" lbrynet-cli status # get daemon status",
" lbrynet-cli resolve_name what # resolve a name",
" lbrynet-cli help resolve_name # get help for a command",
2017-01-11 21:31:08 +01:00
"",
"COMMANDS",
2017-05-28 22:02:22 +02:00
wrap_list_to_term_width(commands, prefix=' ')
2017-01-04 23:15:08 +01:00
])
2017-05-28 22:02:22 +02:00
def print_help_for_command(command):
fn = Daemon.callable_methods.get(command)
if fn:
print "Help for %s method:\n%s" % (command, fn.__doc__)
2017-01-04 23:15:08 +01:00
def wrap_list_to_term_width(l, width=None, separator=', ', prefix=''):
if width is None:
try:
_, width = os.popen('stty size', 'r').read().split()
width = int(width)
except:
pass
if not width:
width = 80
lines = []
2017-01-09 20:03:25 +01:00
curr_line = ''
2017-01-04 23:15:08 +01:00
for item in l:
new_line = curr_line + item + separator
2017-01-09 20:03:25 +01:00
if len(new_line) + len(prefix) > width:
2017-01-04 23:15:08 +01:00
lines.append(curr_line)
2017-01-09 20:03:25 +01:00
curr_line = item + separator
2017-01-04 23:15:08 +01:00
else:
curr_line = new_line
2017-01-09 20:03:25 +01:00
lines.append(curr_line)
2017-01-04 23:15:08 +01:00
2017-01-09 20:03:25 +01:00
ret = prefix + ("\n" + prefix).join(lines)
if ret.endswith(separator):
ret = ret[:-len(separator)]
return ret
if __name__ == '__main__':
2017-01-09 20:03:25 +01:00
sys.exit(main())