Merge remote-tracking branch 'lbryio/master'

This commit is contained in:
Jack 2015-12-16 09:16:42 -05:00
commit 0a33324321
4 changed files with 157 additions and 42 deletions

View file

@ -1,6 +1,7 @@
from lbrynet.interfaces import IRequestCreator, IQueryHandlerFactory, IQueryHandler, ILBRYWallet from lbrynet.interfaces import IRequestCreator, IQueryHandlerFactory, IQueryHandler, ILBRYWallet
from lbrynet.core.client.ClientRequest import ClientRequest from lbrynet.core.client.ClientRequest import ClientRequest
from lbrynet.core.Error import UnknownNameError, InvalidStreamInfoError, RequestCanceledError from lbrynet.core.Error import UnknownNameError, InvalidStreamInfoError, RequestCanceledError
from lbrynet.core.Error import InsufficientFundsError
from lbrynet.core.sqlite_helpers import rerun_if_locked from lbrynet.core.sqlite_helpers import rerun_if_locked
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
from twisted.internet import threads, reactor, defer, task from twisted.internet import threads, reactor, defer, task
@ -498,12 +499,20 @@ class LBRYcrdWallet(object):
@_catch_connection_error @_catch_connection_error
def _claim_name(self, name, value, amount): def _claim_name(self, name, value, amount):
rpc_conn = self._get_rpc_conn() rpc_conn = self._get_rpc_conn()
return str(rpc_conn.claimname(name, value, amount)) try:
return str(rpc_conn.claimname(name, value, amount))
except JSONRPCException as e:
if 'message' in e.error and e.error['message'] == "Insufficient funds":
raise InsufficientFundsError()
elif 'message' in e.error:
raise ValueError(e.error['message'])
@_catch_connection_error @_catch_connection_error
def _get_status_of_claim(self, txhash, name, sd_hash): def _get_status_of_claim(self, txhash, name, sd_hash):
rpc_conn = self._get_rpc_conn() rpc_conn = self._get_rpc_conn()
claims = rpc_conn.getclaimsfortx(txhash) claims = rpc_conn.getclaimsfortx(txhash)
if claims is None:
claims = []
for claim in claims: for claim in claims:
if 'in claim trie' in claim: if 'in claim trie' in claim:
if 'name' in claim and str(claim['name']) == name and 'value' in claim: if 'name' in claim and str(claim['name']) == name and 'value' in claim:

View file

@ -29,7 +29,16 @@ class ConsoleControl(basic.LineReceiver):
def send_initial_prompt(self): def send_initial_prompt(self):
self.sendLine("") self.sendLine("")
self.sendLine("Welcome to lbrynet-console!") self.sendLine("In this early release of LBRY, some functions will not work\n"
"until you have downloaded a full copy of our blockchain. To\n"
"check whether you've caught up with the blockchain, use the\n"
"command 'get-blockchain-status'.\n\n"
"If, for example, you are unable to download some files or\n"
"your balance is showing 0 when you know it shouldn't be, it\n"
"is likely that the culprit is the blockchain.\n\n"
"You should have received 1000 LBC the first time you ran\n"
"this program. If you did not, let us know!\n\n"
"Welcome to lbrynet-console!")
self.sendLine("") self.sendLine("")
self.sendLine("Enter a command. Try 'get wonderfullife' or 'help' to see more options.") self.sendLine("Enter a command. Try 'get wonderfullife' or 'help' to see more options.")
self.show_prompt() self.show_prompt()

View file

