2018-07-26 05:27:53 +02:00
|
|
|
import sys
|
2018-08-16 01:23:06 +02:00
|
|
|
from twisted.internet import asyncioreactor
|
|
|
|
if 'twisted.internet.reactor' not in sys.modules:
|
|
|
|
asyncioreactor.install()
|
|
|
|
else:
|
|
|
|
from twisted.internet import reactor
|
2018-10-01 23:38:03 +02:00
|
|
|
if not isinstance(reactor, asyncioreactor.AsyncioSelectorReactor) and getattr(sys, 'frozen', False):
|
2018-08-16 01:23:06 +02:00
|
|
|
# pyinstaller hooks install the default reactor before
|
|
|
|
# any of our code runs, see kivy for similar problem:
|
|
|
|
# https://github.com/kivy/kivy/issues/4182
|
|
|
|
del sys.modules['twisted.internet.reactor']
|
|
|
|
asyncioreactor.install()
|
2018-10-01 23:38:03 +02:00
|
|
|
from twisted.internet import reactor
|
2018-08-16 01:23:06 +02:00
|
|
|
|
2018-07-27 03:19:29 +02:00
|
|
|
import json
|
2018-07-26 05:27:53 +02:00
|
|
|
import asyncio
|
2018-08-04 23:19:10 +02:00
|
|
|
from aiohttp.client_exceptions import ClientConnectorError
|
|
|
|
from requests.exceptions import ConnectionError
|
2018-07-26 05:27:53 +02:00
|
|
|
from docopt import docopt
|
|
|
|
from textwrap import dedent
|
|
|
|
|
2018-10-05 16:20:32 +02:00
|
|
|
from lbrynet import __name__ as lbrynet_name
|
2018-11-04 19:44:17 +01:00
|
|
|
from lbrynet.extras.daemon.Daemon import Daemon
|
|
|
|
from lbrynet.extras.daemon.DaemonControl import start as daemon_main
|
|
|
|
from lbrynet.extras.daemon.DaemonConsole import main as daemon_console
|
|
|
|
from lbrynet.extras.daemon.auth.client import LBRYAPIClient
|
2018-11-09 19:06:02 +01:00
|
|
|
from lbrynet.extras.system_info import get_platform
|
2018-07-26 05:27:53 +02:00
|
|
|
|
|
|
|
|
2018-08-04 23:19:10 +02:00
|
|
|
async def execute_command(method, params, conf_path=None):
|
|
|
|
# this check if the daemon is running or not
|
2018-11-07 21:24:05 +01:00
|
|
|
api = None
|
2018-08-04 23:19:10 +02:00
|
|
|
try:
|
2018-08-11 12:25:36 +02:00
|
|
|
api = await LBRYAPIClient.get_client(conf_path)
|
2018-08-04 23:19:10 +02:00
|
|
|
await api.status()
|
|
|
|
except (ClientConnectorError, ConnectionError):
|
2018-11-07 21:24:05 +01:00
|
|
|
if api:
|
|
|
|
await api.session.close()
|
2018-08-04 23:19:10 +02:00
|
|
|
print("Could not connect to daemon. Are you sure it's running?")
|
|
|
|
return 1
|
|
|
|
|
|
|
|
# this actually executes the method
|
2018-11-07 21:24:05 +01:00
|
|
|
resp = await api.call(method, params)
|
|
|
|
|
2018-08-04 23:19:10 +02:00
|
|
|
try:
|
2018-08-16 18:13:54 +02:00
|
|
|
await api.session.close()
|
2018-08-04 23:19:10 +02:00
|
|
|
print(json.dumps(resp["result"], indent=2))
|
|
|
|
except KeyError:
|
|
|
|
if resp["error"]["code"] == -32500:
|
|
|
|
print(json.dumps(resp["error"], indent=2))
|
|
|
|
else:
|
|
|
|
print(json.dumps(resp["error"]["message"], indent=2))
|
2018-07-26 05:27:53 +02:00
|
|
|
|
|
|
|
|
|
|
|
def print_help():
|
|
|
|
print(dedent("""
|
|
|
|
NAME
|
2018-08-04 23:19:10 +02:00
|
|
|
lbrynet - LBRY command line client.
|
2018-07-26 05:27:53 +02:00
|
|
|
|
|
|
|
USAGE
|
2018-08-04 23:19:10 +02:00
|
|
|
lbrynet [--conf <config file>] <command> [<args>]
|
2018-07-26 05:27:53 +02:00
|
|
|
|
|
|
|
EXAMPLES
|
2018-10-31 21:42:40 +01:00
|
|
|
lbrynet start # starts the daemon. The daemon needs to be running for commands to work
|
|
|
|
lbrynet help # display this message
|
|
|
|
lbrynet help <command_name> # get help for a command(doesn't need the daemon to be running)
|
|
|
|
lbrynet commands # list available commands
|
|
|
|
lbrynet status # get the running status of the daemon
|
|
|
|
lbrynet --conf ~/l1.conf # use ~/l1.conf as config file
|
|
|
|
lbrynet resolve what # resolve a name
|
2018-07-26 05:27:53 +02:00
|
|
|
"""))
|
|
|
|
|
|
|
|
|
|
|
|
def print_help_for_command(command):
|
2018-07-27 13:30:42 +02:00
|
|
|
fn = Daemon.callable_methods.get(command)
|
|
|
|
if fn:
|
|
|
|
print(dedent(fn.__doc__))
|
|
|
|
else:
|
|
|
|
print("Invalid command name")
|
|
|
|
|
|
|
|
|
2018-08-04 23:19:10 +02:00
|
|
|
def normalize_value(x, key=None):
|
2018-07-26 05:27:53 +02:00
|
|
|
if not isinstance(x, str):
|
|
|
|
return x
|
|
|
|
if key in ('uri', 'channel_name', 'name', 'file_name', 'download_directory'):
|
|
|
|
return x
|
2018-08-04 23:19:10 +02:00
|
|
|
if x.lower() == 'true':
|
2018-07-26 05:27:53 +02:00
|
|
|
return True
|
2018-08-04 23:19:10 +02:00
|
|
|
if x.lower() == 'false':
|
2018-07-26 05:27:53 +02:00
|
|
|
return False
|
2018-08-06 06:28:11 +02:00
|
|
|
if x.isdigit():
|
2018-07-26 05:27:53 +02:00
|
|
|
return int(x)
|
2018-08-06 06:28:11 +02:00
|
|
|
return x
|
2018-07-26 05:27:53 +02:00
|
|
|
|
|
|
|
|
|
|
|
def remove_brackets(key):
|
|
|
|
if key.startswith("<") and key.endswith(">"):
|
|
|
|
return str(key[1:-1])
|
|
|
|
return key
|
|
|
|
|
|
|
|
|
|
|
|
def set_kwargs(parsed_args):
|
|
|
|
kwargs = {}
|
|
|
|
for key, arg in parsed_args.items():
|
|
|
|
k = None
|
|
|
|
if arg is None:
|
|
|
|
continue
|
|
|
|
elif key.startswith("--") and remove_brackets(key[2:]) not in kwargs:
|
|
|
|
k = remove_brackets(key[2:])
|
|
|
|
elif remove_brackets(key) not in kwargs:
|
|
|
|
k = remove_brackets(key)
|
2018-08-04 23:19:10 +02:00
|
|
|
kwargs[k] = normalize_value(arg, k)
|
2018-07-26 05:27:53 +02:00
|
|
|
return kwargs
|
|
|
|
|
|
|
|
|
2018-07-27 14:23:37 +02:00
|
|
|
def main(argv=None):
|
|
|
|
argv = argv or sys.argv[1:]
|
2018-07-26 05:27:53 +02:00
|
|
|
if not argv:
|
|
|
|
print_help()
|
|
|
|
return 1
|
|
|
|
|
2018-08-04 23:19:10 +02:00
|
|
|
conf_path = None
|
|
|
|
if len(argv) and argv[0] == "--conf":
|
|
|
|
if len(argv) < 2:
|
|
|
|
print("No config file specified for --conf option")
|
|
|
|
print_help()
|
|
|
|
return 1
|
|
|
|
|
|
|
|
conf_path = argv[1]
|
|
|
|
argv = argv[2:]
|
|
|
|
|
2018-07-26 05:27:53 +02:00
|
|
|
method, args = argv[0], argv[1:]
|
|
|
|
|
|
|
|
if method in ['help', '--help', '-h']:
|
|
|
|
if len(args) == 1:
|
|
|
|
print_help_for_command(args[0])
|
|
|
|
else:
|
|
|
|
print_help()
|
2018-08-04 23:19:10 +02:00
|
|
|
return 0
|
2018-07-26 05:27:53 +02:00
|
|
|
|
|
|
|
elif method in ['version', '--version', '-v']:
|
2018-10-09 17:14:25 +02:00
|
|
|
print("{lbrynet_name} {lbrynet_version}".format(
|
2018-11-08 00:35:32 +01:00
|
|
|
lbrynet_name=lbrynet_name, **get_platform()
|
2018-10-09 17:14:25 +02:00
|
|
|
))
|
2018-08-04 23:19:10 +02:00
|
|
|
return 0
|
2018-07-26 05:27:53 +02:00
|
|
|
|
|
|
|
elif method == 'start':
|
2018-08-04 23:19:10 +02:00
|
|
|
sys.exit(daemon_main(args, conf_path))
|
2018-07-26 05:27:53 +02:00
|
|
|
|
2018-08-04 23:19:10 +02:00
|
|
|
elif method == 'console':
|
|
|
|
sys.exit(daemon_console())
|
2018-07-26 05:27:53 +02:00
|
|
|
|
2018-08-04 23:19:10 +02:00
|
|
|
elif method not in Daemon.callable_methods:
|
|
|
|
if method not in Daemon.deprecated_methods:
|
2018-10-18 12:42:45 +02:00
|
|
|
print(f'{method} is not a valid command.')
|
2018-08-04 23:19:10 +02:00
|
|
|
return 1
|
2018-09-25 22:21:20 +02:00
|
|
|
|
2018-08-04 23:19:10 +02:00
|
|
|
new_method = Daemon.deprecated_methods[method].new_command
|
2018-09-25 22:21:20 +02:00
|
|
|
if new_method is None:
|
2018-10-18 12:42:45 +02:00
|
|
|
print(f"{method} is permanently deprecated and does not have a replacement command.")
|
2018-09-25 22:21:20 +02:00
|
|
|
return 0
|
|
|
|
|
2018-10-18 12:42:45 +02:00
|
|
|
print(f"{method} is deprecated, using {new_method}.")
|
2018-08-04 23:19:10 +02:00
|
|
|
method = new_method
|
|
|
|
|
|
|
|
fn = Daemon.callable_methods[method]
|
|
|
|
parsed = docopt(fn.__doc__, args)
|
|
|
|
params = set_kwargs(parsed)
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
loop.run_until_complete(execute_command(method, params, conf_path))
|
2018-07-26 05:27:53 +02:00
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2018-07-27 13:30:42 +02:00
|
|
|
sys.exit(main())
|