lbry-sdk/lbrynet/extras/daemon/DaemonConsole.py

232 lines
8.2 KiB
Python
Raw Normal View History

2017-12-05 17:38:50 +01:00
import sys
import code
import argparse
import asyncio
2017-12-05 17:38:50 +01:00
import logging.handlers
from twisted.internet import defer, reactor, threads
from aiohttp import client_exceptions
2018-11-07 21:15:05 +01:00
from lbrynet.extras.daemon import analytics
from lbrynet import utils, conf
from lbrynet import log_support
from .auth.client import LBRYAPIClient
from .Daemon import Daemon
2017-12-05 17:38:50 +01:00
log = logging.getLogger(__name__)
if sys.platform.startswith('darwin') or sys.platform.startswith('linux'):
def color(msg, c="white"):
_colors = {
"normal": (0, 37),
"underlined": (2, 37),
"red": (1, 31),
"green": (1, 32),
"yellow": (1, 33),
"blue": (1, 33),
"magenta": (1, 34),
"cyan": (1, 35),
"white": (1, 36),
"grey": (1, 37)
}
i, j = _colors[c]
return "\033[%i;%i;40m%s\033[0m" % (i, j, msg)
logo = """\
ç
,,
¬
, ^,
`
,
`
,
m , ,,µ
m ^
Q '▀▀▓▓▓▌▄, ,▄█▓▓█▀ ▄█▓▓▓▓▓▀
,
^ `
'▀▀▓▓▓▌▄, ╙▀██▀` ╓▄▓▓▓▀╙
,
`
"""
else:
def color(msg, c=None):
return msg
logo = """\
'.
++++.
+++,;+++,
:+++ :+++:
+++ ,+++;
'++; .+++'
`+++ `++++
+++. `++++
;+++ ++++
+++ +++
+++: '+
,+++ +++
+++` +++:
`+' ,+++
`+ + +++
`+ +++ '++' :'+++:
`+ ++++ `+++ ++++
`+ ++++ +++. :+++'
`+, ++++ ;+++ +++++
`+++, ++++ +++ +++; +
,+++, ++++ +++: .+++
,+++: '++++++ +++`
,+++: '++ '++'
,+++: `+++
.+++; +++,
.+++; ;+++
.+++; +++
`+++++:
`++
"""
welcometext = """\
For a list of available commands:
>>>help()
To see the documentation for a given command:
>>>help("resolve")
To exit:
>>>exit()
"""
welcome = "{:*^60}\n".format(" Welcome to the lbrynet interactive console! ")
welcome += "\n".join([f"{w:<60}" for w in welcometext.splitlines()])
2017-12-05 17:38:50 +01:00
welcome += "\n%s" % ("*" * 60)
welcome = color(welcome, "grey")
banner = color(logo, "green") + color(welcome, "grey")
def get_methods(daemon):
locs = {}
def wrapped(name, fn):
client = LBRYAPIClient.get_client()
2017-12-05 17:38:50 +01:00
_fn = getattr(client, name)
_fn.__doc__ = fn.__doc__
return {name: _fn}
for method_name, method in daemon.callable_methods.items():
2017-12-05 17:38:50 +01:00
locs.update(wrapped(method_name, method))
return locs
def run_terminal(callable_methods, started_daemon, quiet=False):
locs = {}
locs.update(callable_methods)
def help(method_name=None):
if not method_name:
2018-07-22 01:08:28 +02:00
print("Available api functions: ")
2017-12-05 17:38:50 +01:00
for name in callable_methods:
2018-07-22 01:08:28 +02:00
print("\t%s" % name)
2017-12-05 17:38:50 +01:00
return
if method_name not in callable_methods:
2018-07-22 01:08:28 +02:00
print("\"%s\" is not a recognized api function")
2017-12-05 17:38:50 +01:00
return
2018-07-22 01:08:28 +02:00
print(callable_methods[method_name].__doc__)
2017-12-05 17:38:50 +01:00
return
locs.update({'help': help})
if started_daemon:
def exit(status=None):
if not quiet:
2018-07-22 01:08:28 +02:00
print("Stopping lbrynet-daemon...")
2017-12-05 17:38:50 +01:00
callable_methods['daemon_stop']()
return sys.exit(status)
locs.update({'exit': exit})
else:
def exit(status=None):
try:
reactor.callLater(0, reactor.stop)
except Exception as err:
print(f"error stopping reactor: {err}")
2017-12-05 17:38:50 +01:00
return sys.exit(status)
locs.update({'exit': exit})
code.interact(banner if not quiet else "", local=locs)
@defer.inlineCallbacks
def start_server_and_listen(use_auth, analytics_manager, quiet):
log_support.configure_console()
logging.getLogger("lbrynet").setLevel(logging.CRITICAL)
logging.getLogger("lbryum").setLevel(logging.CRITICAL)
logging.getLogger("requests").setLevel(logging.CRITICAL)
analytics_manager.send_server_startup()
yield Daemon().start_listening()
2017-12-05 17:38:50 +01:00
def threaded_terminal(started_daemon, quiet):
callable_methods = get_methods(Daemon)
d = threads.deferToThread(run_terminal, callable_methods, started_daemon, quiet)
d.addErrback(lambda err: err.trap(SystemExit))
d.addErrback(log.exception)
async def start_lbrynet_console(quiet, use_existing_daemon, useauth):
2017-12-05 17:38:50 +01:00
if not utils.check_connection():
2018-07-22 01:08:28 +02:00
print("Not connected to internet, unable to start")
2017-12-05 17:38:50 +01:00
raise Exception("Not connected to internet, unable to start")
if not quiet:
2018-07-22 01:08:28 +02:00
print("Starting lbrynet-console...")
2017-12-05 17:38:50 +01:00
try:
await LBRYAPIClient.get_client().status()
2017-12-05 17:38:50 +01:00
d = defer.succeed(False)
if not quiet:
2018-07-22 01:08:28 +02:00
print("lbrynet-daemon is already running, connecting to it...")
except client_exceptions.ClientConnectorError:
2017-12-05 17:38:50 +01:00
if not use_existing_daemon:
if not quiet:
2018-07-22 01:08:28 +02:00
print("Starting lbrynet-daemon...")
2017-12-05 17:38:50 +01:00
analytics_manager = analytics.Manager.new_instance()
d = start_server_and_listen(useauth, analytics_manager, quiet)
else:
raise Exception("cannot connect to an existing daemon instance, "
"and set to not start a new one")
d.addCallback(threaded_terminal, quiet)
d.addErrback(log.exception)
def main():
conf.initialize_settings()
parser = argparse.ArgumentParser(description="Launch lbrynet-daemon")
parser.add_argument(
"--use_existing_daemon",
help="Start lbrynet-daemon if it isn't already running",
action="store_true",
default=False,
dest="use_existing_daemon"
)
parser.add_argument(
"--quiet", dest="quiet", action="store_true", default=False
)
parser.add_argument(
"--http-auth", dest="useauth", action="store_true", default=conf.settings['use_auth_http']
)
args = parser.parse_args()
loop = asyncio.get_event_loop()
loop.run_until_complete(start_lbrynet_console(args.quiet, args.use_existing_daemon, args.useauth))
2017-12-05 17:38:50 +01:00
reactor.run()
if __name__ == "__main__":
main()