@ -54,6 +54,49 @@ class InvalidValueError(Exception):
# prompt_description = None # prompt_description = None
class RoundedTime(object):
SECOND = 0
MINUTE = 1
HOUR = 2
DAY = 3
WEEK = 4
units = ['second', 'minute', 'hour', 'day', 'week']
def __init__(self, unit, val):
assert unit < len(self.units)
self.unit = unit
self.val = val
def __str__(self):
assert self.unit < len(self.units)
unit_str = self.units[self.unit]
if self.val != 1:
unit_str += "s"
return "%d %s" % (self.val, unit_str)
def get_time_behind_blockchain(best_block_time):
best_time = datetime.datetime.utcfromtimestamp(best_block_time)
diff = datetime.datetime.utcnow() - best_time
if diff.days > 0:
if diff.days >= 7:
val = diff.days // 7
unit = RoundedTime.WEEK
else:
val = diff.days
unit = RoundedTime.DAY
elif diff.seconds >= 60 * 60:
val = diff.seconds // (60 * 60)
unit = RoundedTime.HOUR
elif diff.seconds >= 60:
val = diff.seconds // 60
unit = RoundedTime.MINUTE
else:
val = diff.seconds
unit = RoundedTime.SECOND
return RoundedTime(unit, val)
class CommandHandlerFactory(object): class CommandHandlerFactory(object):
implements(ICommandHandlerFactory) implements(ICommandHandlerFactory)
priority = 0 priority = 0
@ -269,14 +312,30 @@ class GetWalletBalances(CommandHandler):
# assert line is None, "Show wallet balances should not be passed any arguments" # assert line is None, "Show wallet balances should not be passed any arguments"
# return True, self._get_wallet_balances() # return True, self._get_wallet_balances()
def _show_time_behind_blockchain(self, rounded_time):
if rounded_time.unit >= RoundedTime.HOUR:
self.console.sendLine("\n\nYour balance may be out of date. This application\n"
"is %s behind the LBC blockchain.\n\n" % str(rounded_time))
else:
self.console.sendLine("")
def _log_recent_blocktime_error(self, err):
log.error("An error occurred looking up the most recent blocktime: %s", err.getTraceback())
self.console.sendLine("")
def _get_wallet_balances(self): def _get_wallet_balances(self):
d = self.wallet.get_balance() d = self.wallet.get_balance()
def format_balance(balance): def format_balance(balance):
if balance == 0: if balance == 0:
balance = 0 balance = 0
balance_string = "balance: " + str(balance) + " LBC\n" balance_string = "balance: " + str(balance) + " LBC"
self.console.sendLine(balance_string) self.console.sendLine(balance_string)
d = self.wallet.get_most_recent_blocktime()
d.addCallback(get_time_behind_blockchain)
d.addCallback(self._show_time_behind_blockchain)
d.addErrback(self._log_recent_blocktime_error)
return d
d.addCallback(format_balance) d.addCallback(format_balance)
return d return d
@ -398,9 +457,10 @@ class AddStream(CommandHandler):
cancel_prompt = "Trying to locate the stream's metadata. Type \"cancel\" to cancel..." cancel_prompt = "Trying to locate the stream's metadata. Type \"cancel\" to cancel..."
canceled_message = "Canceled downloading." canceled_message = "Canceled downloading."
def __init__(self, console, sd_identifier, base_payment_rate_manager): def __init__(self, console, sd_identifier, base_payment_rate_manager, wallet):
CommandHandler.__init__(self, console) CommandHandler.__init__(self, console)
self.sd_identifier = sd_identifier self.sd_identifier = sd_identifier
self.wallet = wallet
self.loading_metadata_deferred = None self.loading_metadata_deferred = None
self.metadata = None self.metadata = None
self.factory = None self.factory = None
@ -659,6 +719,10 @@ class AddStream(CommandHandler):
def _handle_download_error(self, err): def _handle_download_error(self, err):
if err.check(InsufficientFundsError): if err.check(InsufficientFundsError):
self.console.sendLine("Download stopped due to insufficient funds.") self.console.sendLine("Download stopped due to insufficient funds.")
d = self.wallet.get_most_recent_blocktime()
d.addCallback(get_time_behind_blockchain)
d.addCallback(self._show_time_behind_blockchain_download)
d.addErrback(self._log_recent_blockchain_time_error_download)
else: else:
log.error("An unexpected error has caused the download to stop: %s" % err.getTraceback()) log.error("An unexpected error has caused the download to stop: %s" % err.getTraceback())
self.console.sendLine("An unexpected error has caused the download to stop. See console.log for details.") self.console.sendLine("An unexpected error has caused the download to stop. See console.log for details.")
@ -667,6 +731,15 @@ class AddStream(CommandHandler):
return self.factory.make_downloader(self.metadata, self.options_chosen, return self.factory.make_downloader(self.metadata, self.options_chosen,
self.payment_rate_manager) self.payment_rate_manager)
def _show_time_behind_blockchain_download(self, rounded_time):
if rounded_time.unit >= RoundedTime.HOUR:
self.console.sendLine("\nThis application is %s behind the LBC blockchain, so some of your\n"
"funds may not be available. Use 'get-blockchain-status' to check if\n"
"your application is up to date with the blockchain." % str(rounded_time))
def _log_recent_blockchain_time_error_download(self, err):
log.error("An error occurred trying to look up the most recent blocktime: %s", err.getTraceback())
class AddStreamFromSD(AddStream): class AddStreamFromSD(AddStream):
#prompt_description = "Add a stream from a stream descriptor file" #prompt_description = "Add a stream from a stream descriptor file"
@ -690,8 +763,8 @@ class AddStreamFromHash(AddStream):
#prompt_description = "Add a stream from a hash" #prompt_description = "Add a stream from a hash"
#line_prompt = "Stream descriptor hash:" #line_prompt = "Stream descriptor hash:"
def __init__(self, console, sd_identifier, session): def __init__(self, console, sd_identifier, session, wallet):
AddStream.__init__(self, console, sd_identifier, session.base_payment_rate_manager) AddStream.__init__(self, console, sd_identifier, session.base_payment_rate_manager, wallet)
self.session = session self.session = session
def start(self, sd_hash): def start(self, sd_hash):
@ -708,8 +781,13 @@ class AddStreamFromHash(AddStream):
self.finished_deferred.callback(None) self.finished_deferred.callback(None)
return return
if err.check(InsufficientFundsError): if err.check(InsufficientFundsError):
self.console.sendLine("Insufficient funds to download the metadata blob.\n\n") self.console.sendLine("Insufficient funds to download the metadata blob.")
self.finished_deferred.callback(None) d = self.wallet.get_most_recent_blocktime()
d.addCallback(get_time_behind_blockchain)
d.addCallback(self._show_time_behind_blockchain_download)
d.addErrback(self._log_recent_blockchain_time_error_download)
d.addCallback(lambda _: self.console.sendLine("\n"))
d.chainDeferred(self.finished_deferred)
return return
return AddStream._handle_load_failed(self, err) return AddStream._handle_load_failed(self, err)
@ -729,7 +807,7 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash):
#line_prompt = "Short name:" #line_prompt = "Short name:"
def __init__(self, console, sd_identifier, session, wallet): def __init__(self, console, sd_identifier, session, wallet):
AddStreamFromHash.__init__(self, console, sd_identifier, session) AddStreamFromHash.__init__(self, console, sd_identifier, session, wallet)
self.wallet = wallet self.wallet = wallet
self.resolved_name = None self.resolved_name = None
self.description = None self.description = None
@ -759,10 +837,25 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash):
self.key_fee = None self.key_fee = None
self.key_fee_address = stream_info.get('key_fee_address', None) self.key_fee_address = stream_info.get('key_fee_address', None)
return stream_info['stream_hash'] return stream_info['stream_hash']
d = self.wallet.get_stream_info_for_name(name) d = self.wallet.get_most_recent_blocktime()
d.addCallback(get_time_behind_blockchain)
d.addCallback(self._show_time_behind_blockchain_resolve)
d.addErrback(self._log_recent_blockchain_time_error_resolve)
d.addCallback(lambda _: self.wallet.get_stream_info_for_name(name))
d.addCallback(get_name_from_info) d.addCallback(get_name_from_info)
return d return d
def _show_time_behind_blockchain_resolve(self, rounded_time):
if rounded_time.unit >= RoundedTime.HOUR:
self.console.sendLine("\nThis application is %s behind the LBC blockchain, which may be\n"
"preventing this name from being resolved correctly. Use 'get-blockchain-status'\n"
"to check if your application is up to date with the blockchain.\n\n" % str(rounded_time))
else:
self.console.sendLine("\n")
def _log_recent_blockchain_time_error_resolve(self, err):
log.error("An error occurred trying to look up the most recent blocktime: %s", err.getTraceback())
def _handle_load_failed(self, err): def _handle_load_failed(self, err):
self.loading_failed = True self.loading_failed = True
if err.check(UnknownNameError): if err.check(UnknownNameError):
@ -772,8 +865,8 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash):
AddStreamFromHash.start(self, self.name) AddStreamFromHash.start(self, self.name)
return return
else: else:
self.console.sendLine("The name %s could not be found.\n\n" % err.getErrorMessage()) self.console.sendLine("The name %s could not be found." % err.getErrorMessage())
self.finished_deferred.callback(None) self.finished_deferred.callback(True)
return return
elif err.check(InvalidBlobHashError): elif err.check(InvalidBlobHashError):
self.console.sendLine("The metadata for this name is invalid. The stream cannot be downloaded.\n\n") self.console.sendLine("The metadata for this name is invalid. The stream cannot be downloaded.\n\n")
@ -1706,9 +1799,29 @@ class Publish(CommandHandler):
message = "Finished publishing %s to %s. The txid of the LBRYcrd claim is %s." message = "Finished publishing %s to %s. The txid of the LBRYcrd claim is %s."
self.console.sendLine(message % (str(self.file_name), str(self.publish_name), str(self.tx_hash))) self.console.sendLine(message % (str(self.file_name), str(self.publish_name), str(self.tx_hash)))
def _show_time_behind_blockchain(self, rounded_time):
if rounded_time.unit >= RoundedTime.HOUR:
self.console.sendLine("This application is %s behind the LBC blockchain\n"
"and therefore may not have all of the funds you expect\n"
"available at this time." % str(rounded_time))
def _log_best_blocktime_error(self, err):
log.error("An error occurred checking the best time of the blockchain: %s", err.getTraceback())
def _show_publish_error(self, err): def _show_publish_error(self, err):
message = "An error occurred publishing %s to %s. Error: %s." message = "An error occurred publishing %s to %s. Error: %s."
self.console.sendLine(message % (str(self.file_name), str(self.publish_name), err.getErrorMessage())) if err.check(InsufficientFundsError):
d = self.wallet.get_most_recent_blocktime()
d.addCallback(get_time_behind_blockchain)
d.addCallback(self._show_time_behind_blockchain)
d.addErrback(self._log_best_blocktime_error)
error_message = "Insufficient funds"
else:
d = defer.succeed(True)
error_message = err.getErrorMessage()
self.console.sendLine(message % (str(self.file_name), str(self.publish_name), error_message))
log.error(message, str(self.file_name), str(self.publish_name), err.getTraceback())
return d
def _do_publish(self): def _do_publish(self):
d = create_lbry_file(self.session, self.lbry_file_manager, self.file_name, open(self.file_path)) d = create_lbry_file(self.session, self.lbry_file_manager, self.file_name, open(self.file_path))
@ -1722,7 +1835,7 @@ class Publish(CommandHandler):
class PublishFactory(CommandHandlerFactory): class PublishFactory(CommandHandlerFactory):
control_handler_class = Publish control_handler_class = Publish
priority = 90 priority = 90
command = 'publish' command = "publish"
short_help = "Publish a file to lbrynet" short_help = "Publish a file to lbrynet"
full_help = "Publish a file to lbrynet.\n\n" \ full_help = "Publish a file to lbrynet.\n\n" \
"Usage: publish [file_name]\n\n" \ "Usage: publish [file_name]\n\n" \
@ -2417,35 +2530,19 @@ class BlockchainStatus(CommandHandler):
def start(self): def start(self):
d = self.wallet.get_most_recent_blocktime() d = self.wallet.get_most_recent_blocktime()
d.addCallback(get_time_behind_blockchain)
d.addCallbacks(self._show_time_behind_blockchain, self._show_error) d.addCallbacks(self._show_time_behind_blockchain, self._show_error)
d.chainDeferred(self.finished_deferred) d.chainDeferred(self.finished_deferred)
return d return d
def _show_time_behind_blockchain(self, best_block_time): def _show_time_behind_blockchain(self, rounded_time):
best_time = datetime.datetime.utcfromtimestamp(best_block_time) if rounded_time.unit >= RoundedTime.HOUR:
diff = datetime.datetime.utcnow() - best_time self.console.sendLine("This application is %s behind the LBC blockchain." % str(rounded_time))
unit = None
val = None
if diff.days > 0:
if diff.days >= 7:
val = diff.days // 7
unit = "week"
else:
val = diff.days
unit = "day"
elif diff.seconds >= 60 * 90:
if diff.seconds >= 60 * 60:
val = diff.seconds // (60 * 60)
unit = "hour"
if unit is not None:
if val != 1:
unit += "s"
self.console.sendLine("This application is %d %s behind the LBC blockchain." % (val, unit))
else: else:
self.console.sendLine("This application is up to date with the LBC blockchain.") self.console.sendLine("This application is up to date with the LBC blockchain.")
def _show_error(self, err): def _show_error(self, err):
logging.error(err.getTraceback()) log.error(err.getTraceback())
self.console.sendLine("Unable to determine the status of the blockchain.") self.console.sendLine("Unable to determine the status of the blockchain.")

