Merge branch 'add-lbrynet-console'
This commit is contained in:
commit
beb03e6425
7 changed files with 301 additions and 2 deletions
|
@ -32,6 +32,7 @@ at anytime.
|
||||||
* Added `is_mine` field to `channel_list` results
|
* Added `is_mine` field to `channel_list` results
|
||||||
* Added `claim_renew` command
|
* Added `claim_renew` command
|
||||||
* Added user configurable `auto_renew_claim_height_delta` setting, defaults to 0 (off)
|
* Added user configurable `auto_renew_claim_height_delta` setting, defaults to 0 (off)
|
||||||
|
* Added `lbrynet-console`, a tool to run or connect to lbrynet-daemon and launch an interactive python console with the api functions built in.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
* Removed claim related filter arguments `name`, `claim_id`, and `outpoint` from `file_list`, `file_delete`, `file_set_status`, and `file_reflect`
|
* Removed claim related filter arguments `name`, `claim_id`, and `outpoint` from `file_list`, `file_delete`, `file_set_status`, and `file_reflect`
|
||||||
|
|
|
@ -25,6 +25,7 @@ pip install ..\.
|
||||||
|
|
||||||
pyinstaller -y daemon.onefile.spec
|
pyinstaller -y daemon.onefile.spec
|
||||||
pyinstaller -y cli.onefile.spec
|
pyinstaller -y cli.onefile.spec
|
||||||
|
pyinstaller -y console.onefile.spec
|
||||||
|
|
||||||
nuget install secure-file -ExcludeVersion
|
nuget install secure-file -ExcludeVersion
|
||||||
secure-file\tools\secure-file -decrypt .\lbry2.pfx.enc -secret "$env:pfx_key"
|
secure-file\tools\secure-file -decrypt .\lbry2.pfx.enc -secret "$env:pfx_key"
|
||||||
|
|
|
@ -42,6 +42,7 @@ cp "$ROOT/requirements.txt" "$BUILD_DIR/requirements_base.txt"
|
||||||
cd "$BUILD_DIR"
|
cd "$BUILD_DIR"
|
||||||
pyinstaller -y daemon.onefile.spec
|
pyinstaller -y daemon.onefile.spec
|
||||||
pyinstaller -y cli.onefile.spec
|
pyinstaller -y cli.onefile.spec
|
||||||
|
pyinstaller -y console.onefile.spec
|
||||||
)
|
)
|
||||||
|
|
||||||
python "$BUILD_DIR/zip_daemon.py"
|
python "$BUILD_DIR/zip_daemon.py"
|
||||||
|
|
50
build/console.onefile.spec
Normal file
50
build/console.onefile.spec
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# -*- mode: python -*-
|
||||||
|
import platform
|
||||||
|
import os
|
||||||
|
|
||||||
|
import lbryum
|
||||||
|
|
||||||
|
dir = 'build';
|
||||||
|
cwd = os.getcwd()
|
||||||
|
if os.path.basename(cwd) != dir:
|
||||||
|
raise Exception('pyinstaller build needs to be run from the ' + dir + ' directory')
|
||||||
|
repo_base = os.path.abspath(os.path.join(cwd, '..'))
|
||||||
|
|
||||||
|
execfile(os.path.join(cwd, "entrypoint.py")) # ghetto import
|
||||||
|
|
||||||
|
|
||||||
|
system = platform.system()
|
||||||
|
if system == 'Darwin':
|
||||||
|
icns = os.path.join(repo_base, 'build', 'icon.icns')
|
||||||
|
elif system == 'Linux':
|
||||||
|
icns = os.path.join(repo_base, 'build', 'icons', '256x256.png')
|
||||||
|
elif system == 'Windows':
|
||||||
|
icns = os.path.join(repo_base, 'build', 'icons', 'lbry256.ico')
|
||||||
|
else:
|
||||||
|
print 'Warning: System {} has no icons'.format(system)
|
||||||
|
icns = None
|
||||||
|
|
||||||
|
|
||||||
|
datas = [
|
||||||
|
(os.path.join(os.path.dirname(lbryum.__file__), 'wordlist', language + '.txt'), 'lbryum/wordlist')
|
||||||
|
for language in ('chinese_simplified', 'japanese', 'spanish','english', 'portuguese')
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
a = Entrypoint('lbrynet', 'console_scripts', 'lbrynet-console', pathex=[cwd], datas=datas)
|
||||||
|
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
name='lbrynet-console',
|
||||||
|
debug=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
console=True,
|
||||||
|
icon=icns
|
||||||
|
)
|
|
@ -10,7 +10,7 @@ def main():
|
||||||
tag = subprocess.check_output(['git', 'describe']).strip()
|
tag = subprocess.check_output(['git', 'describe']).strip()
|
||||||
zipfilename = 'lbrynet-daemon-{}-{}.zip'.format(tag, get_system_label())
|
zipfilename = 'lbrynet-daemon-{}-{}.zip'.format(tag, get_system_label())
|
||||||
full_filename = os.path.join(this_dir, 'dist', zipfilename)
|
full_filename = os.path.join(this_dir, 'dist', zipfilename)
|
||||||
executables = ['lbrynet-daemon', 'lbrynet-cli']
|
executables = ['lbrynet-daemon', 'lbrynet-cli', 'lbrynet-console']
|
||||||
ext = '.exe' if platform.system() == 'Windows' else ''
|
ext = '.exe' if platform.system() == 'Windows' else ''
|
||||||
with zipfile.ZipFile(full_filename, 'w') as myzip:
|
with zipfile.ZipFile(full_filename, 'w') as myzip:
|
||||||
for executable in executables:
|
for executable in executables:
|
||||||
|
|
245
lbrynet/daemon/DaemonConsole.py
Normal file
245
lbrynet/daemon/DaemonConsole.py
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import code
|
||||||
|
import argparse
|
||||||
|
import logging.handlers
|
||||||
|
from exceptions import SystemExit
|
||||||
|
from twisted.internet import defer, reactor, threads
|
||||||
|
from lbrynet import analytics
|
||||||
|
from lbrynet import conf
|
||||||
|
from lbrynet.core import utils
|
||||||
|
from lbrynet.core import log_support
|
||||||
|
from lbrynet.daemon.DaemonServer import DaemonServer
|
||||||
|
from lbrynet.daemon.auth.client import LBRYAPIClient
|
||||||
|
from lbrynet.daemon.Daemon import Daemon
|
||||||
|
|
||||||
|
get_client = LBRYAPIClient.get_client
|
||||||
|
|
||||||
|
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(["{:<60}".format(w) for w in welcometext.splitlines()])
|
||||||
|
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 = get_client()
|
||||||
|
_fn = getattr(client, name)
|
||||||
|
_fn.__doc__ = fn.__doc__
|
||||||
|
return {name: _fn}
|
||||||
|
|
||||||
|
for method_name, method in daemon.callable_methods.iteritems():
|
||||||
|
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:
|
||||||
|
print "Available api functions: "
|
||||||
|
for name in callable_methods:
|
||||||
|
print "\t%s" % name
|
||||||
|
return
|
||||||
|
if method_name not in callable_methods:
|
||||||
|
print "\"%s\" is not a recognized api function"
|
||||||
|
return
|
||||||
|
print callable_methods[method_name].__doc__
|
||||||
|
return
|
||||||
|
|
||||||
|
locs.update({'help': help})
|
||||||
|
|
||||||
|
if started_daemon:
|
||||||
|
def exit(status=None):
|
||||||
|
if not quiet:
|
||||||
|
print "Stopping lbrynet-daemon..."
|
||||||
|
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 "error stopping reactor: ", err
|
||||||
|
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()
|
||||||
|
daemon_server = DaemonServer(analytics_manager)
|
||||||
|
try:
|
||||||
|
yield daemon_server.start(use_auth)
|
||||||
|
analytics_manager.send_server_startup_success()
|
||||||
|
if not quiet:
|
||||||
|
print "Started lbrynet-daemon!"
|
||||||
|
defer.returnValue(True)
|
||||||
|
except Exception as e:
|
||||||
|
log.exception('Failed to start lbrynet-daemon')
|
||||||
|
analytics_manager.send_server_startup_error(str(e))
|
||||||
|
daemon_server.stop()
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
def start_lbrynet_console(quiet, use_existing_daemon, useauth):
|
||||||
|
if not utils.check_connection():
|
||||||
|
print "Not connected to internet, unable to start"
|
||||||
|
raise Exception("Not connected to internet, unable to start")
|
||||||
|
if not quiet:
|
||||||
|
print "Starting lbrynet-console..."
|
||||||
|
try:
|
||||||
|
get_client().status()
|
||||||
|
d = defer.succeed(False)
|
||||||
|
if not quiet:
|
||||||
|
print "lbrynet-daemon is already running, connecting to it..."
|
||||||
|
except:
|
||||||
|
if not use_existing_daemon:
|
||||||
|
if not quiet:
|
||||||
|
print "Starting lbrynet-daemon..."
|
||||||
|
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()
|
||||||
|
start_lbrynet_console(args.quiet, args.use_existing_daemon, args.useauth)
|
||||||
|
reactor.run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
3
setup.py
3
setup.py
|
@ -36,7 +36,8 @@ requires = [
|
||||||
|
|
||||||
console_scripts = [
|
console_scripts = [
|
||||||
'lbrynet-daemon = lbrynet.daemon.DaemonControl:start',
|
'lbrynet-daemon = lbrynet.daemon.DaemonControl:start',
|
||||||
'lbrynet-cli = lbrynet.daemon.DaemonCLI:main'
|
'lbrynet-cli = lbrynet.daemon.DaemonCLI:main',
|
||||||
|
'lbrynet-console = lbrynet.daemon.DaemonConsole:main'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue