Merge pull request #260 from lbryio/error-messages

meaningful error messages, improve cli, remove unused search from daemon
This commit is contained in:
Jack Robison 2016-11-22 15:54:21 -05:00 committed by GitHub
commit f65a50a6a3
7 changed files with 163 additions and 230 deletions

View file

@ -163,7 +163,6 @@ class AdjustableSettings(Setting):
self.check_ui_requirements = True self.check_ui_requirements = True
self.local_ui_path = False self.local_ui_path = False
self.api_port = 5279 self.api_port = 5279
self.search_servers = ['lighthouse1.lbry.io:50005']
self.data_rate = .0001 # points/megabyte self.data_rate = .0001 # points/megabyte
self.min_info_rate = .02 # points/1000 infos self.min_info_rate = .02 # points/1000 infos
self.min_valuable_info_rate = .05 # points/1000 infos self.min_valuable_info_rate = .05 # points/1000 infos

View file

@ -321,6 +321,7 @@ class KademliaProtocol(protocol.DatagramProtocol):
except Exception, e: except Exception, e:
log.exception('Failed to cancel %s', self._callLaterList[key]) log.exception('Failed to cancel %s', self._callLaterList[key])
del self._callLaterList[key] del self._callLaterList[key]
# not sure why this is needed, but taking this out sometimes causes # not sure why this is needed, but taking this out sometimes causes
# exceptions.AttributeError: 'Port' object has no attribute 'socket' # exceptions.AttributeError: 'Port' object has no attribute 'socket'
# to happen on shutdown # to happen on shutdown

View file

