diff --git a/lbrynet/core/LBRYcrdWallet.py b/lbrynet/core/LBRYcrdWallet.py index 510d949f2..ef4f70d00 100644 --- a/lbrynet/core/LBRYcrdWallet.py +++ b/lbrynet/core/LBRYcrdWallet.py @@ -312,7 +312,7 @@ class LBRYcrdWallet(object): def get_name_and_validity_for_sd_hash(self, sd_hash): d = self._get_claim_metadata_for_sd_hash(sd_hash) - d.addCallback(lambda name_txid: self._get_status_of_claim(name_txid[1], name_txid[0], sd_hash) if name_txid is not None else None) + d.addCallback(lambda name_txid: threads.deferToThread(self._get_status_of_claim, name_txid[1], name_txid[0], sd_hash) if name_txid is not None else None) return d def get_available_balance(self): @@ -321,6 +321,15 @@ class LBRYcrdWallet(object): def get_new_address(self): return threads.deferToThread(self._get_new_address) + def check_first_run(self): + d = threads.deferToThread(self._get_wallet_balance) + d.addCallback(lambda bal: threads.deferToThread(self._get_num_addresses) if bal == 0 else 2) + d.addCallback(lambda num_addresses: True if num_addresses <= 1 else False) + return d + + def get_most_recent_blocktime(self): + return threads.deferToThread(self._get_best_block_time) + def get_rpc_conf(self): settings = {"username": "rpcuser", "password": "rpcpassword", @@ -378,7 +387,7 @@ class LBRYcrdWallet(object): except (socket.error, JSONRPCException): tries += 1 log.warning("Failed to connect to lbrycrdd.") - if tries < 5: + if tries < 6: time.sleep(2 ** tries) log.warning("Trying again in %d seconds", 2 ** tries) else: @@ -512,6 +521,20 @@ class LBRYcrdWallet(object): return name, "unconfirmed" return None + @_catch_connection_error + def _get_num_addresses(self): + rpc_conn = self._get_rpc_conn() + return len(rpc_conn.getaddressesbyaccount("")) + + @_catch_connection_error + def _get_best_block_time(self): + rpc_conn = self._get_rpc_conn() + best_block_hash = rpc_conn.getbestblockhash() + block = rpc_conn.getblock(best_block_hash) + if 'time' in block: + return block['time'] + raise ValueError("Could not get a block time") + @_catch_connection_error def _rpc_stop(self): diff --git a/lbrynet/core/Session.py b/lbrynet/core/Session.py index 21fd4c979..cc31c08ff 100644 --- a/lbrynet/core/Session.py +++ b/lbrynet/core/Session.py @@ -148,7 +148,8 @@ class LBRYSession(object): ds.append(defer.maybeDeferred(self.wallet.stop)) if self.blob_manager is not None: ds.append(defer.maybeDeferred(self.blob_manager.stop)) - ds.append(defer.maybeDeferred(self._unset_upnp)) + if self.use_upnp is True: + ds.append(defer.maybeDeferred(self._unset_upnp)) return defer.DeferredList(ds) def _try_upnp(self): diff --git a/lbrynet/lbrynet_console/ConsoleControl.py b/lbrynet/lbrynet_console/ConsoleControl.py index a69b73350..4d49fd6d4 100644 --- a/lbrynet/lbrynet_console/ConsoleControl.py +++ b/lbrynet/lbrynet_console/ConsoleControl.py @@ -12,6 +12,8 @@ class ConsoleControl(basic.LineReceiver): def __init__(self): self.connected = False self.buffer = [] + self.command_handlers = {} + self.current_handler = None def start(self, command_handlers): self.command_handlers = {h.command: h for h in command_handlers} @@ -83,6 +85,8 @@ class ConsoleControl(basic.LineReceiver): self.show_prompt() def lineReceived(self, line): + if not self.command_handlers: + return if self.current_handler is None: words = line.split() if len(words) == 0: diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py index 4913414dd..4a5954f9d 100644 --- a/lbrynet/lbrynet_console/ControlHandlers.py +++ b/lbrynet/lbrynet_console/ControlHandlers.py @@ -842,7 +842,7 @@ class LBRYFileChooser(RecursiveCommandHandler): def _get_control_handler_factories(self): control_handler_factories = [] for lbry_file in self.lbry_file_manager.lbry_files: - control_handler_factories.append(self.factory_class(lbry_file, *self.args)) + control_handler_factories.append(self.factory_class(self.console, lbry_file, *self.args)) return control_handler_factories @@ -2454,4 +2454,3 @@ class BlockchainStatusFactory(CommandHandlerFactory): command = "get-blockchain-status" short_help = "Show whether this application has caught up with the LBC blockchain" full_help = "Show whether this applications has caught up with the LBC blockchain" - diff --git a/lbrynet/lbrynet_console/LBRYConsole.py b/lbrynet/lbrynet_console/LBRYConsole.py index 069948165..226716b6e 100644 --- a/lbrynet/lbrynet_console/LBRYConsole.py +++ b/lbrynet/lbrynet_console/LBRYConsole.py @@ -2,6 +2,8 @@ import logging from lbrynet.core.Session import LBRYSession import os.path import argparse +import requests +import locale from yapsy.PluginManager import PluginManager from twisted.internet import defer, threads, stdio, task, error @@ -37,6 +39,7 @@ from lbrynet.lbrynet_console.ControlHandlers import ClaimNameFactory, GetNewWall from lbrynet.lbrynet_console.ControlHandlers import ShowServerStatusFactory, ModifyServerSettingsFactory from lbrynet.lbrynet_console.ControlHandlers import ModifyLBRYFileOptionsChooserFactory, StatusFactory from lbrynet.lbrynet_console.ControlHandlers import PeerStatsAndSettingsChooserFactory, PublishFactory +from lbrynet.lbrynet_console.ControlHandlers import BlockchainStatusFactory from lbrynet.core.LBRYcrdWallet import LBRYcrdWallet @@ -245,7 +248,8 @@ class LBRYConsole(): if not lbrycrdd_path: lbrycrdd_path = self.default_lbrycrdd_path d = defer.succeed(LBRYcrdWallet(self.db_dir, wallet_dir=self.lbrycrd_dir, - wallet_conf=self.lbrycrd_conf, lbrycrdd_path=lbrycrdd_path)) + wallet_conf=self.lbrycrd_conf, + lbrycrdd_path=lbrycrdd_path)) else: d = defer.succeed(PTCWallet(self.db_dir)) d.addCallback(lambda wallet: {"wallet": wallet}) @@ -278,8 +282,51 @@ class LBRYConsole(): dl.addCallback(lambda _: self.session.setup()) + dl.addCallback(lambda _: self.check_first_run()) + + dl.addCallback(self._show_first_run_result) + return dl + def check_first_run(self): + d = self.session.wallet.check_first_run() + d.addCallback(lambda is_first_run: self._do_first_run() if is_first_run else 0.0) + return d + + def _do_first_run(self): + d = self.session.wallet.get_new_address() + + def send_request(url, data): + r = requests.post(url, json=data) + if r.status_code == 200: + return r.json()['credits_sent'] + return 0.0 + + def log_error(err): + log.warning("unable to request free credits. %s", err.getErrorMessage()) + return 0.0 + + def request_credits(address): + url = "http://credreq.lbry.io/requestcredits" + data = {"address": address} + d = threads.deferToThread(send_request, url, data) + d.addErrback(log_error) + return d + + d.addCallback(request_credits) + return d + + @staticmethod + def _show_first_run_result(credits_received): + if credits_received != 0.0: + points_string = locale.format_string("%.2f LBC", (round(credits_received, 2),), + grouping=True) + alert.info("Thank you for using LBRY! You have been given %s for free because we " + "love you. Please give them a few minutes to show up while you catch up " + "with our blockchain.\nTo check whether you've caught up with the blockchain, " + "use the command 'get-blockchain-status'.\nDownloading some files " + "may not work until you have downloaded the LBC blockchain.", points_string) + def _setup_lbry_file_manager(self): self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir) d = self.lbry_file_metadata_manager.setup() @@ -333,10 +380,11 @@ class LBRYConsole(): lbrycrd_handlers = [ AddStreamFromLBRYcrdNameFactory(self.sd_identifier, self.session, self.session.wallet), - ClaimNameFactory(self.session. wallet, self.lbry_file_manager, + ClaimNameFactory(self.session.wallet, self.lbry_file_manager, self.session.blob_manager), GetNewWalletAddressFactory(self.session.wallet), - PublishFactory(self.session, self.lbry_file_manager, self.session.wallet) + PublishFactory(self.session, self.lbry_file_manager, self.session.wallet), + BlockchainStatusFactory(self.session.wallet) ] self.add_control_handlers(lbrycrd_handlers) if self.peer_port is not None: diff --git a/lbrynet/lbrynet_gui/GuiApp.py b/lbrynet/lbrynet_gui/GuiApp.py index 8f5081002..573ac1df6 100644 --- a/lbrynet/lbrynet_gui/GuiApp.py +++ b/lbrynet/lbrynet_gui/GuiApp.py @@ -226,7 +226,7 @@ class DownloaderApp(object): def _start_downloader(self): self.downloader = LBRYDownloader() d = self.downloader.start() - d.addCallback(lambda _: self.downloader.do_first_run()) + d.addCallback(lambda _: self.downloader.check_first_run()) d.addCallback(self._show_welcome_message) return d diff --git a/lbrynet/lbrynet_gui/LBRYGui.py b/lbrynet/lbrynet_gui/LBRYGui.py index f8cdfa8c4..fad1d0fb0 100644 --- a/lbrynet/lbrynet_gui/LBRYGui.py +++ b/lbrynet/lbrynet_gui/LBRYGui.py @@ -32,8 +32,6 @@ class LBRYDownloader(object): self.known_dht_nodes = [('104.236.42.182', 4000)] self.db_dir = os.path.join(os.path.expanduser("~"), ".lbrydownloader") self.blobfile_dir = os.path.join(self.db_dir, "blobfiles") - self.wallet_dir = os.path.join(os.path.expanduser("~"), ".lbrycrd") - self.wallet_conf = os.path.join(self.wallet_dir, "lbrycrd.conf") self.peer_port = 3333 self.dht_node_port = 4444 self.run_server = True @@ -42,8 +40,11 @@ class LBRYDownloader(object): if os.name == "nt": from lbrynet.winhelpers.knownpaths import get_path, FOLDERID, UserHandle self.download_directory = get_path(FOLDERID.Downloads, UserHandle.current) + self.wallet_dir = os.path.join(get_path(FOLDERID.RoamingAppData, UserHandle.current), "lbrycrd") else: self.download_directory = os.getcwd() + self.wallet_dir = os.path.join(os.path.expanduser("~"), ".lbrycrd") + self.wallet_conf = os.path.join(self.wallet_dir, "lbrycrd.conf") self.wallet_user = None self.wallet_password = None self.sd_identifier = StreamDescriptorIdentifier() @@ -267,26 +268,26 @@ class LBRYDownloader(object): if not os.path.exists(self.blobfile_dir): os.makedirs(self.blobfile_dir) log.debug("Created the data directory: %s", str(self.blobfile_dir)) - if not os.path.exists(self.wallet_dir): - os.makedirs(self.wallet_dir) - if not os.path.exists(self.wallet_conf): - lbrycrd_conf = open(self.wallet_conf, mode='w') - self.wallet_user = "rpcuser" - lbrycrd_conf.write("rpcuser=%s\n" % self.wallet_user) - self.wallet_password = binascii.hexlify(Random.new().read(20)) - lbrycrd_conf.write("rpcpassword=%s\n" % self.wallet_password) - lbrycrd_conf.write("server=1\n") - lbrycrd_conf.close() - self.first_run = True - else: - lbrycrd_conf = open(self.wallet_conf) - for l in lbrycrd_conf: - if l.startswith("rpcuser="): - self.wallet_user = l[8:].rstrip('\n') - if l.startswith("rpcpassword="): - self.wallet_password = l[12:].rstrip('\n') - if l.startswith("rpcport="): - self.wallet_rpc_port = int(l[8:-1].rstrip('\n')) + if os.name == "nt": + if not os.path.exists(self.wallet_dir): + os.makedirs(self.wallet_dir) + if not os.path.exists(self.wallet_conf): + lbrycrd_conf = open(self.wallet_conf, mode='w') + self.wallet_user = "rpcuser" + lbrycrd_conf.write("rpcuser=%s\n" % self.wallet_user) + self.wallet_password = binascii.hexlify(Random.new().read(20)) + lbrycrd_conf.write("rpcpassword=%s\n" % self.wallet_password) + lbrycrd_conf.write("server=1\n") + lbrycrd_conf.close() + else: + lbrycrd_conf = open(self.wallet_conf) + for l in lbrycrd_conf: + if l.startswith("rpcuser="): + self.wallet_user = l[8:].rstrip('\n') + if l.startswith("rpcpassword="): + self.wallet_password = l[12:].rstrip('\n') + if l.startswith("rpcport="): + self.wallet_rpc_port = int(l[8:-1].rstrip('\n')) def _get_session(self): lbrycrdd_path = None @@ -349,30 +350,33 @@ class LBRYDownloader(object): self.session.wallet) self.sd_identifier.add_stream_downloader_factory(LBRYFileStreamType, file_opener_factory) - def do_first_run(self): - if self.first_run is True: - d = self.session.wallet.get_new_address() + def check_first_run(self): + d = self.session.wallet.check_first_run() + d.addCallback(lambda is_first_run: self._do_first_run() if is_first_run else 0.0) + return d - def send_request(url, data): - r = requests.post(url, json=data) - if r.status_code == 200: - return r.json()['credits_sent'] - return 0.0 + def _do_first_run(self): + d = self.session.wallet.get_new_address() - def log_error(err): - log.warning("unable to request free credits. %s", err.getErrorMessage()) - return 0.0 + def send_request(url, data): + r = requests.post(url, json=data) + if r.status_code == 200: + return r.json()['credits_sent'] + return 0.0 - def request_credits(address): - url = "http://credreq.lbry.io/requestcredits" - data = {"address": address} - d = threads.deferToThread(send_request, url, data) - d.addErrback(log_error) - return d + def log_error(err): + log.warning("unable to request free credits. %s", err.getErrorMessage()) + return 0.0 - d.addCallback(request_credits) + def request_credits(address): + url = "http://credreq.lbry.io/requestcredits" + data = {"address": address} + d = threads.deferToThread(send_request, url, data) + d.addErrback(log_error) return d - return defer.succeed(0.0) + + d.addCallback(request_credits) + return d def _resolve_name(self, uri): return self.session.wallet.get_stream_info_for_name(uri)