View file

@ -320,11 +320,10 @@ class LBRYConsole():
if credits_received != 0.0: if credits_received != 0.0:
points_string = locale.format_string("%.2f LBC", (round(credits_received, 2),), points_string = locale.format_string("%.2f LBC", (round(credits_received, 2),),
grouping=True) grouping=True)
alert.info("Thank you for using LBRY! You have been given %s for free because we " alert.info("\n\nThank you for testing the alpha version of LBRY!\n\n"
"love you. Please give them a few minutes to show up while you catch up " "You have been given %s for free because we love you.\n"
"with our blockchain.\nTo check whether you've caught up with the blockchain, " "Please give them a few minutes to show up while you\n"
"use the command 'get-blockchain-status'.\nDownloading some files " "catch up with our blockchain.\n", points_string)
"may not work until you have downloaded the LBC blockchain.", points_string)
def _setup_lbry_file_manager(self): def _setup_lbry_file_manager(self):
self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir) self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir)
@ -354,7 +353,8 @@ class LBRYConsole():
ShutDownFactory(self), ShutDownFactory(self),
PeerStatsAndSettingsChooserFactory(self.session.peer_manager), PeerStatsAndSettingsChooserFactory(self.session.peer_manager),
LBRYFileStatusFactory(self.lbry_file_manager), LBRYFileStatusFactory(self.lbry_file_manager),
AddStreamFromSDFactory(self.sd_identifier, self.session.base_payment_rate_manager), AddStreamFromSDFactory(self.sd_identifier, self.session.base_payment_rate_manager,
self.session.wallet),
DeleteLBRYFileChooserFactory(self.lbry_file_metadata_manager, self.session.blob_manager, DeleteLBRYFileChooserFactory(self.lbry_file_metadata_manager, self.session.blob_manager,
self.lbry_file_manager), self.lbry_file_manager),
ToggleLBRYFileRunningChooserFactory(self.lbry_file_manager), ToggleLBRYFileRunningChooserFactory(self.lbry_file_manager),
@ -366,7 +366,7 @@ class LBRYConsole():
CreatePlainStreamDescriptorChooserFactory(self.lbry_file_manager), CreatePlainStreamDescriptorChooserFactory(self.lbry_file_manager),
ShowLBRYFileStreamHashChooserFactory(self.lbry_file_manager), ShowLBRYFileStreamHashChooserFactory(self.lbry_file_manager),
ModifyLBRYFileOptionsChooserFactory(self.lbry_file_manager), ModifyLBRYFileOptionsChooserFactory(self.lbry_file_manager),
AddStreamFromHashFactory(self.sd_identifier, self.session), AddStreamFromHashFactory(self.sd_identifier, self.session, self.session.wallet),
StatusFactory(self, self.session.rate_limiter, self.lbry_file_manager, StatusFactory(self, self.session.rate_limiter, self.lbry_file_manager,
self.session.blob_manager, self.session.wallet if self.wallet_type == 'lbrycrd' else None), self.session.blob_manager, self.session.wallet if self.wallet_type == 'lbrycrd' else None),
# AutoFetcherStartFactory(self.autofetcher), # AutoFetcherStartFactory(self.autofetcher),