forked from LBRYCommunity/lbry-sdk
Merge pull request #260 from lbryio/error-messages
meaningful error messages, improve cli, remove unused search from daemon
This commit is contained in:
commit
f65a50a6a3
7 changed files with 163 additions and 230 deletions
|
@ -163,7 +163,6 @@ class AdjustableSettings(Setting):
|
|||
self.check_ui_requirements = True
|
||||
self.local_ui_path = False
|
||||
self.api_port = 5279
|
||||
self.search_servers = ['lighthouse1.lbry.io:50005']
|
||||
self.data_rate = .0001 # points/megabyte
|
||||
self.min_info_rate = .02 # points/1000 infos
|
||||
self.min_valuable_info_rate = .05 # points/1000 infos
|
||||
|
|
|
@ -321,6 +321,7 @@ class KademliaProtocol(protocol.DatagramProtocol):
|
|||
except Exception, e:
|
||||
log.exception('Failed to cancel %s', self._callLaterList[key])
|
||||
del self._callLaterList[key]
|
||||
|
||||
# not sure why this is needed, but taking this out sometimes causes
|
||||
# exceptions.AttributeError: 'Port' object has no attribute 'socket'
|
||||
# to happen on shutdown
|
||||
|
|
|
@ -9,11 +9,11 @@ import sys
|
|||
import base58
|
||||
import requests
|
||||
import simplejson as json
|
||||
|
||||
from urllib2 import urlopen
|
||||
from appdirs import user_data_dir
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
|
||||
from twisted.web import server
|
||||
from twisted.internet import defer, threads, error, reactor, task
|
||||
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
|
||||
from lbryum.version import LBRYUM_VERSION as lbryum_version
|
||||
|
||||
from lbrynet import __version__ as lbrynet_version
|
||||
from lbrynet import conf
|
||||
from lbrynet.conf import settings as lbrynet_settings
|
||||
from lbrynet import conf, reflector, analytics
|
||||
from lbrynet.conf import LBRYCRD_WALLET, LBRYUM_WALLET, PTC_WALLET
|
||||
from lbrynet import analytics
|
||||
from lbrynet.metadata.Fee import FeeValidator
|
||||
from lbrynet.core import Platform
|
||||
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.metadata.Metadata import Metadata, verify_name_characters
|
||||
from lbrynet.lbryfile.client.EncryptedFileDownloader import EncryptedFileSaverFactory, EncryptedFileOpenerFactory
|
||||
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.Downloader import GetStream
|
||||
from lbrynet.lbrynet_daemon.Publisher import Publisher
|
||||
from lbrynet.lbrynet_daemon.ExchangeRateManager import ExchangeRateManager
|
||||
from lbrynet.lbrynet_daemon.Lighthouse import LighthouseClient
|
||||
from lbrynet.lbrynet_daemon.auth.server import AuthJSONRPCServer
|
||||
|
||||
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 import log_support, utils, Platform
|
||||
from lbrynet.core.StreamDescriptor import StreamDescriptorIdentifier, download_sd_blob, BlobStreamDescriptorReader
|
||||
from lbrynet.core.Session import Session
|
||||
from lbrynet.core.PTCWallet import PTCWallet
|
||||
from lbrynet.core.Wallet import LBRYcrdWallet, LBRYumWallet
|
||||
from lbrynet.lbryfilemanager.EncryptedFileManager import EncryptedFileManager
|
||||
from lbrynet.lbryfile.EncryptedFileMetadataManager import DBEncryptedFileMetadataManager, TempEncryptedFileMetadataManager
|
||||
from lbrynet import reflector
|
||||
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
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -209,52 +200,51 @@ class Daemon(AuthJSONRPCServer):
|
|||
"""
|
||||
|
||||
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)
|
||||
|
||||
self.allowed_during_startup = [
|
||||
'is_running', 'is_first_run',
|
||||
'get_time_behind_blockchain', 'stop',
|
||||
'daemon_status', 'get_start_notice',
|
||||
'version', 'get_search_servers'
|
||||
'version'
|
||||
]
|
||||
last_version = {'last_version': {'lbrynet': lbrynet_version, 'lbryum': lbryum_version}}
|
||||
lbrynet_settings.update(last_version)
|
||||
self.db_dir = lbrynet_settings.data_dir
|
||||
self.download_directory = lbrynet_settings.download_directory
|
||||
conf.settings.update(last_version)
|
||||
self.db_dir = conf.settings.data_dir
|
||||
self.download_directory = conf.settings.download_directory
|
||||
self.created_data_dir = False
|
||||
if not os.path.exists(self.db_dir):
|
||||
os.mkdir(self.db_dir)
|
||||
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")
|
||||
else:
|
||||
log.info("Using non-default blobfiles directory: %s", lbrynet_settings.BLOBFILES_DIR)
|
||||
self.blobfile_dir = lbrynet_settings.BLOBFILES_DIR
|
||||
log.info("Using non-default blobfiles directory: %s", conf.settings.BLOBFILES_DIR)
|
||||
self.blobfile_dir = conf.settings.BLOBFILES_DIR
|
||||
|
||||
self.run_on_startup = lbrynet_settings.run_on_startup
|
||||
self.data_rate = lbrynet_settings.data_rate
|
||||
self.max_key_fee = lbrynet_settings.max_key_fee
|
||||
self.max_upload = lbrynet_settings.max_upload
|
||||
self.max_download = lbrynet_settings.max_download
|
||||
self.upload_log = lbrynet_settings.upload_log
|
||||
self.search_timeout = lbrynet_settings.search_timeout
|
||||
self.download_timeout = lbrynet_settings.download_timeout
|
||||
self.max_search_results = lbrynet_settings.max_search_results
|
||||
self.run_reflector_server = lbrynet_settings.run_reflector_server
|
||||
self.wallet_type = lbrynet_settings.wallet
|
||||
self.delete_blobs_on_remove = lbrynet_settings.delete_blobs_on_remove
|
||||
self.peer_port = lbrynet_settings.peer_port
|
||||
self.reflector_port = lbrynet_settings.reflector_port
|
||||
self.dht_node_port = lbrynet_settings.dht_node_port
|
||||
self.use_upnp = lbrynet_settings.use_upnp
|
||||
self.start_lbrycrdd = lbrynet_settings.start_lbrycrdd
|
||||
self.cache_time = lbrynet_settings.cache_time
|
||||
self.startup_scripts = lbrynet_settings.startup_scripts
|
||||
self.run_on_startup = conf.settings.run_on_startup
|
||||
self.data_rate = conf.settings.data_rate
|
||||
self.max_key_fee = conf.settings.max_key_fee
|
||||
self.max_upload = conf.settings.max_upload
|
||||
self.max_download = conf.settings.max_download
|
||||
self.upload_log = conf.settings.upload_log
|
||||
self.search_timeout = conf.settings.search_timeout
|
||||
self.download_timeout = conf.settings.download_timeout
|
||||
self.max_search_results = conf.settings.max_search_results
|
||||
self.run_reflector_server = conf.settings.run_reflector_server
|
||||
self.wallet_type = conf.settings.wallet
|
||||
self.delete_blobs_on_remove = conf.settings.delete_blobs_on_remove
|
||||
self.peer_port = conf.settings.peer_port
|
||||
self.reflector_port = conf.settings.reflector_port
|
||||
self.dht_node_port = conf.settings.dht_node_port
|
||||
self.use_upnp = conf.settings.use_upnp
|
||||
self.start_lbrycrdd = conf.settings.start_lbrycrdd
|
||||
self.cache_time = conf.settings.cache_time
|
||||
self.startup_scripts = conf.settings.startup_scripts
|
||||
|
||||
self.startup_status = STARTUP_STAGES[0]
|
||||
self.startup_message = None
|
||||
self.announced_startup = False
|
||||
self.connected_to_internet = True
|
||||
self.connection_problem = None
|
||||
self.git_lbrynet_version = None
|
||||
|
@ -262,19 +252,19 @@ class Daemon(AuthJSONRPCServer):
|
|||
self.ui_version = None
|
||||
self.platform = 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.session = None
|
||||
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
|
||||
# possibly have the entire log upload functionality taken out
|
||||
# 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.analytics_manager = None
|
||||
self.analytics_manager = analytics_manager
|
||||
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_password = None
|
||||
|
@ -285,7 +275,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
self.name_cache = {}
|
||||
self.set_wallet_attributes()
|
||||
self.exchange_rate_manager = ExchangeRateManager()
|
||||
self.lighthouse_client = LighthouseClient()
|
||||
calls = {
|
||||
Checker.INTERNET_CONNECTION: LoopingCall(CheckInternetConnection(self)),
|
||||
Checker.VERSION: LoopingCall(CheckRemoteVersions(self)),
|
||||
|
@ -300,7 +289,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
self.blob_request_payment_rate_manager = None
|
||||
self.lbry_file_metadata_manager = None
|
||||
self.lbry_file_manager = None
|
||||
self.analytics_manager = analytics_manager
|
||||
|
||||
@AuthJSONRPCServer.subhandler
|
||||
def _exclude_lbrycrd_only_commands_from_lbryum_session(self, request):
|
||||
|
@ -377,7 +365,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
self.exchange_rate_manager.start()
|
||||
|
||||
d = defer.Deferred()
|
||||
if lbrynet_settings.host_ui:
|
||||
if conf.settings.host_ui:
|
||||
self.lbry_ui_manager.update_checker.start(1800, now=False)
|
||||
d.addCallback(lambda _: self.lbry_ui_manager.setup())
|
||||
d.addCallback(lambda _: self._initial_setup())
|
||||
|
@ -661,27 +649,27 @@ class Daemon(AuthJSONRPCServer):
|
|||
for key, setting_type in setting_types.iteritems():
|
||||
if key in settings:
|
||||
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):
|
||||
lbrynet_settings.update({key: settings[key]})
|
||||
conf.settings.update({key: settings[key]})
|
||||
else:
|
||||
try:
|
||||
converted = setting_type(settings[key])
|
||||
lbrynet_settings.update({key: converted})
|
||||
conf.settings.update({key: converted})
|
||||
except Exception as err:
|
||||
log.warning(err.message)
|
||||
log.warning("error converting setting '%s' to type %s", key, setting_type)
|
||||
|
||||
self.run_on_startup = lbrynet_settings.run_on_startup
|
||||
self.data_rate = lbrynet_settings.data_rate
|
||||
self.max_key_fee = lbrynet_settings.max_key_fee
|
||||
self.download_directory = lbrynet_settings.download_directory
|
||||
self.max_upload = lbrynet_settings.max_upload
|
||||
self.max_download = lbrynet_settings.max_download
|
||||
self.upload_log = lbrynet_settings.upload_log
|
||||
self.download_timeout = lbrynet_settings.download_timeout
|
||||
self.search_timeout = lbrynet_settings.search_timeout
|
||||
self.cache_time = lbrynet_settings.cache_time
|
||||
self.run_on_startup = conf.settings.run_on_startup
|
||||
self.data_rate = conf.settings.data_rate
|
||||
self.max_key_fee = conf.settings.max_key_fee
|
||||
self.download_directory = conf.settings.download_directory
|
||||
self.max_upload = conf.settings.max_upload
|
||||
self.max_download = conf.settings.max_download
|
||||
self.upload_log = conf.settings.upload_log
|
||||
self.download_timeout = conf.settings.download_timeout
|
||||
self.search_timeout = conf.settings.search_timeout
|
||||
self.cache_time = conf.settings.cache_time
|
||||
|
||||
return defer.succeed(True)
|
||||
|
||||
|
@ -738,7 +726,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
self.lbryid = lbryid
|
||||
|
||||
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))
|
||||
d = self.settings.save_lbryid(self.lbryid)
|
||||
return d
|
||||
|
@ -785,7 +773,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
def get_default_data_rate():
|
||||
d = self.settings.get_default_data_payment_rate()
|
||||
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
|
||||
|
||||
def get_wallet():
|
||||
|
@ -799,8 +787,8 @@ class Daemon(AuthJSONRPCServer):
|
|||
elif self.wallet_type == LBRYUM_WALLET:
|
||||
log.info("Using lbryum wallet")
|
||||
config = {'auto_connect': True}
|
||||
if lbrynet_settings.lbryum_wallet_dir:
|
||||
config['lbryum_path'] = lbrynet_settings.lbryum_wallet_dir
|
||||
if conf.settings.lbryum_wallet_dir:
|
||||
config['lbryum_path'] = conf.settings.lbryum_wallet_dir
|
||||
d = defer.succeed(LBRYumWallet(self.db_dir, config))
|
||||
elif self.wallet_type == PTC_WALLET:
|
||||
log.info("Using PTC wallet")
|
||||
|
@ -823,7 +811,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
def create_session(results):
|
||||
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,
|
||||
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'])
|
||||
self.startup_status = STARTUP_STAGES[2]
|
||||
|
||||
|
@ -845,7 +833,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
self.sd_identifier.add_stream_downloader_factory(EncryptedFileStreamType, file_opener_factory)
|
||||
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):
|
||||
if not r.called:
|
||||
r.callback(result)
|
||||
|
@ -866,7 +854,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
|
||||
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):
|
||||
"""
|
||||
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")
|
||||
remaining_scripts = [s for s in self.startup_scripts if 'run_once' not in s.keys()]
|
||||
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()
|
||||
|
||||
for script in startup_scripts:
|
||||
|
@ -1055,9 +1043,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
|
||||
return defer.succeed(None)
|
||||
|
||||
def _search(self, search):
|
||||
return self.lighthouse_client.search(search)
|
||||
|
||||
def jsonrpc_is_running(self):
|
||||
"""
|
||||
Check if lbrynet daemon is running
|
||||
|
@ -1218,7 +1203,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
"""
|
||||
|
||||
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
|
||||
def jsonrpc_set_settings(self, p):
|
||||
|
@ -1239,12 +1224,12 @@ class Daemon(AuthJSONRPCServer):
|
|||
"""
|
||||
|
||||
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.addErrback(lambda err: log.info(err.getTraceback()))
|
||||
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
|
||||
|
||||
|
@ -1556,42 +1541,6 @@ class Daemon(AuthJSONRPCServer):
|
|||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||
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
|
||||
def jsonrpc_delete_lbry_file(self, p):
|
||||
"""
|
||||
|
@ -2002,7 +1951,7 @@ class Daemon(AuthJSONRPCServer):
|
|||
sd blob, dict
|
||||
"""
|
||||
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.addCallbacks(
|
||||
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))
|
||||
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):
|
||||
"""
|
||||
Get mean blob availability
|
||||
|
@ -2365,7 +2302,7 @@ def get_darwin_lbrycrdd_path():
|
|||
|
||||
|
||||
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):
|
||||
self.daemon = daemon
|
||||
self.name = name
|
||||
|
@ -2668,7 +2605,7 @@ def handle_failure(err, msg):
|
|||
|
||||
|
||||
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
|
||||
log.info("Start reflector client")
|
||||
d = reactor.resolve(reflector_address)
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import sys
|
||||
import json
|
||||
import argparse
|
||||
|
||||
import json
|
||||
from lbrynet.conf import settings
|
||||
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: " \
|
||||
+ "lbrynet-cli resolve_name '{\"name\": \"what\"}'\n" \
|
||||
+ "lbrynet-cli resolve_name name=what\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"
|
||||
|
||||
|
||||
|
@ -59,14 +61,13 @@ def main():
|
|||
meth = args.method[0]
|
||||
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)
|
||||
elif len(args.params) == 1:
|
||||
try:
|
||||
params = json.loads(args.params[0])
|
||||
except ValueError:
|
||||
params = get_params_from_kwargs(args.params)
|
||||
|
||||
msg = help_msg
|
||||
for f in api.help():
|
||||
|
@ -83,14 +84,16 @@ def main():
|
|||
else:
|
||||
result = LBRYAPIClient.config(service=meth, params=params)
|
||||
print json.dumps(result, sort_keys=True)
|
||||
except:
|
||||
except RPCError as err:
|
||||
# TODO: The api should return proper error codes
|
||||
# and messages so that they can be passed along to the user
|
||||
# instead of this generic message.
|
||||
# https://app.asana.com/0/158602294500137/200173944358192
|
||||
|
||||
print "Something went wrong, here's the usage for %s:" % meth
|
||||
print api.help({'function': meth})
|
||||
print "Here's the traceback for the error you encountered:"
|
||||
print err.msg
|
||||
|
||||
else:
|
||||
print "Unknown function"
|
||||
print msg
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
|
@ -77,13 +76,10 @@ class GetStream(object):
|
|||
self.finished.callback((False, None, None))
|
||||
|
||||
def _convert_max_fee(self):
|
||||
if isinstance(self.max_key_fee, dict):
|
||||
max_fee = FeeValidator(self.max_key_fee)
|
||||
if max_fee.currency_symbol == "LBC":
|
||||
return max_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)
|
||||
max_fee = FeeValidator(self.max_key_fee)
|
||||
if max_fee.currency_symbol == "LBC":
|
||||
return max_fee.amount
|
||||
return self.exchange_rate_manager.to_lbc(self.max_key_fee).amount
|
||||
|
||||
def start(self, stream_info, name):
|
||||
def _cause_timeout(err):
|
||||
|
@ -117,14 +113,18 @@ class GetStream(object):
|
|||
if 'fee' in self.stream_info:
|
||||
self.fee = FeeValidator(self.stream_info['fee'])
|
||||
max_key_fee = self._convert_max_fee()
|
||||
if self.exchange_rate_manager.to_lbc(self.fee).amount > max_key_fee:
|
||||
log.info("Key fee %f above limit of %f didn't download lbry://%s" % (self.fee.amount,
|
||||
self.max_key_fee,
|
||||
self.resolved_name))
|
||||
converted_fee = self.exchange_rate_manager.to_lbc(self.fee).amount
|
||||
if converted_fee > self.wallet.get_balance():
|
||||
log.warning("Insufficient funds to download lbry://%s", 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())
|
||||
log.info("Key fee %s below limit of %f, downloading lbry://%s" % (json.dumps(self.fee),
|
||||
max_key_fee,
|
||||
self.resolved_name))
|
||||
log.info("Key fee %f below limit of %f, downloading lbry://%s", converted_fee,
|
||||
max_key_fee,
|
||||
self.resolved_name)
|
||||
|
||||
self.checker.start(1)
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -1,11 +1,11 @@
|
|||
import logging
|
||||
|
||||
from decimal import Decimal
|
||||
from zope.interface import implements
|
||||
from twisted.web import server, resource
|
||||
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.conf import settings
|
||||
from lbrynet.core import log_support
|
||||
|
@ -20,6 +20,16 @@ def default_decimal(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):
|
||||
def __init__(self):
|
||||
self.authorized_functions = []
|
||||
|
@ -85,20 +95,36 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
def __init__(self, use_authentication=settings.use_auth_http):
|
||||
AuthorizedBase.__init__(self)
|
||||
self._use_authentication = use_authentication
|
||||
self.announced_startup = False
|
||||
self.allowed_during_startup = []
|
||||
self.sessions = {}
|
||||
|
||||
def setup(self):
|
||||
return NotImplementedError()
|
||||
|
||||
def render(self, request):
|
||||
assert self._check_headers(request), InvalidHeaderError
|
||||
def _render_error(self, failure, request, version=jsonrpclib.VERSION_1, response_code=FAILURE):
|
||||
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_id = session.uid
|
||||
|
||||
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):
|
||||
def expire_session():
|
||||
self._unregister_user_session(session_id)
|
||||
|
@ -115,8 +141,10 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
content = request.content.read()
|
||||
try:
|
||||
parsed = jsonrpclib.loads(content)
|
||||
except ValueError:
|
||||
return server.failure
|
||||
except ValueError as err:
|
||||
log.warning("Unable to decode request json")
|
||||
self._render_error(err, request)
|
||||
return server.NOT_DONE_YET
|
||||
|
||||
function_name = parsed.get('method')
|
||||
args = parsed.get('params')
|
||||
|
@ -126,36 +154,38 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
|
||||
try:
|
||||
self._run_subhandlers(request)
|
||||
except SubhandlerError:
|
||||
return server.failure
|
||||
except SubhandlerError as err:
|
||||
self._render_error(err, request, version)
|
||||
return server.NOT_DONE_YET
|
||||
|
||||
reply_with_next_secret = False
|
||||
if self._use_authentication:
|
||||
if function_name in self.authorized_functions:
|
||||
try:
|
||||
self._verify_token(session_id, parsed, token)
|
||||
except InvalidAuthenticationToken:
|
||||
except InvalidAuthenticationToken as err:
|
||||
log.warning("API validation failed")
|
||||
request.setResponseCode(self.UNAUTHORIZED)
|
||||
request.finish()
|
||||
self._render_error(err, request, version=version, response_code=AuthJSONRPCServer.UNAUTHORIZED)
|
||||
return server.NOT_DONE_YET
|
||||
self._update_session_secret(session_id)
|
||||
reply_with_next_secret = True
|
||||
|
||||
try:
|
||||
function = self._get_jsonrpc_method(function_name)
|
||||
except Exception:
|
||||
except AttributeError as err:
|
||||
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
|
||||
notify_finish = request.notifyFinish()
|
||||
notify_finish.addErrback(self._response_failed, d)
|
||||
d.addErrback(self._errback_render, id)
|
||||
d.addCallback(self._callback_render, request, id, version, reply_with_next_secret)
|
||||
d.addErrback(notify_finish.errback)
|
||||
|
||||
d.addCallback(self._callback_render, request, version, reply_with_next_secret)
|
||||
d.addErrback(self._log_and_render_error, request, version=version)
|
||||
return server.NOT_DONE_YET
|
||||
|
||||
def _register_user_session(self, session_id):
|
||||
|
@ -210,7 +240,8 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
return True
|
||||
|
||||
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)
|
||||
|
||||
def _initialize_session(self, session_id):
|
||||
|
@ -239,13 +270,10 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
|
||||
def _run_subhandlers(self, request):
|
||||
for handler in self.subhandlers:
|
||||
try:
|
||||
assert handler(request)
|
||||
except Exception as err:
|
||||
log.error(err.message)
|
||||
raise SubhandlerError
|
||||
if not handler(request):
|
||||
raise SubhandlerError("Subhandler error processing request: %s", request)
|
||||
|
||||
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']
|
||||
|
||||
if version == jsonrpclib.VERSION_PRE1:
|
||||
|
@ -256,17 +284,9 @@ class AuthJSONRPCServer(AuthorizedBase):
|
|||
encoded_message = jsonrpclib.dumps(result_for_return, version=version, default=default_decimal)
|
||||
self._set_headers(request, encoded_message, auth_required)
|
||||
self._render_message(request, encoded_message)
|
||||
except:
|
||||
fault = jsonrpclib.Fault(self.FAILURE, "can't serialize output")
|
||||
encoded_message = jsonrpclib.dumps(fault, 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
|
||||
except Exception as err:
|
||||
msg = "Failed to render API response: %s"
|
||||
self._log_and_render_error(err, request, message=msg, version=version)
|
||||
|
||||
def _render_response(self, result, code):
|
||||
return defer.succeed({'result': result, 'code': code})
|
||||
|
|
Loading…
Reference in a new issue