forked from LBRYCommunity/lbry-sdk
Merge branch 'rename_api_methods'
* rename_api_methods: updates based on job's comments appveyor is a line-length nazi detect authentication error and warn accordingly remove authjsonrpc subhandlers. we dont use them rpc works with authentication restore one deprecated method (for now) incorporate job's changes remove return codes that are not being used make sure deprecated methods still return results better cli help remove extraneous ellipses in messages rename api endpoints
This commit is contained in:
commit
93ff4f63b5
18 changed files with 840 additions and 674 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -9,12 +9,11 @@
|
|||
|
||||
/build
|
||||
/dist
|
||||
/lbrynet.egg-info
|
||||
|
||||
.idea/.name
|
||||
.coverage
|
||||
.DS_Store
|
||||
|
||||
lbrynet.egg-info/PKG-INFO
|
||||
|
||||
# temporary files from the twisted.trial test runner
|
||||
_trial_temp/
|
9
FAQ.md
9
FAQ.md
|
@ -77,9 +77,10 @@ Note: the lbry api can only be used while either the app or lbrynet-daemon comma
|
|||
sys.exit(0)
|
||||
|
||||
api = JSONRPCProxy.from_url(API_CONNECTION_STRING)
|
||||
if not api.is_running():
|
||||
print api.daemon_status()
|
||||
status = api.status()
|
||||
if not status['is_running']:
|
||||
print status
|
||||
else:
|
||||
for func in api.help():
|
||||
print "%s:\n%s" % (func, api.help({'function': func}))
|
||||
for cmd in api.commands():
|
||||
print "%s:\n%s" % (cmd, api.help({'command': cmd}))
|
||||
|
||||
|
|
|
@ -49,11 +49,12 @@ except:
|
|||
API_CONNECTION_STRING = "http://localhost:5279/lbryapi"
|
||||
|
||||
api = JSONRPCProxy.from_url(API_CONNECTION_STRING)
|
||||
if not api.is_running():
|
||||
print api.daemon_status()
|
||||
status = api.status()
|
||||
if not status['is_running']:
|
||||
print status
|
||||
else:
|
||||
for func in api.help():
|
||||
print "%s:\n%s" % (func, api.help({'function': func}))
|
||||
for cmd in api.commands():
|
||||
print "%s:\n%s" % (cmd, api.help({'command': cmd}))
|
||||
```
|
||||
|
||||
If you've installed lbrynet, it comes with a file sharing application, called `lbrynet-daemon`, which breaks
|
||||
|
|
|
@ -96,9 +96,5 @@ class InvalidAuthenticationToken(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class SubhandlerError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NegotiationError(Exception):
|
||||
pass
|
||||
|
|
|
@ -182,10 +182,6 @@ class Wallet(object):
|
|||
"""This class implements the Wallet interface for the LBRYcrd payment system"""
|
||||
implements(IWallet)
|
||||
|
||||
_FIRST_RUN_UNKNOWN = 0
|
||||
_FIRST_RUN_YES = 1
|
||||
_FIRST_RUN_NO = 2
|
||||
|
||||
def __init__(self, storage):
|
||||
if not isinstance(storage, MetaDataStorage):
|
||||
raise ValueError('storage must be an instance of MetaDataStorage')
|
||||
|
@ -209,7 +205,6 @@ class Wallet(object):
|
|||
self._manage_count = 0
|
||||
self._balance_refresh_time = 3
|
||||
self._batch_count = 20
|
||||
self._first_run = self._FIRST_RUN_UNKNOWN
|
||||
|
||||
def start(self):
|
||||
def start_manage():
|
||||
|
@ -703,20 +698,6 @@ class Wallet(object):
|
|||
def get_available_balance(self):
|
||||
return float(self.wallet_balance - self.total_reserved_points)
|
||||
|
||||
def is_first_run(self):
|
||||
if self._first_run == self._FIRST_RUN_UNKNOWN:
|
||||
d = self._check_first_run()
|
||||
|
||||
def set_first_run(is_first):
|
||||
self._first_run = self._FIRST_RUN_YES if is_first else self._FIRST_RUN_NO
|
||||
|
||||
d.addCallback(set_first_run)
|
||||
else:
|
||||
d = defer.succeed(self._FIRST_RUN_YES if self._first_run else self._FIRST_RUN_NO)
|
||||
|
||||
d.addCallback(lambda _: self._first_run == self._FIRST_RUN_YES)
|
||||
return d
|
||||
|
||||
def _get_status_of_claim(self, claim_outpoint, name, sd_hash):
|
||||
d = self.get_claims_from_tx(claim_outpoint['txid'])
|
||||
|
||||
|
@ -819,9 +800,6 @@ class Wallet(object):
|
|||
def _get_claims_for_name(self, name):
|
||||
return defer.fail(NotImplementedError())
|
||||
|
||||
def _check_first_run(self):
|
||||
return defer.fail(NotImplementedError())
|
||||
|
||||
def _send_name_claim(self, name, val, amount):
|
||||
return defer.fail(NotImplementedError())
|
||||
|
||||
|
@ -865,13 +843,13 @@ class LBRYumWallet(Wallet):
|
|||
self._config = config
|
||||
self.network = None
|
||||
self.wallet = None
|
||||
self.first_run = False
|
||||
self.is_first_run = False
|
||||
self.printed_retrieving_headers = False
|
||||
self._start_check = None
|
||||
self._catch_up_check = None
|
||||
self._caught_up_counter = 0
|
||||
self._lag_counter = 0
|
||||
self.blocks_behind_alert = 0
|
||||
self.blocks_behind = 0
|
||||
self.catchup_progress = 0
|
||||
self.max_behind = 0
|
||||
|
||||
|
@ -881,16 +859,15 @@ class LBRYumWallet(Wallet):
|
|||
def setup_network():
|
||||
self.config = make_config(self._config)
|
||||
self.network = Network(self.config)
|
||||
alert.info("Loading the wallet...")
|
||||
alert.info("Loading the wallet")
|
||||
return defer.succeed(self.network.start())
|
||||
|
||||
|
||||
d = setup_network()
|
||||
|
||||
def check_started():
|
||||
if self.network.is_connecting():
|
||||
if not self.printed_retrieving_headers and self.network.blockchain.retrieving_headers:
|
||||
alert.info("Running the wallet for the first time...this may take a moment.")
|
||||
alert.info("Running the wallet for the first time. This may take a moment.")
|
||||
self.printed_retrieving_headers = True
|
||||
return False
|
||||
self._start_check.stop()
|
||||
|
@ -941,7 +918,7 @@ class LBRYumWallet(Wallet):
|
|||
storage = lbryum.wallet.WalletStorage(path)
|
||||
wallet = lbryum.wallet.Wallet(storage)
|
||||
if not storage.file_exists:
|
||||
self.first_run = True
|
||||
self.is_first_run = True
|
||||
seed = wallet.make_seed()
|
||||
wallet.add_seed(seed, None)
|
||||
wallet.create_master_keys(None)
|
||||
|
@ -957,7 +934,13 @@ class LBRYumWallet(Wallet):
|
|||
local_height = self.network.get_catchup_progress()
|
||||
remote_height = self.network.get_server_height()
|
||||
|
||||
if remote_height != 0 and remote_height - local_height <= 5:
|
||||
if remote_height == 0:
|
||||
return
|
||||
|
||||
height_diff = remote_height - local_height
|
||||
|
||||
if height_diff <= 5:
|
||||
self.blocks_behind = 0
|
||||
msg = ""
|
||||
if self._caught_up_counter != 0:
|
||||
msg += "All caught up. "
|
||||
|
@ -966,27 +949,29 @@ class LBRYumWallet(Wallet):
|
|||
self._catch_up_check.stop()
|
||||
self._catch_up_check = None
|
||||
blockchain_caught_d.callback(True)
|
||||
return
|
||||
|
||||
elif remote_height != 0:
|
||||
past_blocks_behind = self.blocks_behind_alert
|
||||
self.blocks_behind_alert = remote_height - local_height
|
||||
if self.blocks_behind_alert < past_blocks_behind:
|
||||
self._lag_counter = 0
|
||||
self.is_lagging = False
|
||||
else:
|
||||
self._lag_counter += 1
|
||||
if self._lag_counter >= 900:
|
||||
self.is_lagging = True
|
||||
if height_diff < self.blocks_behind:
|
||||
# We're making progress in catching up
|
||||
self._lag_counter = 0
|
||||
self.is_lagging = False
|
||||
else:
|
||||
# No progress. Might be lagging
|
||||
self._lag_counter += 1
|
||||
if self._lag_counter >= 900:
|
||||
self.is_lagging = True
|
||||
|
||||
if self.blocks_behind_alert > self.max_behind:
|
||||
self.max_behind = self.blocks_behind_alert
|
||||
self.catchup_progress = int(100 * (self.blocks_behind_alert / (5 + self.max_behind)))
|
||||
if self._caught_up_counter == 0:
|
||||
alert.info('Catching up with the blockchain...showing blocks left...')
|
||||
if self._caught_up_counter % 30 == 0:
|
||||
alert.info('%d...', (remote_height - local_height))
|
||||
self.blocks_behind = height_diff
|
||||
|
||||
self._caught_up_counter += 1
|
||||
if self.blocks_behind > self.max_behind:
|
||||
self.max_behind = self.blocks_behind
|
||||
self.catchup_progress = int(100 * (self.blocks_behind / (5 + self.max_behind)))
|
||||
if self._caught_up_counter == 0:
|
||||
alert.info('Catching up with the blockchain')
|
||||
if self._caught_up_counter % 30 == 0:
|
||||
alert.info('Blocks left: %d', (remote_height - local_height))
|
||||
|
||||
self._caught_up_counter += 1
|
||||
|
||||
def log_error(err):
|
||||
log.warning(err.getErrorMessage())
|
||||
|
@ -1052,9 +1037,6 @@ class LBRYumWallet(Wallet):
|
|||
def get_name_claims(self):
|
||||
return self._run_cmd_as_defer_succeed('getnameclaims')
|
||||
|
||||
def _check_first_run(self):
|
||||
return defer.succeed(self.first_run)
|
||||
|
||||
def _get_claims_for_name(self, name):
|
||||
return self._run_cmd_as_defer_to_thread('getclaimsforname', name)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ amount = 0
|
|||
|
||||
|
||||
def destroyNetwork(nodes):
|
||||
print 'Destroying Kademlia network...'
|
||||
print 'Destroying Kademlia network'
|
||||
i = 0
|
||||
for node in nodes:
|
||||
i += 1
|
||||
|
@ -50,12 +50,12 @@ def main():
|
|||
else:
|
||||
import socket
|
||||
ipAddress = socket.gethostbyname(socket.gethostname())
|
||||
print 'Network interface IP address omitted; using %s...' % ipAddress
|
||||
print 'Network interface IP address omitted; using %s' % ipAddress
|
||||
|
||||
startPort = 4000
|
||||
port = startPort+1
|
||||
nodes = []
|
||||
print 'Creating Kademlia network...'
|
||||
print 'Creating Kademlia network'
|
||||
try:
|
||||
node = os.spawnlp(
|
||||
os.P_NOWAIT, 'lbrynet-launch-node', 'lbrynet-launch-node', str(startPort))
|
||||
|
|
|
@ -16,10 +16,10 @@ def print_usage():
|
|||
def join_network(udp_port, known_nodes):
|
||||
lbryid = generate_id()
|
||||
|
||||
log.info('Creating Node...')
|
||||
log.info('Creating Node')
|
||||
node = Node(udpPort=udp_port, lbryid=lbryid)
|
||||
|
||||
log.info('Joining network...')
|
||||
log.info('Joining network')
|
||||
d = node.joinNetwork(known_nodes)
|
||||
|
||||
def log_network_size():
|
||||
|
|
|
@ -59,7 +59,7 @@ def storeValueCallback(*args, **kwargs):
|
|||
""" Callback function that is invoked when the storeValue() operation succeeds """
|
||||
print 'Value has been stored in the DHT'
|
||||
# Now that the value has been stored, schedule that the value is read again after 2.5 seconds
|
||||
print 'Scheduling retrieval in 2.5 seconds...'
|
||||
print 'Scheduling retrieval in 2.5 seconds'
|
||||
twisted.internet.reactor.callLater(2.5, getValue)
|
||||
|
||||
|
||||
|
@ -72,7 +72,7 @@ def getValue():
|
|||
""" Retrieves the value of the specified key (KEY) from the DHT """
|
||||
global node, KEY
|
||||
# Get the value for the specified key (immediately returns a Twisted deferred result)
|
||||
print ('\nRetrieving value from DHT for key "%s"...' %
|
||||
print ('\nRetrieving value from DHT for key "%s"' %
|
||||
binascii.unhexlify("f7d9dc4de674eaa2c5a022eb95bc0d33ec2e75c6"))
|
||||
deferredResult = node.iterativeFindValue(
|
||||
binascii.unhexlify("f7d9dc4de674eaa2c5a022eb95bc0d33ec2e75c6"))
|
||||
|
@ -91,13 +91,13 @@ def getValueCallback(result):
|
|||
print result
|
||||
|
||||
# Either way, schedule a "delete" operation for the key
|
||||
print 'Scheduling shutdown in 2.5 seconds...'
|
||||
print 'Scheduling shutdown in 2.5 seconds'
|
||||
twisted.internet.reactor.callLater(2.5, stop)
|
||||
|
||||
|
||||
def stop():
|
||||
""" Stops the Twisted reactor, and thus the script """
|
||||
print '\nStopping Kademlia node and terminating script...'
|
||||
print '\nStopping Kademlia node and terminating script'
|
||||
twisted.internet.reactor.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -145,7 +145,7 @@ if __name__ == '__main__':
|
|||
#
|
||||
# If you wish to have a pure Kademlia network, use the
|
||||
# entangled.kademlia.node.Node class instead
|
||||
print 'Creating Node...'
|
||||
print 'Creating Node'
|
||||
node = Node(udpPort=int(sys.argv[1]), lbryid=lbryid)
|
||||
|
||||
# Schedule the node to join the Kademlia/Entangled DHT
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,18 +1,93 @@
|
|||
import sys
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
from lbrynet import conf
|
||||
from lbrynet.lbrynet_daemon.auth.client import LBRYAPIClient
|
||||
from lbrynet.lbrynet_daemon.auth.client import JSONRPCException, LBRYAPIClient
|
||||
from lbrynet.lbrynet_daemon.Daemon import LOADING_WALLET_CODE
|
||||
from jsonrpc.common import RPCError
|
||||
from urllib2 import URLError, HTTPError
|
||||
from httplib import UNAUTHORIZED
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
_, arguments = parser.parse_known_args()
|
||||
|
||||
help_msg = "Usage: lbrynet-cli method kwargs\n" \
|
||||
+ "Examples: " \
|
||||
+ "lbrynet-cli resolve_name name=what\n" \
|
||||
+ "lbrynet-cli get_balance\n" \
|
||||
+ "lbrynet-cli help function=resolve_name\n" \
|
||||
+ "\n******lbrynet-cli functions******\n"
|
||||
conf.initialize_settings()
|
||||
conf.update_settings_from_file()
|
||||
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)
|
||||
return 1
|
||||
|
||||
if status['startup_status']['code'] != "started":
|
||||
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['blocks_behind'] > 0
|
||||
):
|
||||
message += '. Blocks left: ' + str(status['blocks_behind'])
|
||||
print " Status: " + message
|
||||
return 1
|
||||
|
||||
if len(arguments) < 1:
|
||||
print_help(api)
|
||||
return 1
|
||||
|
||||
method = arguments[0]
|
||||
try:
|
||||
params = parse_params(arguments[1:])
|
||||
except InvalidParameters as e:
|
||||
print_error(e.message)
|
||||
return 1
|
||||
|
||||
# TODO: check if port is bound. Error if its not
|
||||
|
||||
if method in ['--help', '-h', 'help']:
|
||||
if len(params) == 0:
|
||||
print_help(api)
|
||||
elif 'command' not in params:
|
||||
print_error(
|
||||
'To get help on a specific command, use `{} help command=COMMAND_NAME`'.format(
|
||||
os.path.basename(sys.argv[0]))
|
||||
)
|
||||
else:
|
||||
print api.call('help', params).strip()
|
||||
|
||||
elif method not in api.commands():
|
||||
print_error("'" + method + "' is not a valid command.")
|
||||
|
||||
else:
|
||||
try:
|
||||
result = api.call(method, params)
|
||||
if isinstance(result, basestring):
|
||||
# printing the undumped string is prettier
|
||||
print result
|
||||
else:
|
||||
print json.dumps(result, sort_keys=True, indent=2, separators=(',', ': '))
|
||||
except (RPCError, KeyError, JSONRPCException) as err:
|
||||
# TODO: The api should return proper error codes
|
||||
# and messages so that they can be passed along to the user
|
||||
# instead of this generic message.
|
||||
# https://app.asana.com/0/158602294500137/200173944358192
|
||||
print "Something went wrong, here's the usage for %s:" % method
|
||||
print api.call('help', {'command': method})
|
||||
if hasattr(err, 'msg'):
|
||||
print "Here's the traceback for the error you encountered:"
|
||||
print err.msg
|
||||
return 1
|
||||
|
||||
|
||||
def guess_type(x):
|
||||
|
@ -28,77 +103,89 @@ def guess_type(x):
|
|||
return x
|
||||
|
||||
|
||||
def parse_params(params):
|
||||
if len(params) > 1:
|
||||
return get_params_from_kwargs(params)
|
||||
elif len(params) == 1:
|
||||
try:
|
||||
return json.loads(params[0])
|
||||
except ValueError:
|
||||
return get_params_from_kwargs(params)
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
class InvalidParameters(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def get_params_from_kwargs(params):
|
||||
params_for_return = {}
|
||||
for i in params:
|
||||
eq_pos = i.index('=')
|
||||
k, v = i[:eq_pos], i[eq_pos+1:]
|
||||
try:
|
||||
eq_pos = i.index('=')
|
||||
except ValueError:
|
||||
raise InvalidParameters('{} is not in <key>=<value> format'.format(i))
|
||||
k, v = i[:eq_pos], i[eq_pos + 1:]
|
||||
params_for_return[k] = guess_type(v)
|
||||
return params_for_return
|
||||
|
||||
|
||||
def main():
|
||||
conf.initialize_settings()
|
||||
api = LBRYAPIClient.config()
|
||||
def print_help_suggestion():
|
||||
print "See `{} help` for more information.".format(os.path.basename(sys.argv[0]))
|
||||
|
||||
try:
|
||||
status = api.daemon_status()
|
||||
assert status.get('code', False) == "started"
|
||||
except Exception:
|
||||
|
||||
def print_error(message, suggest_help=True):
|
||||
print "ERROR: " + message
|
||||
if suggest_help:
|
||||
print_help_suggestion()
|
||||
|
||||
|
||||
def print_help(api):
|
||||
print "\n".join([
|
||||
"NAME",
|
||||
" lbrynet-cli - LBRY command line client.",
|
||||
"",
|
||||
"USAGE",
|
||||
" lbrynet-cli <command> [<args>]",
|
||||
"",
|
||||
"EXAMPLES",
|
||||
" lbrynet-cli commands # list available commands",
|
||||
" lbrynet-cli status # get daemon status",
|
||||
" lbrynet-cli resolve_name name=what # resolve a name",
|
||||
" lbrynet-cli help command=resolve_name # get help for a command",
|
||||
"",
|
||||
"COMMANDS",
|
||||
wrap_list_to_term_width(api.commands(), prefix=' ')
|
||||
])
|
||||
|
||||
|
||||
def wrap_list_to_term_width(l, width=None, separator=', ', prefix=''):
|
||||
if width is None:
|
||||
try:
|
||||
conf.settings.update({'use_auth_http': not conf.settings.use_auth_http})
|
||||
api = LBRYAPIClient.config()
|
||||
status = api.daemon_status()
|
||||
assert status.get('code', False) == "started"
|
||||
except Exception:
|
||||
print "lbrynet-daemon isn't running"
|
||||
sys.exit(1)
|
||||
_, width = os.popen('stty size', 'r').read().split()
|
||||
width = int(width)
|
||||
except:
|
||||
pass
|
||||
if not width:
|
||||
width = 80
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('method', nargs=1)
|
||||
parser.add_argument('params', nargs=argparse.REMAINDER, default=None)
|
||||
args = parser.parse_args()
|
||||
lines = []
|
||||
curr_line = ''
|
||||
for item in l:
|
||||
new_line = curr_line + item + separator
|
||||
if len(new_line) + len(prefix) > width:
|
||||
lines.append(curr_line)
|
||||
curr_line = item + separator
|
||||
else:
|
||||
curr_line = new_line
|
||||
lines.append(curr_line)
|
||||
|
||||
meth = args.method[0]
|
||||
params = {}
|
||||
|
||||
if len(args.params) > 1:
|
||||
params = get_params_from_kwargs(args.params)
|
||||
elif len(args.params) == 1:
|
||||
try:
|
||||
params = json.loads(args.params[0])
|
||||
except ValueError:
|
||||
params = get_params_from_kwargs(args.params)
|
||||
|
||||
msg = help_msg
|
||||
for f in api.help():
|
||||
msg += f + "\n"
|
||||
|
||||
if meth in ['--help', '-h', 'help']:
|
||||
print msg
|
||||
sys.exit(1)
|
||||
|
||||
if meth in api.help():
|
||||
try:
|
||||
if params:
|
||||
result = LBRYAPIClient.config(service=meth, params=params)
|
||||
else:
|
||||
result = LBRYAPIClient.config(service=meth, params=params)
|
||||
print json.dumps(result, sort_keys=True)
|
||||
except RPCError as err:
|
||||
# TODO: The api should return proper error codes
|
||||
# and messages so that they can be passed along to the user
|
||||
# instead of this generic message.
|
||||
# https://app.asana.com/0/158602294500137/200173944358192
|
||||
print "Something went wrong, here's the usage for %s:" % meth
|
||||
print api.help({'function': meth})
|
||||
print "Here's the traceback for the error you encountered:"
|
||||
print err.msg
|
||||
|
||||
else:
|
||||
print "Unknown function"
|
||||
print msg
|
||||
ret = prefix + ("\n" + prefix).join(lines)
|
||||
if ret.endswith(separator):
|
||||
ret = ret[:-len(separator)]
|
||||
return ret
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
sys.exit(main())
|
||||
|
|
|
@ -9,7 +9,7 @@ from jsonrpc.proxy import JSONRPCProxy
|
|||
from lbrynet import analytics
|
||||
from lbrynet import conf
|
||||
from lbrynet.core import utils
|
||||
from lbrynet.lbrynet_daemon.auth import client
|
||||
from lbrynet.lbrynet_daemon.auth.client import LBRYAPIClient
|
||||
from lbrynet.lbrynet_daemon.DaemonServer import DaemonServer
|
||||
|
||||
|
||||
|
@ -24,7 +24,7 @@ def stop():
|
|||
conf.initialize_settings()
|
||||
log_support.configure_console()
|
||||
try:
|
||||
client.LBRYAPIClient.config().stop()
|
||||
LBRYAPIClient.get_client().call('stop')
|
||||
except Exception:
|
||||
log.exception('Failed to stop deamon')
|
||||
else:
|
||||
|
|
|
@ -18,7 +18,7 @@ DOWNLOAD_RUNNING_CODE = 'running'
|
|||
# TODO: is this ever used?
|
||||
DOWNLOAD_STOPPED_CODE = 'stopped'
|
||||
STREAM_STAGES = [
|
||||
(INITIALIZING_CODE, 'Initializing...'),
|
||||
(INITIALIZING_CODE, 'Initializing'),
|
||||
(DOWNLOAD_METADATA_CODE, 'Downloading metadata'),
|
||||
(DOWNLOAD_RUNNING_CODE, 'Started stream'),
|
||||
(DOWNLOAD_STOPPED_CODE, 'Paused stream'),
|
||||
|
|
|
@ -23,8 +23,7 @@ class JSONRPCException(Exception):
|
|||
|
||||
|
||||
class AuthAPIClient(object):
|
||||
def __init__(self, key, timeout, connection, count, service, cookies, auth, url, login_url):
|
||||
self.__service_name = service
|
||||
def __init__(self, key, timeout, connection, count, cookies, auth, url, login_url):
|
||||
self.__api_key = key
|
||||
self.__service_url = login_url
|
||||
self.__id_count = count
|
||||
|
@ -35,30 +34,25 @@ class AuthAPIClient(object):
|
|||
|
||||
def __getattr__(self, name):
|
||||
if name.startswith('__') and name.endswith('__'):
|
||||
# Python internal stuff
|
||||
raise AttributeError
|
||||
if self.__service_name is not None:
|
||||
name = "%s.%s" % (self.__service_name, name)
|
||||
return AuthAPIClient(key=self.__api_key,
|
||||
timeout=HTTP_TIMEOUT,
|
||||
connection=self.__conn,
|
||||
count=self.__id_count,
|
||||
service=name,
|
||||
cookies=self.__cookies,
|
||||
auth=self.__auth_header,
|
||||
url=self.__url,
|
||||
login_url=self.__service_url)
|
||||
raise AttributeError # Python internal stuff
|
||||
|
||||
def __call__(self, *args):
|
||||
def f(*args):
|
||||
return self.call(name, args[0] if args else {})
|
||||
|
||||
return f
|
||||
|
||||
def call(self, method, params={}):
|
||||
self.__id_count += 1
|
||||
pre_auth_postdata = {'version': '1.1',
|
||||
'method': self.__service_name,
|
||||
'params': args,
|
||||
'id': self.__id_count}
|
||||
to_auth = get_auth_message(pre_auth_postdata)
|
||||
pre_auth_post_data = {
|
||||
'version': '1.1',
|
||||
'method': method,
|
||||
'params': [params],
|
||||
'id': self.__id_count
|
||||
}
|
||||
to_auth = get_auth_message(pre_auth_post_data)
|
||||
token = self.__api_key.get_hmac(to_auth)
|
||||
pre_auth_postdata.update({'hmac': token})
|
||||
postdata = json.dumps(pre_auth_postdata)
|
||||
pre_auth_post_data.update({'hmac': token})
|
||||
post_data = json.dumps(pre_auth_post_data)
|
||||
service_url = self.__service_url
|
||||
auth_header = self.__auth_header
|
||||
cookies = self.__cookies
|
||||
|
@ -66,11 +60,13 @@ class AuthAPIClient(object):
|
|||
|
||||
req = requests.Request(method='POST',
|
||||
url=service_url,
|
||||
data=postdata,
|
||||
headers={'Host': host,
|
||||
'User-Agent': USER_AGENT,
|
||||
'Authorization': auth_header,
|
||||
'Content-type': 'application/json'},
|
||||
data=post_data,
|
||||
headers={
|
||||
'Host': host,
|
||||
'User-Agent': USER_AGENT,
|
||||
'Authorization': auth_header,
|
||||
'Content-type': 'application/json'
|
||||
},
|
||||
cookies=cookies)
|
||||
r = req.prepare()
|
||||
http_response = self.__conn.send(r)
|
||||
|
@ -101,7 +97,6 @@ class AuthAPIClient(object):
|
|||
def config(cls, key_name=None, key=None, pw_path=None,
|
||||
timeout=HTTP_TIMEOUT,
|
||||
connection=None, count=0,
|
||||
service=None,
|
||||
cookies=None, auth=None,
|
||||
url=None, login_url=None):
|
||||
|
||||
|
@ -157,21 +152,11 @@ class AuthAPIClient(object):
|
|||
assert cookies.get(LBRY_SECRET, False), "Missing cookie"
|
||||
secret = cookies.get(LBRY_SECRET)
|
||||
api_key = APIKey(secret, api_key_name)
|
||||
return cls(api_key, timeout, conn, id_count, service, cookies,
|
||||
auth_header, url, service_url)
|
||||
return cls(api_key, timeout, conn, id_count, cookies, auth_header, url, service_url)
|
||||
|
||||
|
||||
class LBRYAPIClient(object):
|
||||
@staticmethod
|
||||
def config(service=None, params=None):
|
||||
if conf.settings.use_auth_http:
|
||||
if service is None:
|
||||
return AuthAPIClient.config()
|
||||
log.error("Try auth")
|
||||
if params is not None:
|
||||
return AuthAPIClient.config(service=service)(params)
|
||||
return AuthAPIClient.config(service=service)()
|
||||
url = conf.settings.API_CONNECTION_STRING
|
||||
if service is None:
|
||||
return JSONRPCProxy.from_url(url)
|
||||
return JSONRPCProxy.from_url(url).call(service, params)
|
||||
def get_client():
|
||||
return AuthAPIClient.config() if conf.settings.use_auth_http else \
|
||||
JSONRPCProxy.from_url(conf.settings.API_CONNECTION_STRING)
|
||||
|
|
|
@ -8,13 +8,15 @@ from twisted.internet import defer
|
|||
from twisted.python.failure import Failure
|
||||
|
||||
from txjsonrpc import jsonrpclib
|
||||
from lbrynet.core.Error import InvalidAuthenticationToken, InvalidHeaderError, SubhandlerError
|
||||
from lbrynet.core.Error import InvalidAuthenticationToken, InvalidHeaderError
|
||||
from lbrynet import conf
|
||||
from lbrynet.lbrynet_daemon.auth.util import APIKey, get_auth_message
|
||||
from lbrynet.lbrynet_daemon.auth.client import LBRY_SECRET
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
EMPTY_PARAMS = [{}]
|
||||
|
||||
|
||||
def default_decimal(obj):
|
||||
if isinstance(obj, Decimal):
|
||||
|
@ -34,7 +36,6 @@ class JSONRPCException(Exception):
|
|||
class AuthorizedBase(object):
|
||||
def __init__(self):
|
||||
self.authorized_functions = []
|
||||
self.subhandlers = []
|
||||
self.callable_methods = {}
|
||||
|
||||
for methodname in dir(self):
|
||||
|
@ -43,21 +44,12 @@ class AuthorizedBase(object):
|
|||
self.callable_methods.update({methodname.split("jsonrpc_")[1]: method})
|
||||
if hasattr(method, '_auth_required'):
|
||||
self.authorized_functions.append(methodname.split("jsonrpc_")[1])
|
||||
elif not methodname.startswith("__"):
|
||||
method = getattr(self, methodname)
|
||||
if hasattr(method, '_subhandler'):
|
||||
self.subhandlers.append(method)
|
||||
|
||||
@staticmethod
|
||||
def auth_required(f):
|
||||
f._auth_required = True
|
||||
return f
|
||||
|
||||
@staticmethod
|
||||
def subhandler(f):
|
||||
f._subhandler = True
|
||||
return f
|
||||
|
||||
|
||||
class AuthJSONRPCServer(AuthorizedBase):
|
||||
"""Authorized JSONRPC server used as the base class for the LBRY API
|
||||
|
@ -69,12 +61,6 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
@AuthJSONRPCServer.auth_required: this requires the client
|
||||
include a valid hmac authentication token in their request
|
||||
|
||||
@AuthJSONRPCServer.subhandler: include the tagged method in
|
||||
the processing of requests, to allow inheriting classes to
|
||||
modify request handling. Tagged methods will be passed the
|
||||
request object, and return True when finished to indicate
|
||||
success
|
||||
|
||||
Attributes:
|
||||
allowed_during_startup (list): list of api methods that are
|
||||
callable before the server has finished startup
|
||||
|
@ -84,8 +70,6 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
|
||||
authorized_functions (list): list of api methods that require authentication
|
||||
|
||||
subhandlers (list): list of subhandlers
|
||||
|
||||
callable_methods (dict): dictionary of api_callable_name: method values
|
||||
|
||||
"""
|
||||
|
@ -131,6 +115,7 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
if self._initialize_session(session_id):
|
||||
def expire_session():
|
||||
self._unregister_user_session(session_id)
|
||||
|
||||
session.startCheckingExpiration()
|
||||
session.notifyOnExpire(expire_session)
|
||||
message = "OK"
|
||||
|
@ -138,7 +123,8 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
self._set_headers(request, message, True)
|
||||
self._render_message(request, message)
|
||||
return server.NOT_DONE_YET
|
||||
session.touch()
|
||||
else:
|
||||
session.touch()
|
||||
|
||||
request.content.seek(0, 0)
|
||||
content = request.content.read()
|
||||
|
@ -155,12 +141,6 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
token = parsed.pop('hmac', None)
|
||||
version = self._get_jsonrpc_version(parsed.get('jsonrpc'), id_)
|
||||
|
||||
try:
|
||||
self._run_subhandlers(request)
|
||||
except SubhandlerError as err:
|
||||
self._render_error(err, request, id_, version)
|
||||
return server.NOT_DONE_YET
|
||||
|
||||
reply_with_next_secret = False
|
||||
if self._use_authentication:
|
||||
if function_name in self.authorized_functions:
|
||||
|
@ -182,7 +162,7 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
self._render_error(err, request, id_, version)
|
||||
return server.NOT_DONE_YET
|
||||
|
||||
if args == [{}]:
|
||||
if args == EMPTY_PARAMS:
|
||||
d = defer.maybeDeferred(function)
|
||||
else:
|
||||
d = defer.maybeDeferred(function, *args)
|
||||
|
@ -281,6 +261,7 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
return False
|
||||
|
||||
def _verify_token(self, session_id, message, token):
|
||||
assert token is not None, InvalidAuthenticationToken
|
||||
to_auth = get_auth_message(message)
|
||||
api_key = self.sessions.get(session_id)
|
||||
assert api_key.compare_hmac(to_auth, token), InvalidAuthenticationToken
|
||||
|
@ -297,18 +278,13 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
version_for_return = jsonrpclib.VERSION_PRE1
|
||||
return version_for_return
|
||||
|
||||
def _run_subhandlers(self, request):
|
||||
for handler in self.subhandlers:
|
||||
if not handler(request):
|
||||
raise SubhandlerError("Subhandler error processing request: %s", request)
|
||||
|
||||
def _callback_render(self, result, request, id_, version, auth_required=False):
|
||||
result_for_return = result if not isinstance(result, dict) else result['result']
|
||||
result_for_return = result
|
||||
|
||||
if version == jsonrpclib.VERSION_PRE1:
|
||||
if not isinstance(result, jsonrpclib.Fault):
|
||||
result_for_return = (result_for_return,)
|
||||
# Convert the result (python) to JSON-RPC
|
||||
|
||||
try:
|
||||
encoded_message = jsonrpclib.dumps(
|
||||
result_for_return, id=id_, version=version, default=default_decimal)
|
||||
|
@ -318,5 +294,5 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
log.exception("Failed to render API response: %s", result)
|
||||
self._render_error(err, request, id_, version)
|
||||
|
||||
def _render_response(self, result, code):
|
||||
return defer.succeed({'result': result, 'code': code})
|
||||
def _render_response(self, result):
|
||||
return defer.succeed(result)
|
||||
|
|
|
@ -34,7 +34,7 @@ class LBRYURIHandler(object):
|
|||
except:
|
||||
cmd = r'DIR = "$( cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )"' \
|
||||
r'if [-z "$(pgrep lbrynet-daemon)"]; then' \
|
||||
r'echo "running lbrynet-daemon..."' \
|
||||
r'echo "running lbrynet-daemon"' \
|
||||
r'$DIR / lbrynet - daemon &' \
|
||||
r'sleep 3 # let the daemon load before connecting' \
|
||||
r'fi'
|
||||
|
|
|
@ -27,7 +27,7 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
|||
|
||||
|
||||
if [ -z "$(pgrep lbrynet-daemon)" ]; then
|
||||
echo "running lbrynet-daemon..."
|
||||
echo "running lbrynet-daemon"
|
||||
$DIR/lbrynet-daemon --no-launch &
|
||||
sleep 3 # let the daemon load before connecting
|
||||
fi
|
||||
|
|
|
@ -11,7 +11,7 @@ from lbrynet import conf
|
|||
class LBRYURIHandler(object):
|
||||
def __init__(self):
|
||||
self.started_daemon = False
|
||||
self.daemon = LBRYAPIClient.config()
|
||||
self.daemon = LBRYAPIClient.get_client()
|
||||
|
||||
def handle_osx(self, lbry_name):
|
||||
self.check_daemon()
|
||||
|
@ -27,7 +27,7 @@ class LBRYURIHandler(object):
|
|||
if not self.started_daemon:
|
||||
cmd = r'DIR = "$( cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )"' \
|
||||
r'if [-z "$(pgrep lbrynet-daemon)"]; then' \
|
||||
r'echo "running lbrynet-daemon..."' \
|
||||
r'echo "running lbrynet-daemon"' \
|
||||
r'$DIR / lbrynet - daemon &' \
|
||||
r'sleep 3 # let the daemon load before connecting' \
|
||||
r'fi'
|
||||
|
@ -49,7 +49,8 @@ class LBRYURIHandler(object):
|
|||
|
||||
def check_daemon(self):
|
||||
try:
|
||||
self.started_daemon = self.daemon.is_running()
|
||||
status = self.daemon.call('status')
|
||||
self.started_daemon = status['is_running']
|
||||
except:
|
||||
self.started_daemon = False
|
||||
|
||||
|
|
|
@ -944,7 +944,7 @@ class TestTransfer(TestCase):
|
|||
self.assertEqual(hashsum.hexdigest(), "4ca2aafb4101c1e42235aad24fbb83be")
|
||||
|
||||
def delete_lbry_file():
|
||||
logging.debug("deleting the file...")
|
||||
logging.debug("deleting the file")
|
||||
d = self.lbry_file_manager.delete_lbry_file(downloaders[0])
|
||||
d.addCallback(lambda _: self.lbry_file_manager.get_count_for_stream_hash(downloaders[0].stream_hash))
|
||||
d.addCallback(
|
||||
|
|
Loading…
Reference in a new issue