@ -9,11 +9,11 @@ import sys
import base58 import base58
import requests import requests
import simplejson as json import simplejson as json
from urllib2 import urlopen from urllib2 import urlopen
from appdirs import user_data_dir from appdirs import user_data_dir
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
from twisted.web import server from twisted.web import server
from twisted.internet import defer, threads, error, reactor, task from twisted.internet import defer, threads, error, reactor, task
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
@ -22,41 +22,32 @@ from jsonschema import ValidationError
# TODO: importing this when internet is disabled raises a socket.gaierror # TODO: importing this when internet is disabled raises a socket.gaierror
from lbryum.version import LBRYUM_VERSION as lbryum_version from lbryum.version import LBRYUM_VERSION as lbryum_version
from lbrynet import __version__ as lbrynet_version from lbrynet import __version__ as lbrynet_version
from lbrynet import conf from lbrynet import conf, reflector, analytics
from lbrynet.conf import settings as lbrynet_settings
from lbrynet.conf import LBRYCRD_WALLET, LBRYUM_WALLET, PTC_WALLET from lbrynet.conf import LBRYCRD_WALLET, LBRYUM_WALLET, PTC_WALLET
from lbrynet import analytics
from lbrynet.metadata.Fee import FeeValidator from lbrynet.metadata.Fee import FeeValidator
from lbrynet.core import Platform from lbrynet.metadata.Metadata import Metadata, verify_name_characters
from lbrynet.core.looping_call_manager import LoopingCallManager
from lbrynet.core.server.BlobRequestHandler import BlobRequestHandlerFactory
from lbrynet.core.server.ServerProtocol import ServerProtocolFactory
from lbrynet.core.Error import InsufficientFundsError, InvalidNameError
from lbrynet.lbryfile.StreamDescriptor import EncryptedFileStreamType
from lbrynet.lbryfile.client.EncryptedFileDownloader import EncryptedFileSaverFactory, EncryptedFileOpenerFactory from lbrynet.lbryfile.client.EncryptedFileDownloader import EncryptedFileSaverFactory, EncryptedFileOpenerFactory
from lbrynet.lbryfile.client.EncryptedFileOptions import add_lbry_file_to_sd_identifier from lbrynet.lbryfile.client.EncryptedFileOptions import add_lbry_file_to_sd_identifier
from lbrynet.lbryfile.EncryptedFileMetadataManager import DBEncryptedFileMetadataManager
from lbrynet.lbryfile.EncryptedFileMetadataManager import TempEncryptedFileMetadataManager
from lbrynet.lbryfile.StreamDescriptor import EncryptedFileStreamType
from lbrynet.lbryfilemanager.EncryptedFileManager import EncryptedFileManager
from lbrynet.lbrynet_console.Settings import Settings
from lbrynet.lbrynet_daemon.UIManager import UIManager from lbrynet.lbrynet_daemon.UIManager import UIManager
from lbrynet.lbrynet_daemon.Downloader import GetStream from lbrynet.lbrynet_daemon.Downloader import GetStream
from lbrynet.lbrynet_daemon.Publisher import Publisher from lbrynet.lbrynet_daemon.Publisher import Publisher
from lbrynet.lbrynet_daemon.ExchangeRateManager import ExchangeRateManager from lbrynet.lbrynet_daemon.ExchangeRateManager import ExchangeRateManager
from lbrynet.lbrynet_daemon.Lighthouse import LighthouseClient
from lbrynet.lbrynet_daemon.auth.server import AuthJSONRPCServer from lbrynet.lbrynet_daemon.auth.server import AuthJSONRPCServer
from lbrynet.core import log_support, utils, Platform
from lbrynet.metadata.Metadata import Metadata, verify_name_characters
from lbrynet.core import log_support
from lbrynet.core import utils
from lbrynet.core.utils import generate_id
from lbrynet.lbrynet_console.Settings import Settings
from lbrynet.core.StreamDescriptor import StreamDescriptorIdentifier, download_sd_blob, BlobStreamDescriptorReader from lbrynet.core.StreamDescriptor import StreamDescriptorIdentifier, download_sd_blob, BlobStreamDescriptorReader
from lbrynet.core.Session import Session from lbrynet.core.Session import Session
from lbrynet.core.PTCWallet import PTCWallet from lbrynet.core.PTCWallet import PTCWallet
from lbrynet.core.Wallet import LBRYcrdWallet, LBRYumWallet from lbrynet.core.Wallet import LBRYcrdWallet, LBRYumWallet
from lbrynet.lbryfilemanager.EncryptedFileManager import EncryptedFileManager from lbrynet.core.looping_call_manager import LoopingCallManager
from lbrynet.lbryfile.EncryptedFileMetadataManager import DBEncryptedFileMetadataManager, TempEncryptedFileMetadataManager from lbrynet.core.server.BlobRequestHandler import BlobRequestHandlerFactory
from lbrynet import reflector from lbrynet.core.server.ServerProtocol import ServerProtocolFactory
from lbrynet.core.Error import InsufficientFundsError, InvalidNameError
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -209,52 +200,51 @@ class Daemon(AuthJSONRPCServer):
""" """
def __init__(self, root, analytics_manager): def __init__(self, root, analytics_manager):
AuthJSONRPCServer.__init__(self, lbrynet_settings.use_auth_http) AuthJSONRPCServer.__init__(self, conf.settings.use_auth_http)
reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown) reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown)
self.allowed_during_startup = [ self.allowed_during_startup = [
'is_running', 'is_first_run', 'is_running', 'is_first_run',
'get_time_behind_blockchain', 'stop', 'get_time_behind_blockchain', 'stop',
'daemon_status', 'get_start_notice', 'daemon_status', 'get_start_notice',
'version', 'get_search_servers' 'version'
] ]
last_version = {'last_version': {'lbrynet': lbrynet_version, 'lbryum': lbryum_version}} last_version = {'last_version': {'lbrynet': lbrynet_version, 'lbryum': lbryum_version}}
lbrynet_settings.update(last_version) conf.settings.update(last_version)
self.db_dir = lbrynet_settings.data_dir self.db_dir = conf.settings.data_dir
self.download_directory = lbrynet_settings.download_directory self.download_directory = conf.settings.download_directory
self.created_data_dir = False self.created_data_dir = False
if not os.path.exists(self.db_dir): if not os.path.exists(self.db_dir):
os.mkdir(self.db_dir) os.mkdir(self.db_dir)
self.created_data_dir = True self.created_data_dir = True
if lbrynet_settings.BLOBFILES_DIR == "blobfiles": if conf.settings.BLOBFILES_DIR == "blobfiles":
self.blobfile_dir = os.path.join(self.db_dir, "blobfiles") self.blobfile_dir = os.path.join(self.db_dir, "blobfiles")
else: else:
log.info("Using non-default blobfiles directory: %s", lbrynet_settings.BLOBFILES_DIR) log.info("Using non-default blobfiles directory: %s", conf.settings.BLOBFILES_DIR)
self.blobfile_dir = lbrynet_settings.BLOBFILES_DIR self.blobfile_dir = conf.settings.BLOBFILES_DIR
self.run_on_startup = lbrynet_settings.run_on_startup self.run_on_startup = conf.settings.run_on_startup
self.data_rate = lbrynet_settings.data_rate self.data_rate = conf.settings.data_rate
self.max_key_fee = lbrynet_settings.max_key_fee self.max_key_fee = conf.settings.max_key_fee
self.max_upload = lbrynet_settings.max_upload self.max_upload = conf.settings.max_upload
self.max_download = lbrynet_settings.max_download self.max_download = conf.settings.max_download
self.upload_log = lbrynet_settings.upload_log self.upload_log = conf.settings.upload_log
self.search_timeout = lbrynet_settings.search_timeout self.search_timeout = conf.settings.search_timeout
self.download_timeout = lbrynet_settings.download_timeout self.download_timeout = conf.settings.download_timeout
self.max_search_results = lbrynet_settings.max_search_results self.max_search_results = conf.settings.max_search_results
self.run_reflector_server = lbrynet_settings.run_reflector_server self.run_reflector_server = conf.settings.run_reflector_server
self.wallet_type = lbrynet_settings.wallet self.wallet_type = conf.settings.wallet
self.delete_blobs_on_remove = lbrynet_settings.delete_blobs_on_remove self.delete_blobs_on_remove = conf.settings.delete_blobs_on_remove
self.peer_port = lbrynet_settings.peer_port self.peer_port = conf.settings.peer_port
self.reflector_port = lbrynet_settings.reflector_port self.reflector_port = conf.settings.reflector_port
self.dht_node_port = lbrynet_settings.dht_node_port self.dht_node_port = conf.settings.dht_node_port
self.use_upnp = lbrynet_settings.use_upnp self.use_upnp = conf.settings.use_upnp
self.start_lbrycrdd = lbrynet_settings.start_lbrycrdd self.start_lbrycrdd = conf.settings.start_lbrycrdd
self.cache_time = lbrynet_settings.cache_time self.cache_time = conf.settings.cache_time
self.startup_scripts = lbrynet_settings.startup_scripts self.startup_scripts = conf.settings.startup_scripts
self.startup_status = STARTUP_STAGES[0] self.startup_status = STARTUP_STAGES[0]
self.startup_message = None self.startup_message = None
self.announced_startup = False
self.connected_to_internet = True self.connected_to_internet = True
self.connection_problem = None self.connection_problem = None
self.git_lbrynet_version = None self.git_lbrynet_version = None
@ -262,19 +252,19 @@ class Daemon(AuthJSONRPCServer):
self.ui_version = None self.ui_version = None
self.platform = None self.platform = None
self.first_run = None self.first_run = None
self.log_file = lbrynet_settings.get_log_filename() self.log_file = conf.settings.get_log_filename()
self.current_db_revision = 1 self.current_db_revision = 1
self.session = None self.session = None
self.uploaded_temp_files = [] self.uploaded_temp_files = []
self._session_id = base58.b58encode(generate_id()) self._session_id = base58.b58encode(utils.generate_id())
# TODO: this should probably be passed into the daemon, or # TODO: this should probably be passed into the daemon, or
# possibly have the entire log upload functionality taken out # possibly have the entire log upload functionality taken out
# of the daemon, but I don't want to deal with that now # of the daemon, but I don't want to deal with that now
self.log_uploader = log_support.LogUploader.load('lbrynet', self.log_file) self.log_uploader = log_support.LogUploader.load('lbrynet', self.log_file)
self.analytics_manager = None self.analytics_manager = analytics_manager
self.lbryid = PENDING_LBRY_ID self.lbryid = PENDING_LBRY_ID
self.daemon_conf = lbrynet_settings.get_conf_filename() self.daemon_conf = conf.settings.get_conf_filename()
self.wallet_user = None self.wallet_user = None
self.wallet_password = None self.wallet_password = None
@ -285,7 +275,6 @@ class Daemon(AuthJSONRPCServer):
self.name_cache = {} self.name_cache = {}
self.set_wallet_attributes() self.set_wallet_attributes()
self.exchange_rate_manager = ExchangeRateManager() self.exchange_rate_manager = ExchangeRateManager()
self.lighthouse_client = LighthouseClient()
calls = { calls = {
Checker.INTERNET_CONNECTION: LoopingCall(CheckInternetConnection(self)), Checker.INTERNET_CONNECTION: LoopingCall(CheckInternetConnection(self)),
Checker.VERSION: LoopingCall(CheckRemoteVersions(self)), Checker.VERSION: LoopingCall(CheckRemoteVersions(self)),
@ -300,7 +289,6 @@ class Daemon(AuthJSONRPCServer):
self.blob_request_payment_rate_manager = None self.blob_request_payment_rate_manager = None
self.lbry_file_metadata_manager = None self.lbry_file_metadata_manager = None
self.lbry_file_manager = None self.lbry_file_manager = None
self.analytics_manager = analytics_manager
@AuthJSONRPCServer.subhandler @AuthJSONRPCServer.subhandler
def _exclude_lbrycrd_only_commands_from_lbryum_session(self, request): def _exclude_lbrycrd_only_commands_from_lbryum_session(self, request):
@ -377,7 +365,7 @@ class Daemon(AuthJSONRPCServer):
self.exchange_rate_manager.start() self.exchange_rate_manager.start()
d = defer.Deferred() d = defer.Deferred()
if lbrynet_settings.host_ui: if conf.settings.host_ui:
self.lbry_ui_manager.update_checker.start(1800, now=False) self.lbry_ui_manager.update_checker.start(1800, now=False)
d.addCallback(lambda _: self.lbry_ui_manager.setup()) d.addCallback(lambda _: self.lbry_ui_manager.setup())
d.addCallback(lambda _: self._initial_setup()) d.addCallback(lambda _: self._initial_setup())
@ -661,27 +649,27 @@ class Daemon(AuthJSONRPCServer):
for key, setting_type in setting_types.iteritems(): for key, setting_type in setting_types.iteritems():
if key in settings: if key in settings:
if isinstance(settings[key], setting_type): if isinstance(settings[key], setting_type):
lbrynet_settings.update({key: settings[key]}) conf.settings.update({key: settings[key]})
elif key == "max_key_fee" and isinstance(FeeValidator(settings[key]).amount, setting_type): elif key == "max_key_fee" and isinstance(FeeValidator(settings[key]).amount, setting_type):
lbrynet_settings.update({key: settings[key]}) conf.settings.update({key: settings[key]})
else: else:
try: try:
converted = setting_type(settings[key]) converted = setting_type(settings[key])
lbrynet_settings.update({key: converted}) conf.settings.update({key: converted})
except Exception as err: except Exception as err:
log.warning(err.message) log.warning(err.message)
log.warning("error converting setting '%s' to type %s", key, setting_type) log.warning("error converting setting '%s' to type %s", key, setting_type)
self.run_on_startup = lbrynet_settings.run_on_startup self.run_on_startup = conf.settings.run_on_startup
self.data_rate = lbrynet_settings.data_rate self.data_rate = conf.settings.data_rate
self.max_key_fee = lbrynet_settings.max_key_fee self.max_key_fee = conf.settings.max_key_fee
self.download_directory = lbrynet_settings.download_directory self.download_directory = conf.settings.download_directory
self.max_upload = lbrynet_settings.max_upload self.max_upload = conf.settings.max_upload
self.max_download = lbrynet_settings.max_download self.max_download = conf.settings.max_download
self.upload_log = lbrynet_settings.upload_log self.upload_log = conf.settings.upload_log
self.download_timeout = lbrynet_settings.download_timeout self.download_timeout = conf.settings.download_timeout
self.search_timeout = lbrynet_settings.search_timeout self.search_timeout = conf.settings.search_timeout
self.cache_time = lbrynet_settings.cache_time self.cache_time = conf.settings.cache_time
return defer.succeed(True) return defer.succeed(True)
@ -738,7 +726,7 @@ class Daemon(AuthJSONRPCServer):
self.lbryid = lbryid self.lbryid = lbryid
def _make_set_and_save_lbryid(self): def _make_set_and_save_lbryid(self):
self.lbryid = generate_id() self.lbryid = utils.generate_id()
log.info("Generated new LBRY ID: " + base58.b58encode(self.lbryid)) log.info("Generated new LBRY ID: " + base58.b58encode(self.lbryid))
d = self.settings.save_lbryid(self.lbryid) d = self.settings.save_lbryid(self.lbryid)
return d return d
@ -785,7 +773,7 @@ class Daemon(AuthJSONRPCServer):
def get_default_data_rate(): def get_default_data_rate():
d = self.settings.get_default_data_payment_rate() d = self.settings.get_default_data_payment_rate()
d.addCallback(lambda rate: {"default_data_payment_rate": rate if rate is not None else d.addCallback(lambda rate: {"default_data_payment_rate": rate if rate is not None else
lbrynet_settings.data_rate}) conf.settings.data_rate})
return d return d
def get_wallet(): def get_wallet():
@ -799,8 +787,8 @@ class Daemon(AuthJSONRPCServer):
elif self.wallet_type == LBRYUM_WALLET: elif self.wallet_type == LBRYUM_WALLET:
log.info("Using lbryum wallet") log.info("Using lbryum wallet")
config = {'auto_connect': True} config = {'auto_connect': True}
if lbrynet_settings.lbryum_wallet_dir: if conf.settings.lbryum_wallet_dir:
config['lbryum_path'] = lbrynet_settings.lbryum_wallet_dir config['lbryum_path'] = conf.settings.lbryum_wallet_dir
d = defer.succeed(LBRYumWallet(self.db_dir, config)) d = defer.succeed(LBRYumWallet(self.db_dir, config))
elif self.wallet_type == PTC_WALLET: elif self.wallet_type == PTC_WALLET:
log.info("Using PTC wallet") log.info("Using PTC wallet")
@ -823,7 +811,7 @@ class Daemon(AuthJSONRPCServer):
def create_session(results): def create_session(results):
self.session = Session(results['default_data_payment_rate'], db_dir=self.db_dir, lbryid=self.lbryid, self.session = Session(results['default_data_payment_rate'], db_dir=self.db_dir, lbryid=self.lbryid,
blob_dir=self.blobfile_dir, dht_node_port=self.dht_node_port, blob_dir=self.blobfile_dir, dht_node_port=self.dht_node_port,
known_dht_nodes=lbrynet_settings.known_dht_nodes, peer_port=self.peer_port, known_dht_nodes=conf.settings.known_dht_nodes, peer_port=self.peer_port,
use_upnp=self.use_upnp, wallet=results['wallet']) use_upnp=self.use_upnp, wallet=results['wallet'])
self.startup_status = STARTUP_STAGES[2] self.startup_status = STARTUP_STAGES[2]
@ -845,7 +833,7 @@ class Daemon(AuthJSONRPCServer):
self.sd_identifier.add_stream_downloader_factory(EncryptedFileStreamType, file_opener_factory) self.sd_identifier.add_stream_downloader_factory(EncryptedFileStreamType, file_opener_factory)
return defer.succeed(None) return defer.succeed(None)
def _download_sd_blob(self, sd_hash, timeout=lbrynet_settings.sd_download_timeout): def _download_sd_blob(self, sd_hash, timeout=conf.settings.sd_download_timeout):
def cb(result): def cb(result):
if not r.called: if not r.called:
r.callback(result) r.callback(result)
@ -866,7 +854,7 @@ class Daemon(AuthJSONRPCServer):
return r return r
def _download_name(self, name, timeout=lbrynet_settings.download_timeout, download_directory=None, def _download_name(self, name, timeout=conf.settings.download_timeout, download_directory=None,
file_name=None, stream_info=None, wait_for_write=True): file_name=None, stream_info=None, wait_for_write=True):
""" """
Add a lbry file to the file manager, start the download, and return the new lbry file. Add a lbry file to the file manager, start the download, and return the new lbry file.
@ -1039,7 +1027,7 @@ class Daemon(AuthJSONRPCServer):
log.info("Removing one time startup scripts") log.info("Removing one time startup scripts")
remaining_scripts = [s for s in self.startup_scripts if 'run_once' not in s.keys()] remaining_scripts = [s for s in self.startup_scripts if 'run_once' not in s.keys()]
startup_scripts = self.startup_scripts startup_scripts = self.startup_scripts
self.startup_scripts = lbrynet_settings.startup_scripts = remaining_scripts self.startup_scripts = conf.settings.startup_scripts = remaining_scripts
conf.save_settings() conf.save_settings()
for script in startup_scripts: for script in startup_scripts:
@ -1055,9 +1043,6 @@ class Daemon(AuthJSONRPCServer):
return defer.succeed(None) return defer.succeed(None)
def _search(self, search):
return self.lighthouse_client.search(search)
def jsonrpc_is_running(self): def jsonrpc_is_running(self):
""" """
Check if lbrynet daemon is running Check if lbrynet daemon is running
@ -1218,7 +1203,7 @@ class Daemon(AuthJSONRPCServer):
""" """
log.info("Get daemon settings") log.info("Get daemon settings")
return self._render_response(lbrynet_settings.__dict__, OK_CODE) return self._render_response(conf.settings.__dict__, OK_CODE)
@AuthJSONRPCServer.auth_required @AuthJSONRPCServer.auth_required
def jsonrpc_set_settings(self, p): def jsonrpc_set_settings(self, p):
@ -1239,12 +1224,12 @@ class Daemon(AuthJSONRPCServer):
""" """
def _log_settings_change(): def _log_settings_change():
log.info("Set daemon settings to " + json.dumps(lbrynet_settings.configurable_settings)) log.info("Set daemon settings to " + json.dumps(conf.settings.configurable_settings))
d = self._update_settings(p) d = self._update_settings(p)
d.addErrback(lambda err: log.info(err.getTraceback())) d.addErrback(lambda err: log.info(err.getTraceback()))
d.addCallback(lambda _: _log_settings_change()) d.addCallback(lambda _: _log_settings_change())
d.addCallback(lambda _: self._render_response(lbrynet_settings.configurable_settings, OK_CODE)) d.addCallback(lambda _: self._render_response(conf.settings.configurable_settings, OK_CODE))
return d return d
@ -1556,42 +1541,6 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda r: self._render_response(r, OK_CODE)) d.addCallback(lambda r: self._render_response(r, OK_CODE))
return d return d
def jsonrpc_search_nametrie(self, p):
"""
Search the nametrie for claims
Args:
'search': search query, string
Returns:
List of search results
"""
# TODO: change this function to "search"
if 'search' in p.keys():
search = p['search']
else:
return self._render_response(None, BAD_REQUEST)
# TODO: have ui accept the actual outputs
def _clean(n):
t = []
for i in n:
td = {k: i['value'][k] for k in i['value']}
td['cost_est'] = float(i['cost'])
td['thumbnail'] = i['value'].get('thumbnail', "img/Free-speech-flag.svg")
td['name'] = i['name']
t.append(td)
return t
log.info('Search: %s' % search)
d = self._search(search)
d.addCallback(_clean)
d.addCallback(lambda results: self._render_response(results, OK_CODE))
return d
@AuthJSONRPCServer.auth_required @AuthJSONRPCServer.auth_required
def jsonrpc_delete_lbry_file(self, p): def jsonrpc_delete_lbry_file(self, p):
""" """
@ -2002,7 +1951,7 @@ class Daemon(AuthJSONRPCServer):
sd blob, dict sd blob, dict
""" """
sd_hash = p[FileID.SD_HASH] sd_hash = p[FileID.SD_HASH]
timeout = p.get('timeout', lbrynet_settings.sd_download_timeout) timeout = p.get('timeout', conf.settings.sd_download_timeout)
d = self._download_sd_blob(sd_hash, timeout) d = self._download_sd_blob(sd_hash, timeout)
d.addCallbacks( d.addCallbacks(
lambda r: self._render_response(r, OK_CODE), lambda r: self._render_response(r, OK_CODE),
@ -2235,18 +2184,6 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda r: self._render_response(r, OK_CODE)) d.addCallback(lambda r: self._render_response(r, OK_CODE))
return d return d
def jsonrpc_get_search_servers(self):
"""
Get list of lighthouse servers
Args:
None
Returns:
List of address:port
"""
d = self._render_response(lbrynet_settings.search_servers, OK_CODE)
return d
def jsonrpc_get_mean_availability(self): def jsonrpc_get_mean_availability(self):
""" """
Get mean blob availability Get mean blob availability
@ -2365,7 +2302,7 @@ def get_darwin_lbrycrdd_path():
class _DownloadNameHelper(object): class _DownloadNameHelper(object):
def __init__(self, daemon, name, timeout=lbrynet_settings.download_timeout, download_directory=None, def __init__(self, daemon, name, timeout=conf.settings.download_timeout, download_directory=None,
file_name=None, wait_for_write=True): file_name=None, wait_for_write=True):
self.daemon = daemon self.daemon = daemon
self.name = name self.name = name
@ -2668,7 +2605,7 @@ def handle_failure(err, msg):
def run_reflector_factory(factory): def run_reflector_factory(factory):
reflector_server = random.choice(lbrynet_settings.reflector_servers) reflector_server = random.choice(conf.settings.reflector_servers)
reflector_address, reflector_port = reflector_server reflector_address, reflector_port = reflector_server
log.info("Start reflector client") log.info("Start reflector client")
d = reactor.resolve(reflector_address) d = reactor.resolve(reflector_address)

View file

@ -1,15 +1,17 @@
import sys import sys
import json
import argparse import argparse
import json
from lbrynet.conf import settings from lbrynet.conf import settings
from lbrynet.lbrynet_daemon.auth.client import LBRYAPIClient from lbrynet.lbrynet_daemon.auth.client import LBRYAPIClient
from jsonrpc.common import RPCError
help_msg = "Usage: lbrynet-cli method json-args\n" \
help_msg = "Usage: lbrynet-cli method kwargs\n" \
+ "Examples: " \ + "Examples: " \
+ "lbrynet-cli resolve_name '{\"name\": \"what\"}'\n" \ + "lbrynet-cli resolve_name name=what\n" \
+ "lbrynet-cli get_balance\n" \ + "lbrynet-cli get_balance\n" \
+ "lbrynet-cli help '{\"function\": \"resolve_name\"}'\n" \ + "lbrynet-cli help function=resolve_name\n" \
+ "\n******lbrynet-cli functions******\n" + "\n******lbrynet-cli functions******\n"
@ -59,14 +61,13 @@ def main():
meth = args.method[0] meth = args.method[0]
params = {} params = {}
if args.params: if len(args.params) > 1:
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) 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 msg = help_msg
for f in api.help(): for f in api.help():
@ -83,14 +84,16 @@ def main():
else: else:
result = LBRYAPIClient.config(service=meth, params=params) result = LBRYAPIClient.config(service=meth, params=params)
print json.dumps(result, sort_keys=True) print json.dumps(result, sort_keys=True)
except: except RPCError as err:
# TODO: The api should return proper error codes # TODO: The api should return proper error codes
# and messages so that they can be passed along to the user # and messages so that they can be passed along to the user
# instead of this generic message. # instead of this generic message.
# https://app.asana.com/0/158602294500137/200173944358192 # https://app.asana.com/0/158602294500137/200173944358192
print "Something went wrong, here's the usage for %s:" % meth print "Something went wrong, here's the usage for %s:" % meth
print api.help({'function': meth}) print api.help({'function': meth})
print "Here's the traceback for the error you encountered:"
print err.msg
else: else:
print "Unknown function" print "Unknown function"
print msg print msg

View file

@ -1,4 +1,3 @@
import json
import logging import logging
import os import os
@ -77,13 +76,10 @@ class GetStream(object):
self.finished.callback((False, None, None)) self.finished.callback((False, None, None))
def _convert_max_fee(self): def _convert_max_fee(self):
if isinstance(self.max_key_fee, dict): max_fee = FeeValidator(self.max_key_fee)
max_fee = FeeValidator(self.max_key_fee) if max_fee.currency_symbol == "LBC":
if max_fee.currency_symbol == "LBC": return max_fee.amount
return max_fee.amount return self.exchange_rate_manager.to_lbc(self.max_key_fee).amount
return self.exchange_rate_manager.to_lbc(self.fee).amount
elif isinstance(self.max_key_fee, float):
return float(self.max_key_fee)
def start(self, stream_info, name): def start(self, stream_info, name):
def _cause_timeout(err): def _cause_timeout(err):
@ -117,14 +113,18 @@ class GetStream(object):
if 'fee' in self.stream_info: if 'fee' in self.stream_info:
self.fee = FeeValidator(self.stream_info['fee']) self.fee = FeeValidator(self.stream_info['fee'])
max_key_fee = self._convert_max_fee() max_key_fee = self._convert_max_fee()
if self.exchange_rate_manager.to_lbc(self.fee).amount > max_key_fee: converted_fee = self.exchange_rate_manager.to_lbc(self.fee).amount
log.info("Key fee %f above limit of %f didn't download lbry://%s" % (self.fee.amount, if converted_fee > self.wallet.get_balance():
self.max_key_fee, log.warning("Insufficient funds to download lbry://%s", self.resolved_name)
self.resolved_name)) return defer.fail(InsufficientFundsError())
if converted_fee > max_key_fee:
log.warning("Key fee %f above limit of %f didn't download lbry://%s", converted_fee,
max_key_fee,
self.resolved_name)
return defer.fail(KeyFeeAboveMaxAllowed()) return defer.fail(KeyFeeAboveMaxAllowed())
log.info("Key fee %s below limit of %f, downloading lbry://%s" % (json.dumps(self.fee), log.info("Key fee %f below limit of %f, downloading lbry://%s", converted_fee,
max_key_fee, max_key_fee,
self.resolved_name)) self.resolved_name)
self.checker.start(1) self.checker.start(1)

View file

@ -1,27 +0,0 @@
import logging
import random
from txjsonrpc.web.jsonrpc import Proxy
from lbrynet.conf import settings
log = logging.getLogger(__name__)
class LighthouseClient(object):
def __init__(self, servers=None):
self.servers = servers or settings.search_servers
def _get_random_server(self):
return Proxy(random.choice(self.servers))
def _run_query(self, func, arg):
return self._get_random_server().callRemote(func, arg)
def search(self, search):
return self._run_query('search', search)
def announce_sd(self, sd_hash):
log.info("Announce sd to lighthouse")
return self._run_query('announce_sd', sd_hash)
def check_available(self, sd_hash):
return self._run_query('check_available', sd_hash)

View file

@ -1,11 +1,11 @@
import logging import logging
from decimal import Decimal from decimal import Decimal
from zope.interface import implements from zope.interface import implements
from twisted.web import server, resource from twisted.web import server, resource
from twisted.internet import defer from twisted.internet import defer
from txjsonrpc import jsonrpclib 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, SubhandlerError
from lbrynet.conf import settings from lbrynet.conf import settings
from lbrynet.core import log_support from lbrynet.core import log_support
@ -20,6 +20,16 @@ def default_decimal(obj):
return float(obj) return float(obj)
class JSONRPCException(Exception):
def __init__(self, err, code):
self.faultCode = code
self.err = err
@property
def faultString(self):
return self.err.getTraceback()
class AuthorizedBase(object): class AuthorizedBase(object):
def __init__(self): def __init__(self):
self.authorized_functions = [] self.authorized_functions = []
@ -85,20 +95,36 @@ class AuthJSONRPCServer(AuthorizedBase):
def __init__(self, use_authentication=settings.use_auth_http): def __init__(self, use_authentication=settings.use_auth_http):
AuthorizedBase.__init__(self) AuthorizedBase.__init__(self)
self._use_authentication = use_authentication self._use_authentication = use_authentication
self.announced_startup = False
self.allowed_during_startup = [] self.allowed_during_startup = []
self.sessions = {} self.sessions = {}
def setup(self): def setup(self):
return NotImplementedError() return NotImplementedError()
def render(self, request): def _render_error(self, failure, request, version=jsonrpclib.VERSION_1, response_code=FAILURE):
assert self._check_headers(request), InvalidHeaderError err = JSONRPCException(Failure(failure), response_code)
fault = jsonrpclib.dumps(err, version=version)
self._set_headers(request, fault)
if response_code != AuthJSONRPCServer.FAILURE:
request.setResponseCode(response_code)
request.write(fault)
request.finish()
def _log_and_render_error(self, failure, request, message=None, **kwargs):
msg = message or "API Failure: %s"
log_support.failure(Failure(failure), log, msg)
self._render_error(failure, request, **kwargs)
def render(self, request):
notify_finish = request.notifyFinish()
assert self._check_headers(request), InvalidHeaderError
session = request.getSession() session = request.getSession()
session_id = session.uid session_id = session.uid
if self._use_authentication: if self._use_authentication:
# if this is a new session, send a new secret and set the expiration, otherwise, session.touch() # if this is a new session, send a new secret and set the expiration
# otherwise, session.touch()
if self._initialize_session(session_id): if self._initialize_session(session_id):
def expire_session(): def expire_session():
self._unregister_user_session(session_id) self._unregister_user_session(session_id)
@ -115,8 +141,10 @@ class AuthJSONRPCServer(AuthorizedBase):
content = request.content.read() content = request.content.read()
try: try:
parsed = jsonrpclib.loads(content) parsed = jsonrpclib.loads(content)
except ValueError: except ValueError as err:
return server.failure log.warning("Unable to decode request json")
self._render_error(err, request)
return server.NOT_DONE_YET
function_name = parsed.get('method') function_name = parsed.get('method')
args = parsed.get('params') args = parsed.get('params')
@ -126,36 +154,38 @@ class AuthJSONRPCServer(AuthorizedBase):
try: try:
self._run_subhandlers(request) self._run_subhandlers(request)
except SubhandlerError: except SubhandlerError as err:
return server.failure self._render_error(err, request, version)
return server.NOT_DONE_YET
reply_with_next_secret = False reply_with_next_secret = False
if self._use_authentication: if self._use_authentication:
if function_name in self.authorized_functions: if function_name in self.authorized_functions:
try: try:
self._verify_token(session_id, parsed, token) self._verify_token(session_id, parsed, token)
except InvalidAuthenticationToken: except InvalidAuthenticationToken as err:
log.warning("API validation failed") log.warning("API validation failed")
request.setResponseCode(self.UNAUTHORIZED) self._render_error(err, request, version=version, response_code=AuthJSONRPCServer.UNAUTHORIZED)
request.finish()
return server.NOT_DONE_YET return server.NOT_DONE_YET
self._update_session_secret(session_id) self._update_session_secret(session_id)
reply_with_next_secret = True reply_with_next_secret = True
try: try:
function = self._get_jsonrpc_method(function_name) function = self._get_jsonrpc_method(function_name)
except Exception: except AttributeError as err:
log.warning("Unknown method: %s", function_name) log.warning("Unknown method: %s", function_name)
return server.failure self._render_error(err, request, version)
return server.NOT_DONE_YET
if args == [{}]:
d = defer.maybeDeferred(function)
else:
d = defer.maybeDeferred(function, *args)
d = defer.maybeDeferred(function) if args == [{}] else defer.maybeDeferred(function, *args)
# cancel the response if the connection is broken # cancel the response if the connection is broken
notify_finish = request.notifyFinish()
notify_finish.addErrback(self._response_failed, d) notify_finish.addErrback(self._response_failed, d)
d.addErrback(self._errback_render, id) d.addCallback(self._callback_render, request, version, reply_with_next_secret)
d.addCallback(self._callback_render, request, id, version, reply_with_next_secret) d.addErrback(self._log_and_render_error, request, version=version)
d.addErrback(notify_finish.errback)
return server.NOT_DONE_YET return server.NOT_DONE_YET
def _register_user_session(self, session_id): def _register_user_session(self, session_id):
@ -210,7 +240,8 @@ class AuthJSONRPCServer(AuthorizedBase):
return True return True
def _get_jsonrpc_method(self, function_path): def _get_jsonrpc_method(self, function_path):
assert self._check_function_path(function_path) if not self._check_function_path(function_path):
raise AttributeError(function_path)
return self.callable_methods.get(function_path) return self.callable_methods.get(function_path)
def _initialize_session(self, session_id): def _initialize_session(self, session_id):
@ -239,13 +270,10 @@ class AuthJSONRPCServer(AuthorizedBase):
def _run_subhandlers(self, request): def _run_subhandlers(self, request):
for handler in self.subhandlers: for handler in self.subhandlers:
try: if not handler(request):
assert handler(request) raise SubhandlerError("Subhandler error processing request: %s", request)
except Exception as err:
log.error(err.message)
raise SubhandlerError
def _callback_render(self, result, request, id, version, auth_required=False): def _callback_render(self, result, request, version, auth_required=False):
result_for_return = result if not isinstance(result, dict) else result['result'] result_for_return = result if not isinstance(result, dict) else result['result']
if version == jsonrpclib.VERSION_PRE1: if version == jsonrpclib.VERSION_PRE1:
@ -256,17 +284,9 @@ class AuthJSONRPCServer(AuthorizedBase):
encoded_message = jsonrpclib.dumps(result_for_return, version=version, default=default_decimal) encoded_message = jsonrpclib.dumps(result_for_return, version=version, default=default_decimal)
self._set_headers(request, encoded_message, auth_required) self._set_headers(request, encoded_message, auth_required)
self._render_message(request, encoded_message) self._render_message(request, encoded_message)
except: except Exception as err:
fault = jsonrpclib.Fault(self.FAILURE, "can't serialize output") msg = "Failed to render API response: %s"
encoded_message = jsonrpclib.dumps(fault, version=version) self._log_and_render_error(err, request, message=msg, version=version)
self._set_headers(request, encoded_message)
self._render_message(request, encoded_message)
def _errback_render(self, failure, id):
log_support.failure(failure, log, "Request failed. Id: %s, Failure: %s", id)
if isinstance(failure.value, jsonrpclib.Fault):
return failure.value
return server.failure
def _render_response(self, result, code): def _render_response(self, result, code):
return defer.succeed({'result': result, 'code': code}) return defer.succeed({'result': result, 'code': code})