forked from LBRYCommunity/lbry-sdk
Merge pull request #448 from lbryio/jsonrpc_params_in_function_signature
explicitly list jsonrpc params in function signature. add jsonrpc tests
This commit is contained in:
commit
b219806959
4 changed files with 192 additions and 204 deletions
|
@ -1031,7 +1031,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
)
|
||||
return run_reflector_factory(factory)
|
||||
|
||||
|
||||
############################################################################
|
||||
# #
|
||||
# JSON-RPC API methods start here #
|
||||
|
@ -1039,7 +1038,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
############################################################################
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def jsonrpc_status(self, p={}):
|
||||
def jsonrpc_status(self, session_status=False, blockchain_status=False):
|
||||
"""
|
||||
Return daemon status
|
||||
|
||||
|
@ -1068,17 +1067,17 @@ class Daemon(AuthJSONRPCServer):
|
|||
},
|
||||
'blocks_behind': (
|
||||
self.session.wallet.blocks_behind
|
||||
if has_wallet and self.wallet_type == LBRYUM_WALLET
|
||||
if has_wallet and self.wallet_type == LBRYUM_WALLET
|
||||
else 'unknown'
|
||||
),
|
||||
}
|
||||
if p.get('session_status', False):
|
||||
if session_status:
|
||||
blobs = yield self.session.blob_manager.get_all_verified_blobs()
|
||||
response['session_status'] = {
|
||||
'managed_blobs': len(blobs),
|
||||
'managed_streams': len(self.lbry_file_manager.lbry_files),
|
||||
}
|
||||
if p.get('blockchain_status', False) and has_wallet:
|
||||
if blockchain_status and has_wallet:
|
||||
# calculate blocks_behind more accurately
|
||||
local_height = self.session.wallet.network.get_local_height()
|
||||
remote_height = self.session.wallet.network.get_server_height()
|
||||
|
@ -1091,7 +1090,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
"""
|
||||
DEPRECATED. Use `status blockchain_status=True` instead
|
||||
"""
|
||||
d = self.jsonrpc_status({'blockchain_status': True})
|
||||
d = self.jsonrpc_status(blockchain_status=True)
|
||||
d.addCallback(lambda x: self._render_response(
|
||||
x['blockchain_status']['best_blockhash']))
|
||||
return d
|
||||
|
@ -1141,7 +1140,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
"""
|
||||
DEPRECATED. Use `status` instead
|
||||
"""
|
||||
d = self.jsonrpc_status({'blockchain_status': True})
|
||||
d = self.jsonrpc_status(blockchain_status=True)
|
||||
d.addCallback(lambda x: self._render_response(x['is_first_run']))
|
||||
return d
|
||||
|
||||
|
@ -1150,7 +1149,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
DEPRECATED. Use `status` instead
|
||||
"""
|
||||
|
||||
d = self.jsonrpc_status({'session_status': True})
|
||||
d = self.jsonrpc_status(session_status=True)
|
||||
d.addCallback(lambda x: self._render_response({
|
||||
'lbry_id': x['lbry_id'],
|
||||
'managed_blobs': x['session_status']['managed_blobs'],
|
||||
|
@ -1162,7 +1161,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
"""
|
||||
DEPRECATED. Use `status` instead
|
||||
"""
|
||||
d = self.jsonrpc_status({'blockchain_status': True}) # blockchain_status=True is needed
|
||||
d = self.jsonrpc_status(blockchain_status=True)
|
||||
d.addCallback(lambda x: self._render_response(x['blocks_behind']))
|
||||
return d
|
||||
|
||||
|
@ -1210,7 +1209,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
log.info("Get version info: " + json.dumps(msg))
|
||||
return self._render_response(msg)
|
||||
|
||||
def jsonrpc_report_bug(self, p):
|
||||
def jsonrpc_report_bug(self, message=None):
|
||||
"""
|
||||
Report a bug to slack
|
||||
|
||||
|
@ -1220,9 +1219,8 @@ class Daemon(AuthJSONRPCServer):
|
|||
True if successful
|
||||
"""
|
||||
|
||||
bug_message = p['message']
|
||||
platform_name = self._get_platform()['platform']
|
||||
report_bug_to_slack(bug_message, self.lbryid, platform_name, lbrynet_version)
|
||||
report_bug_to_slack(message, self.lbryid, platform_name, lbrynet_version)
|
||||
return self._render_response(True)
|
||||
|
||||
def jsonrpc_get_settings(self):
|
||||
|
@ -1233,10 +1231,8 @@ class Daemon(AuthJSONRPCServer):
|
|||
|
||||
def jsonrpc_settings_get(self):
|
||||
"""
|
||||
Get lbrynet daemon settings
|
||||
Get daemon settings
|
||||
|
||||
Args:
|
||||
None
|
||||
Returns:
|
||||
'run_on_startup': bool,
|
||||
'data_rate': float,
|
||||
|
@ -1259,16 +1255,16 @@ class Daemon(AuthJSONRPCServer):
|
|||
return self._render_response(conf.settings.get_current_settings_dict())
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_set_settings(self, p):
|
||||
def jsonrpc_set_settings(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `settings_set` instead.
|
||||
"""
|
||||
return self.jsonrpc_settings_set(p)
|
||||
return self.jsonrpc_settings_set(**kwargs)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_settings_set(self, p):
|
||||
def jsonrpc_settings_set(self, **kwargs):
|
||||
"""
|
||||
Set lbrynet daemon settings
|
||||
Set daemon settings
|
||||
|
||||
Args:
|
||||
'run_on_startup': bool,
|
||||
|
@ -1288,7 +1284,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
"Set daemon settings to %s",
|
||||
json.dumps(conf.settings.get_adjustable_settings_dict()))
|
||||
|
||||
d = self._update_settings(p)
|
||||
d = self._update_settings(kwargs)
|
||||
d.addErrback(lambda err: log.info(err.getTraceback()))
|
||||
d.addCallback(lambda _: _log_settings_change())
|
||||
d.addCallback(
|
||||
|
@ -1296,7 +1292,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
|
||||
return d
|
||||
|
||||
def jsonrpc_help(self, p=None):
|
||||
def jsonrpc_help(self, command=None):
|
||||
"""
|
||||
Return a useful message for an API command
|
||||
|
||||
|
@ -1307,16 +1303,17 @@ class Daemon(AuthJSONRPCServer):
|
|||
otherwise returns general help message
|
||||
"""
|
||||
|
||||
if p and 'command' in p:
|
||||
fn = self.callable_methods.get(p['command'])
|
||||
if fn is None:
|
||||
return self._render_response(
|
||||
"No help available for '" + p['command'] + "'. It is not a valid command."
|
||||
)
|
||||
return self._render_response(textwrap.dedent(fn.__doc__))
|
||||
else:
|
||||
if command is None:
|
||||
return self._render_response(textwrap.dedent(self.jsonrpc_help.__doc__))
|
||||
|
||||
fn = self.callable_methods.get(command)
|
||||
if fn is None:
|
||||
return self._render_response(
|
||||
"No help available for '{}'. It is not a valid command.".format(command)
|
||||
)
|
||||
return self._render_response(textwrap.dedent(fn.__doc__))
|
||||
|
||||
|
||||
def jsonrpc_commands(self):
|
||||
"""
|
||||
Return a list of available commands
|
||||
|
@ -1394,13 +1391,13 @@ class Daemon(AuthJSONRPCServer):
|
|||
|
||||
return d
|
||||
|
||||
def jsonrpc_get_lbry_file(self, p):
|
||||
def jsonrpc_get_lbry_file(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `file_get` instead.
|
||||
"""
|
||||
return self.jsonrpc_file_get(p)
|
||||
return self.jsonrpc_file_get(**kwargs)
|
||||
|
||||
def jsonrpc_file_get(self, p):
|
||||
def jsonrpc_file_get(self, **kwargs):
|
||||
"""
|
||||
Get a file
|
||||
|
||||
|
@ -1420,19 +1417,19 @@ class Daemon(AuthJSONRPCServer):
|
|||
'upload_allowed': bool
|
||||
'sd_hash': string
|
||||
"""
|
||||
d = self._get_deferred_for_lbry_file(p)
|
||||
d = self._get_deferred_for_lbry_file(kwargs)
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
return d
|
||||
|
||||
def _get_deferred_for_lbry_file(self, p):
|
||||
def _get_deferred_for_lbry_file(self, search_fields):
|
||||
try:
|
||||
searchtype, value = get_lbry_file_search_value(p)
|
||||
searchtype, value = get_lbry_file_search_value(search_fields)
|
||||
except NoValidSearch:
|
||||
return defer.fail()
|
||||
else:
|
||||
return self._get_lbry_file(searchtype, value)
|
||||
|
||||
def jsonrpc_resolve_name(self, p):
|
||||
def jsonrpc_resolve_name(self, name, force=False):
|
||||
"""
|
||||
Resolve stream info from a LBRY uri
|
||||
|
||||
|
@ -1442,9 +1439,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
metadata from name claim
|
||||
"""
|
||||
|
||||
force = p.get('force', False)
|
||||
|
||||
name = p.get(FileID.NAME)
|
||||
if not name:
|
||||
return self._render_response(None)
|
||||
|
||||
|
@ -1452,13 +1446,13 @@ class Daemon(AuthJSONRPCServer):
|
|||
d.addCallback(self._render_response)
|
||||
return d
|
||||
|
||||
def jsonrpc_get_claim_info(self, p):
|
||||
def jsonrpc_get_claim_info(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `claim_show` instead.
|
||||
"""
|
||||
return self.jsonrpc_claim_show(p)
|
||||
return self.jsonrpc_claim_show(**kwargs)
|
||||
|
||||
def jsonrpc_claim_show(self, p):
|
||||
def jsonrpc_claim_show(self, name, txid=None, nout=None):
|
||||
|
||||
"""
|
||||
Resolve claim info from a LBRY uri
|
||||
|
@ -1479,9 +1473,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
r['amount'] = float(r['amount']) / 10 ** 8
|
||||
return r
|
||||
|
||||
name = p[FileID.NAME]
|
||||
txid = p.get('txid', None)
|
||||
nout = p.get('nout', None)
|
||||
d = self.session.wallet.get_claim_info(name, txid, nout)
|
||||
d.addCallback(_convert_amount_to_float)
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
|
@ -1510,7 +1501,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
@defer.inlineCallbacks
|
||||
def jsonrpc_get(self, p):
|
||||
def jsonrpc_get(self, **kwargs):
|
||||
"""
|
||||
Download stream from a LBRY uri.
|
||||
|
||||
|
@ -1526,7 +1517,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
'stream_hash': hex string
|
||||
'path': path of download
|
||||
"""
|
||||
params = self._process_get_parameters(p)
|
||||
params = self._process_get_parameters(kwargs)
|
||||
if not params.name:
|
||||
# TODO: return a useful error message here, like "name argument is required"
|
||||
defer.returnValue(server.failure)
|
||||
|
@ -1587,24 +1578,22 @@ class Daemon(AuthJSONRPCServer):
|
|||
defer.returnValue(response)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_stop_lbry_file(self, p):
|
||||
def jsonrpc_stop_lbry_file(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `file_seed status=stop` instead.
|
||||
"""
|
||||
p['status'] = 'stop'
|
||||
return self.jsonrpc_file_seed(p)
|
||||
return self.jsonrpc_file_seed(status='stop', **kwargs)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_start_lbry_file(self, p):
|
||||
def jsonrpc_start_lbry_file(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `file_seed status=start` instead.
|
||||
"""
|
||||
p['status'] = 'start'
|
||||
return self.jsonrpc_file_seed(p)
|
||||
return self.jsonrpc_file_seed(status='start', **kwargs)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
@defer.inlineCallbacks
|
||||
def jsonrpc_file_seed(self, p):
|
||||
def jsonrpc_file_seed(self, status, **kwargs):
|
||||
"""
|
||||
Start or stop seeding a file
|
||||
|
||||
|
@ -1617,13 +1606,10 @@ class Daemon(AuthJSONRPCServer):
|
|||
confirmation message
|
||||
"""
|
||||
|
||||
status = p.get('status', None)
|
||||
if status is None:
|
||||
raise Exception('"status" option required')
|
||||
if status not in ['start', 'stop']:
|
||||
raise Exception('Status must be "start" or "stop".')
|
||||
|
||||
search_type, value = get_lbry_file_search_value(p)
|
||||
search_type, value = get_lbry_file_search_value(**kwargs)
|
||||
lbry_file = yield self._get_lbry_file(search_type, value, return_json=False)
|
||||
if not lbry_file:
|
||||
raise Exception('Unable to find a file for {}:{}'.format(search_type, value))
|
||||
|
@ -1646,7 +1632,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
return self.jsonrpc_file_delete(p)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_file_delete(self, p):
|
||||
def jsonrpc_file_delete(self, delete_target_file=True, **kwargs):
|
||||
"""
|
||||
Delete a lbry file
|
||||
|
||||
|
@ -1656,19 +1642,16 @@ class Daemon(AuthJSONRPCServer):
|
|||
confirmation message
|
||||
"""
|
||||
|
||||
# TODO: is this option used? if yes, document it. if no, remove it
|
||||
delete_file = p.get('delete_target_file', True)
|
||||
|
||||
def _delete_file(f):
|
||||
if not f:
|
||||
return False
|
||||
file_name = f.file_name
|
||||
d = self._delete_lbry_file(f, delete_file=delete_file)
|
||||
d = self._delete_lbry_file(f, delete_file=delete_target_file)
|
||||
d.addCallback(lambda _: "Deleted file: " + file_name)
|
||||
return d
|
||||
|
||||
try:
|
||||
searchtype, value = get_lbry_file_search_value(p)
|
||||
searchtype, value = get_lbry_file_search_value(kwargs)
|
||||
except NoValidSearch:
|
||||
d = defer.fail()
|
||||
else:
|
||||
|
@ -1678,13 +1661,13 @@ class Daemon(AuthJSONRPCServer):
|
|||
d.addCallback(lambda r: self._render_response(r))
|
||||
return d
|
||||
|
||||
def jsonrpc_get_est_cost(self, p):
|
||||
def jsonrpc_get_est_cost(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `stream_cost_estimate` instead
|
||||
"""
|
||||
return self.jsonrpc_stream_cost_estimate(p)
|
||||
return self.jsonrpc_stream_cost_estimate(**kwargs)
|
||||
|
||||
def jsonrpc_stream_cost_estimate(self, p):
|
||||
def jsonrpc_stream_cost_estimate(self, name, size=None):
|
||||
"""
|
||||
Get estimated cost for a lbry stream
|
||||
|
||||
|
@ -1695,15 +1678,12 @@ class Daemon(AuthJSONRPCServer):
|
|||
estimated cost
|
||||
"""
|
||||
|
||||
size = p.get('size', None)
|
||||
name = p.get(FileID.NAME, None)
|
||||
|
||||
d = self.get_est_cost(name, size)
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
return d
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_publish(self, p):
|
||||
def jsonrpc_publish(self, name, file_path, bid, metadata, fee=None):
|
||||
"""
|
||||
Make a new name claim and publish associated data to lbrynet
|
||||
|
||||
|
@ -1733,23 +1713,26 @@ class Daemon(AuthJSONRPCServer):
|
|||
d.addCallback(lambda _: claim_out)
|
||||
return d
|
||||
|
||||
name = p[FileID.NAME]
|
||||
log.info("Publish: %s", p)
|
||||
log.info("Publish: %s", {
|
||||
'name': name,
|
||||
'file_path': file_path,
|
||||
'bid': bid,
|
||||
'metadata': metadata,
|
||||
'fee': fee,
|
||||
})
|
||||
verify_name_characters(name)
|
||||
bid = p['bid']
|
||||
|
||||
if bid <= 0.0:
|
||||
return defer.fail(Exception("Invalid bid"))
|
||||
|
||||
try:
|
||||
metadata = Metadata(p['metadata'])
|
||||
metadata = Metadata(metadata)
|
||||
make_lbry_file = False
|
||||
sd_hash = metadata['sources']['lbry_sd_hash']
|
||||
log.info("Update publish for %s using existing stream", name)
|
||||
except ValidationError:
|
||||
make_lbry_file = True
|
||||
sd_hash = None
|
||||
metadata = p['metadata']
|
||||
file_path = p['file_path']
|
||||
if not file_path:
|
||||
raise Exception("No file given to publish")
|
||||
if not os.path.isfile(file_path):
|
||||
|
@ -1760,8 +1743,8 @@ class Daemon(AuthJSONRPCServer):
|
|||
d = self._resolve_name(name, force_refresh=True)
|
||||
d.addErrback(lambda _: None)
|
||||
|
||||
if 'fee' in p:
|
||||
metadata['fee'] = p['fee']
|
||||
if fee is not None:
|
||||
metadata['fee'] = fee
|
||||
assert len(metadata['fee']) == 1, "Too many fees"
|
||||
for c in metadata['fee']:
|
||||
if 'address' not in metadata['fee'][c]:
|
||||
|
@ -1783,14 +1766,14 @@ class Daemon(AuthJSONRPCServer):
|
|||
return d
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_abandon_claim(self, p):
|
||||
def jsonrpc_abandon_claim(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `claim_abandon` instead
|
||||
"""
|
||||
return self.jsonrpc_claim_abandon(p)
|
||||
return self.jsonrpc_claim_abandon(**kwargs)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_claim_abandon(self, p):
|
||||
def jsonrpc_claim_abandon(self, txid, nout):
|
||||
"""
|
||||
Abandon a name and reclaim credits from the claim
|
||||
|
||||
|
@ -1801,21 +1784,18 @@ class Daemon(AuthJSONRPCServer):
|
|||
txid : txid of resulting transaction if succesful
|
||||
fee : fee paid for the transaction if succesful
|
||||
"""
|
||||
if 'txid' not in p or 'nout' not in p:
|
||||
return server.failure
|
||||
|
||||
def _disp(x):
|
||||
log.info("Abandoned name claim tx " + str(x))
|
||||
return self._render_response(x)
|
||||
|
||||
d = defer.Deferred()
|
||||
d.addCallback(lambda _: self.session.wallet.abandon_claim(p['txid'], p['nout']))
|
||||
d.addCallback(lambda _: self.session.wallet.abandon_claim(txid, nout))
|
||||
d.addCallback(_disp)
|
||||
d.callback(None) # TODO: is this line necessary???
|
||||
return d
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_abandon_name(self, p):
|
||||
def jsonrpc_abandon_name(self, **kwargs):
|
||||
"""
|
||||
DEPRECIATED, use abandon_claim
|
||||
|
||||
|
@ -1825,17 +1805,17 @@ class Daemon(AuthJSONRPCServer):
|
|||
txid
|
||||
"""
|
||||
|
||||
return self.jsonrpc_abandon_claim(p)
|
||||
return self.jsonrpc_abandon_claim(**kwargs)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_support_claim(self, p):
|
||||
def jsonrpc_support_claim(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `claim_abandon` instead
|
||||
"""
|
||||
return self.jsonrpc_claim_new_support(p)
|
||||
return self.jsonrpc_claim_new_support(**kwargs)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_claim_new_support(self, p):
|
||||
def jsonrpc_claim_new_support(self, name, claim_id, amount):
|
||||
"""
|
||||
Support a name claim
|
||||
|
||||
|
@ -1849,16 +1829,13 @@ class Daemon(AuthJSONRPCServer):
|
|||
fee : fee paid for the transaction if succesful
|
||||
"""
|
||||
|
||||
name = p[FileID.NAME]
|
||||
claim_id = p['claim_id']
|
||||
amount = p['amount']
|
||||
d = self.session.wallet.support_claim(name, claim_id, amount)
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
return d
|
||||
|
||||
# TODO: merge this into claim_list
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_get_my_claim(self, p):
|
||||
def jsonrpc_get_my_claim(self, name):
|
||||
"""
|
||||
DEPRECATED. This method will be removed in a future release.
|
||||
|
||||
|
@ -1870,7 +1847,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
claim info, False if no such claim exists
|
||||
"""
|
||||
|
||||
d = self.session.wallet.get_my_claim(p[FileID.NAME])
|
||||
d = self.session.wallet.get_my_claim(name)
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
return d
|
||||
|
||||
|
@ -1905,19 +1882,19 @@ class Daemon(AuthJSONRPCServer):
|
|||
d.addCallback(lambda claims: self._render_response(claims))
|
||||
return d
|
||||
|
||||
def jsonrpc_get_claims_for_name(self, p):
|
||||
def jsonrpc_get_claims_for_name(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `claim_list` instead.
|
||||
"""
|
||||
return self.jsonrpc_claim_list(p)
|
||||
return self.jsonrpc_claim_list(**kwargs)
|
||||
|
||||
def jsonrpc_get_claims_for_tx(self, p):
|
||||
def jsonrpc_get_claims_for_tx(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `claim_list` instead.
|
||||
"""
|
||||
return self.jsonrpc_claim_list(p)
|
||||
return self.jsonrpc_claim_list(**kwargs)
|
||||
|
||||
def jsonrpc_claim_list(self, p):
|
||||
def jsonrpc_claim_list(self, name=None, txid=None):
|
||||
"""
|
||||
Get claims for a name
|
||||
|
||||
|
@ -1928,10 +1905,10 @@ class Daemon(AuthJSONRPCServer):
|
|||
list of name claims
|
||||
"""
|
||||
|
||||
if FileID.NAME in p:
|
||||
d = self.session.wallet.get_claims_for_name(p[FileID.NAME])
|
||||
elif 'txid' in p:
|
||||
d = self.session.wallet.get_claims_from_tx(p['txid'])
|
||||
if name is not None:
|
||||
d = self.session.wallet.get_claims_for_name(name)
|
||||
elif txid is not None:
|
||||
d = self.session.wallet.get_claims_from_tx(txid)
|
||||
else:
|
||||
return server.failure
|
||||
|
||||
|
@ -1960,13 +1937,13 @@ class Daemon(AuthJSONRPCServer):
|
|||
d.addCallback(lambda r: self._render_response(r))
|
||||
return d
|
||||
|
||||
def jsonrpc_get_transaction(self, p):
|
||||
def jsonrpc_get_transaction(self, txid):
|
||||
"""
|
||||
DEPRECATED. Use `transaction_show` instead
|
||||
"""
|
||||
return self.jsonrpc_transaction_show(p)
|
||||
return self.jsonrpc_transaction_show(txid)
|
||||
|
||||
def jsonrpc_transaction_show(self, p):
|
||||
def jsonrpc_transaction_show(self, txid):
|
||||
"""
|
||||
Get a decoded transaction from a txid
|
||||
|
||||
|
@ -1976,19 +1953,19 @@ class Daemon(AuthJSONRPCServer):
|
|||
JSON formatted transaction
|
||||
"""
|
||||
|
||||
d = self.session.wallet.get_transaction(p['txid'])
|
||||
d = self.session.wallet.get_transaction(txid)
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
return d
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_address_is_mine(self, p):
|
||||
def jsonrpc_address_is_mine(self, address):
|
||||
"""
|
||||
DEPRECATED. Use `wallet_is_address_mine` instead
|
||||
"""
|
||||
return self.jsonrpc_wallet_is_address_mine(p)
|
||||
return self.jsonrpc_wallet_is_address_mine(address)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_wallet_is_address_mine(self, p):
|
||||
def jsonrpc_wallet_is_address_mine(self, address):
|
||||
"""
|
||||
Checks if an address is associated with the current wallet.
|
||||
|
||||
|
@ -1998,19 +1975,19 @@ class Daemon(AuthJSONRPCServer):
|
|||
is_mine: bool
|
||||
"""
|
||||
|
||||
d = self.session.wallet.address_is_mine(p['address'])
|
||||
d = self.session.wallet.address_is_mine(address)
|
||||
d.addCallback(lambda is_mine: self._render_response(is_mine))
|
||||
return d
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_get_public_key_from_wallet(self, p):
|
||||
def jsonrpc_get_public_key_from_wallet(self, wallet):
|
||||
"""
|
||||
DEPRECATED. Use `wallet_is_address_mine` instead
|
||||
"""
|
||||
return self.jsonrpc_wallet_public_key(p)
|
||||
return self.jsonrpc_wallet_public_key(wallet)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_wallet_public_key(self, p):
|
||||
def jsonrpc_wallet_public_key(self, wallet):
|
||||
"""
|
||||
Get public key from wallet address
|
||||
|
||||
|
@ -2020,7 +1997,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
public key
|
||||
"""
|
||||
|
||||
d = self.session.wallet.get_pub_keys(p['wallet'])
|
||||
d = self.session.wallet.get_pub_keys(wallet)
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
|
@ -2051,7 +2028,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
return d
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_send_amount_to_address(self, p):
|
||||
def jsonrpc_send_amount_to_address(self, amount, address):
|
||||
"""
|
||||
Send credits to an address
|
||||
|
||||
|
@ -2062,13 +2039,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
True if payment successfully scheduled
|
||||
"""
|
||||
|
||||
if 'amount' in p and 'address' in p:
|
||||
amount = p['amount']
|
||||
address = p['address']
|
||||
else:
|
||||
# TODO: return a useful error message
|
||||
return server.failure
|
||||
|
||||
reserved_points = self.session.wallet.reserve_points(address, amount)
|
||||
if reserved_points is None:
|
||||
return defer.fail(InsufficientFundsError())
|
||||
|
@ -2076,13 +2046,13 @@ class Daemon(AuthJSONRPCServer):
|
|||
d.addCallback(lambda _: self._render_response(True))
|
||||
return d
|
||||
|
||||
def jsonrpc_get_block(self, p):
|
||||
def jsonrpc_get_block(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `block_show` instead
|
||||
"""
|
||||
return self.jsonrpc_block_show(p)
|
||||
return self.jsonrpc_block_show(**kwargs)
|
||||
|
||||
def jsonrpc_block_show(self, p):
|
||||
def jsonrpc_block_show(self, blockhash=None, height=None):
|
||||
"""
|
||||
Get contents of a block
|
||||
|
||||
|
@ -2092,36 +2062,38 @@ class Daemon(AuthJSONRPCServer):
|
|||
requested block
|
||||
"""
|
||||
|
||||
if 'blockhash' in p:
|
||||
d = self.session.wallet.get_block(p['blockhash'])
|
||||
elif 'height' in p:
|
||||
d = self.session.wallet.get_block_info(p['height'])
|
||||
d.addCallback(lambda blockhash: self.session.wallet.get_block(blockhash))
|
||||
if blockhash is not None:
|
||||
d = self.session.wallet.get_block(blockhash)
|
||||
elif height is not None:
|
||||
d = self.session.wallet.get_block_info(height)
|
||||
d.addCallback(lambda b: self.session.wallet.get_block(b))
|
||||
else:
|
||||
# TODO: return a useful error message
|
||||
return server.failure
|
||||
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
return d
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_download_descriptor(self, p):
|
||||
def jsonrpc_download_descriptor(self, **kwargs):
|
||||
"""
|
||||
DEPRECATED. Use `blob_get` instead
|
||||
"""
|
||||
return self.jsonrpc_blob_get(p)
|
||||
return self.jsonrpc_blob_get(**kwargs)
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_blob_get(self, p):
|
||||
def jsonrpc_blob_get(self, sd_hash, timeout=None):
|
||||
"""
|
||||
Download and return a sd blob
|
||||
|
||||
Args:
|
||||
sd_hash
|
||||
timeout (optional)
|
||||
Returns
|
||||
sd blob, dict
|
||||
"""
|
||||
sd_hash = p[FileID.SD_HASH]
|
||||
timeout = p.get('timeout', conf.settings['sd_download_timeout'])
|
||||
if timeout is None:
|
||||
timeout = conf.settings['sd_download_timeout']
|
||||
d = self._download_sd_blob(sd_hash, timeout)
|
||||
d.addCallbacks(
|
||||
lambda r: self._render_response(r),
|
||||
|
@ -2143,7 +2115,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
d.addCallback(lambda r: self._render_response(r))
|
||||
return d
|
||||
|
||||
def jsonrpc_log(self, p):
|
||||
def jsonrpc_log(self, message):
|
||||
"""
|
||||
DEPRECATED. This method will be removed in a future release.
|
||||
|
||||
|
@ -2155,10 +2127,11 @@ class Daemon(AuthJSONRPCServer):
|
|||
True
|
||||
"""
|
||||
|
||||
log.info("API client log request: %s" % p['message'])
|
||||
log.info("API client log request: %s" % message)
|
||||
return self._render_response(True)
|
||||
|
||||
def jsonrpc_upload_log(self, p=None):
|
||||
def jsonrpc_upload_log(self, name_prefix=None, log_type=None, exclude_previous=True,
|
||||
message=None, force=False):
|
||||
"""
|
||||
DEPRECATED. This method will be removed in a future release.
|
||||
|
||||
|
@ -2174,33 +2147,22 @@ class Daemon(AuthJSONRPCServer):
|
|||
|
||||
"""
|
||||
|
||||
exclude_previous = True
|
||||
force = False
|
||||
log_type = None
|
||||
|
||||
if p:
|
||||
if 'name_prefix' in p:
|
||||
log_type = p['name_prefix'] + '_api'
|
||||
elif 'log_type' in p:
|
||||
log_type = p['log_type'] + '_api'
|
||||
|
||||
if 'exclude_previous' in p:
|
||||
exclude_previous = p['exclude_previous']
|
||||
|
||||
if 'message' in p:
|
||||
log.info("Upload log message: " + str(p['message']))
|
||||
|
||||
if 'force' in p:
|
||||
force = p['force']
|
||||
if name_prefix is not None:
|
||||
log_type = name_prefix + '_api'
|
||||
elif log_type is not None:
|
||||
log_type += '_api'
|
||||
else:
|
||||
log_type = "api"
|
||||
log_type = 'api'
|
||||
|
||||
if message is not None:
|
||||
log.info("Upload log message: " + str(message))
|
||||
|
||||
d = self._upload_log(log_type=log_type, exclude_previous=exclude_previous, force=force)
|
||||
d.addCallback(lambda _: self._render_response(True))
|
||||
return d
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_configure_ui(self, p):
|
||||
def jsonrpc_configure_ui(self, branch=None, path=None, check_requirements=True):
|
||||
"""
|
||||
Configure the UI being hosted
|
||||
|
||||
|
@ -2209,25 +2171,21 @@ class Daemon(AuthJSONRPCServer):
|
|||
'path': path to a ui folder
|
||||
"""
|
||||
|
||||
if 'check_requirements' in p:
|
||||
check_require = p['check_requirements']
|
||||
else:
|
||||
check_require = True
|
||||
|
||||
if 'path' in p:
|
||||
if path is not None:
|
||||
d = self.lbry_ui_manager.setup(
|
||||
user_specified=p['path'], check_requirements=check_require)
|
||||
elif 'branch' in p:
|
||||
d = self.lbry_ui_manager.setup(branch=p['branch'], check_requirements=check_require)
|
||||
user_specified=path, check_requirements=check_requirements)
|
||||
elif branch is not None:
|
||||
d = self.lbry_ui_manager.setup(branch=branch, check_requirements=check_requirements)
|
||||
else:
|
||||
d = self.lbry_ui_manager.setup(check_requirements=check_require)
|
||||
d = self.lbry_ui_manager.setup(check_requirements=check_requirements)
|
||||
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
|
||||
return d
|
||||
|
||||
@AuthJSONRPCServer.auth_required
|
||||
@defer.inlineCallbacks
|
||||
def jsonrpc_open(self, p):
|
||||
def jsonrpc_open(self, sd_hash):
|
||||
"""
|
||||
Instruct the OS to open a file with its default program.
|
||||
|
||||
|
@ -2237,12 +2195,9 @@ class Daemon(AuthJSONRPCServer):
|
|||
True, opens file
|
||||
"""
|
||||
|
||||
if 'sd_hash' not in p:
|
||||
raise ValueError('sd_hash is required')
|
||||
|
||||
lbry_file = yield self._get_lbry_file(FileID.SD_HASH, p['sd_hash'])
|
||||
lbry_file = yield self._get_lbry_file(FileID.SD_HASH, sd_hash)
|
||||
if not lbry_file:
|
||||
raise Exception('Unable to find file for {}'.format(p['sd_hash']))
|
||||
raise Exception('Unable to find file for {}'.format(sd_hash))
|
||||
|
||||
try:
|
||||
file_utils.start(lbry_file['download_path'])
|
||||
|
@ -2252,7 +2207,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
|
||||
@defer.inlineCallbacks
|
||||
@AuthJSONRPCServer.auth_required
|
||||
def jsonrpc_reveal(self, p):
|
||||
def jsonrpc_reveal(self, sd_hash):
|
||||
"""
|
||||
Reveal a file or directory in file browser
|
||||
|
||||
|
@ -2262,12 +2217,9 @@ class Daemon(AuthJSONRPCServer):
|
|||
True, opens file browser
|
||||
"""
|
||||
|
||||
if 'sd_hash' not in p:
|
||||
raise ValueError('sd_hash is required')
|
||||
|
||||
lbry_file = yield self._get_lbry_file(FileID.SD_HASH, p['sd_hash'])
|
||||
lbry_file = yield self._get_lbry_file(FileID.SD_HASH, sd_hash)
|
||||
if not lbry_file:
|
||||
raise Exception('Unable to find file for {}'.format(p['sd_hash']))
|
||||
raise Exception('Unable to find file for {}'.format(sd_hash))
|
||||
|
||||
try:
|
||||
file_utils.reveal(lbry_file['download_path'])
|
||||
|
@ -2275,13 +2227,13 @@ class Daemon(AuthJSONRPCServer):
|
|||
pass
|
||||
defer.returnValue(True)
|
||||
|
||||
def jsonrpc_get_peers_for_hash(self, p):
|
||||
def jsonrpc_get_peers_for_hash(self, blob_hash):
|
||||
"""
|
||||
DEPRECATED. Use `peer_list` instead
|
||||
"""
|
||||
return self.jsonrpc_peer_list(p)
|
||||
return self.jsonrpc_peer_list(blob_hash)
|
||||
|
||||
def jsonrpc_peer_list(self, p):
|
||||
def jsonrpc_peer_list(self, blob_hash):
|
||||
"""
|
||||
Get peers for blob hash
|
||||
|
||||
|
@ -2291,8 +2243,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
List of contacts
|
||||
"""
|
||||
|
||||
blob_hash = p['blob_hash']
|
||||
|
||||
d = self.session.peer_finder.find_peers_for_blob(blob_hash)
|
||||
d.addCallback(lambda r: [[c.host, c.port, c.is_available()] for c in r])
|
||||
d.addCallback(lambda r: self._render_response(r))
|
||||
|
@ -2318,7 +2268,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
d.addCallback(lambda _: self._render_response("Announced"))
|
||||
return d
|
||||
|
||||
def jsonrpc_reflect(self, p):
|
||||
def jsonrpc_reflect(self, sd_hash):
|
||||
"""
|
||||
Reflect a stream
|
||||
|
||||
|
@ -2328,7 +2278,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
True or traceback
|
||||
"""
|
||||
|
||||
sd_hash = p[FileID.SD_HASH]
|
||||
d = self._get_lbry_file(FileID.SD_HASH, sd_hash, return_json=False)
|
||||
d.addCallback(self._reflect)
|
||||
d.addCallbacks(
|
||||
|
@ -2390,7 +2339,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
d = self._render_response(self.session.blob_tracker.last_mean_availability)
|
||||
return d
|
||||
|
||||
def jsonrpc_get_availability(self, p):
|
||||
def jsonrpc_get_availability(self, name):
|
||||
"""
|
||||
Get stream availability for a winning claim
|
||||
|
||||
|
@ -2411,7 +2360,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
else:
|
||||
return 0.0
|
||||
|
||||
d = self._resolve_name(p[FileID.NAME], force_refresh=True)
|
||||
d = self._resolve_name(name, force_refresh=True)
|
||||
d.addCallback(get_sd_hash)
|
||||
d.addCallback(self._download_sd_blob)
|
||||
d.addCallbacks(
|
||||
|
@ -2445,7 +2394,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
return d
|
||||
|
||||
|
||||
|
||||
def get_lbryum_version_from_github():
|
||||
return get_version_from_github('https://api.github.com/repos/lbryio/lbryum/releases/latest')
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
|
||||
Decorators:
|
||||
|
||||
@AuthJSONRPCServer.auth_required: this requires the client
|
||||
@AuthJSONRPCServer.auth_required: this requires that the client
|
||||
include a valid hmac authentication token in their request
|
||||
|
||||
Attributes:
|
||||
|
@ -195,10 +195,17 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
self._render_error(err, request, version)
|
||||
return server.NOT_DONE_YET
|
||||
|
||||
if args == EMPTY_PARAMS:
|
||||
if args == EMPTY_PARAMS or args == []:
|
||||
d = defer.maybeDeferred(function)
|
||||
elif isinstance(args, dict):
|
||||
d = defer.maybeDeferred(function, **args)
|
||||
elif len(args) == 1 and isinstance(args[0], dict):
|
||||
# TODO: this is for backwards compatibility. Remove this once API and UI are updated
|
||||
# TODO: also delete EMPTY_PARAMS then
|
||||
d = defer.maybeDeferred(function, **args[0])
|
||||
else:
|
||||
d = defer.maybeDeferred(function, *args)
|
||||
# d = defer.maybeDeferred(function, *args) # if we want to support positional args too
|
||||
raise ValueError('Args must be a dict')
|
||||
|
||||
# finished_deferred will callback when the request is finished
|
||||
# and errback if something went wrong. If the errback is
|
||||
|
|
|
@ -25,6 +25,18 @@ class Wallet(object):
|
|||
def __init__(self):
|
||||
self.private_key = RSA.generate(1024)
|
||||
self.encoded_public_key = self.private_key.publickey().exportKey()
|
||||
self._config = None
|
||||
self.network = None
|
||||
self.wallet = None
|
||||
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 = 0
|
||||
self.catchup_progress = 0
|
||||
self.max_behind = 0
|
||||
|
||||
def start(self):
|
||||
return defer.succeed(True)
|
||||
|
|
|
@ -3,9 +3,10 @@ import requests
|
|||
from tests.mocks import BlobAvailabilityTracker as DummyBlobAvailabilityTracker
|
||||
from tests import util
|
||||
from twisted.internet import defer
|
||||
from twisted.internet import reactor
|
||||
from twisted.trial import unittest
|
||||
from lbrynet.lbrynet_daemon import Daemon
|
||||
from lbrynet.core import Session, PaymentRateManager
|
||||
from lbrynet.core import Session, PaymentRateManager, Wallet
|
||||
from lbrynet.lbrynet_daemon.Daemon import Daemon as LBRYDaemon
|
||||
from lbrynet.lbrynet_daemon import ExchangeRateManager
|
||||
from lbrynet import conf
|
||||
|
@ -50,14 +51,15 @@ def get_test_daemon(data_rate=None, generous=True, with_fee=False):
|
|||
data_rate = conf.ADJUSTABLE_SETTINGS['data_rate'][1]
|
||||
|
||||
rates = {
|
||||
'BTCLBC': {'spot': 3.0, 'ts': util.DEFAULT_ISO_TIME + 1},
|
||||
'USDBTC': {'spot': 2.0, 'ts': util.DEFAULT_ISO_TIME + 2}
|
||||
}
|
||||
'BTCLBC': {'spot': 3.0, 'ts': util.DEFAULT_ISO_TIME + 1},
|
||||
'USDBTC': {'spot': 2.0, 'ts': util.DEFAULT_ISO_TIME + 2}
|
||||
}
|
||||
daemon = LBRYDaemon(None, None, upload_logs_on_shutdown=False)
|
||||
daemon.session = mock.Mock(spec=Session.Session)
|
||||
daemon.exchange_rate_manager = ExchangeRateManager.DummyExchangeRateManager(rates)
|
||||
base_prm = PaymentRateManager.BasePaymentRateManager(rate=data_rate)
|
||||
prm = PaymentRateManager.NegotiatedPaymentRateManager(base_prm, DummyBlobAvailabilityTracker(), generous=generous)
|
||||
prm = PaymentRateManager.NegotiatedPaymentRateManager(base_prm, DummyBlobAvailabilityTracker(),
|
||||
generous=generous)
|
||||
daemon.session.payment_rate_manager = prm
|
||||
metadata = {
|
||||
"author": "fake author",
|
||||
|
@ -74,7 +76,8 @@ def get_test_daemon(data_rate=None, generous=True, with_fee=False):
|
|||
"ver": "0.0.3"
|
||||
}
|
||||
if with_fee:
|
||||
metadata.update({"fee": {"USD": {"address": "bQ6BGboPV2SpTMEP7wLNiAcnsZiH8ye6eA", "amount": 0.75}}})
|
||||
metadata.update(
|
||||
{"fee": {"USD": {"address": "bQ6BGboPV2SpTMEP7wLNiAcnsZiH8ye6eA", "amount": 0.75}}})
|
||||
daemon._resolve_name = lambda _: defer.succeed(metadata)
|
||||
return daemon
|
||||
|
||||
|
@ -94,7 +97,7 @@ class TestCostEst(unittest.TestCase):
|
|||
size = 10000000
|
||||
fake_fee_amount = 4.5
|
||||
data_rate = conf.ADJUSTABLE_SETTINGS['data_rate'][1]
|
||||
correct_result = size / 10**6 * data_rate + fake_fee_amount
|
||||
correct_result = size / 10 ** 6 * data_rate + fake_fee_amount
|
||||
daemon = get_test_daemon(generous=False, with_fee=True)
|
||||
self.assertEquals(daemon.get_est_cost("test", size).result, correct_result)
|
||||
|
||||
|
@ -107,6 +110,24 @@ class TestCostEst(unittest.TestCase):
|
|||
def test_ungenerous_data_and_no_fee(self):
|
||||
size = 10000000
|
||||
data_rate = conf.ADJUSTABLE_SETTINGS['data_rate'][1]
|
||||
correct_result = size / 10**6 * data_rate
|
||||
correct_result = size / 10 ** 6 * data_rate
|
||||
daemon = get_test_daemon(generous=False)
|
||||
self.assertEquals(daemon.get_est_cost("test", size).result, correct_result)
|
||||
|
||||
|
||||
class TestJsonRpc(unittest.TestCase):
|
||||
def setUp(self):
|
||||
mock_conf_settings(self)
|
||||
util.resetTime(self)
|
||||
self.test_daemon = get_test_daemon()
|
||||
self.test_daemon.session.wallet = Wallet.LBRYumWallet(storage=Wallet.InMemoryStorage())
|
||||
# self.test_daemon.session.wallet = FakeWallet()
|
||||
|
||||
def test_status(self):
|
||||
d = defer.maybeDeferred(self.test_daemon.jsonrpc_status)
|
||||
d.addCallback(lambda status: self.assertDictContainsSubset({'is_running': False}, status))
|
||||
|
||||
def test_help(self):
|
||||
d = defer.maybeDeferred(self.test_daemon.jsonrpc_help, command='status')
|
||||
d.addCallback(lambda result: self.assertSubstring('daemon status', result))
|
||||
# self.assertSubstring('daemon status', d.result)
|
||||
|
|
Loading…
Reference in a new issue