Merge pull request #26 from lbryio/settings

merge in updates from settings branch
This commit is contained in:
Jack Robison 2016-04-11 23:19:40 -04:00
commit 32293ee3bb
10 changed files with 467 additions and 230 deletions

View file

@ -4,5 +4,5 @@ import logging
logging.getLogger(__name__).addHandler(logging.NullHandler())
version = (0, 2, 0)
version = (0, 2, 1)
__version__ = ".".join([str(x) for x in version])

View file

@ -365,7 +365,8 @@ class LBRYWallet(object):
value['content_license'] = content_license
if author is not None:
value['author'] = author
if sources is not None:
if isinstance(sources, dict):
sources['lbry_sd_hash'] = sd_hash
value['sources'] = sources
d = self._send_name_claim(name, json.dumps(value), amount)
@ -436,7 +437,8 @@ class LBRYWallet(object):
d.addCallback(set_first_run)
else:
d = defer.succeed(None)
d = defer.succeed(self._FIRST_RUN_YES if self._first_run else self._FIRST_RUN_NO)
d.addCallback(lambda _: self._first_run == self._FIRST_RUN_YES)
return d
@ -900,6 +902,7 @@ class LBRYumWallet(LBRYWallet):
self._start_check = None
self._catch_up_check = None
self._caught_up_counter = 0
self.blocks_behind_alert = 0
def _start(self):
@ -994,6 +997,7 @@ class LBRYumWallet(LBRYWallet):
if self._caught_up_counter == 0:
alert.info('Catching up to the blockchain...showing blocks left...')
if self._caught_up_counter % 30 == 0:
self.blocks_behind_alert = remote_height - local_height
alert.info('%d...', (remote_height - local_height))
self._caught_up_counter += 1
@ -1072,6 +1076,7 @@ class LBRYumWallet(LBRYWallet):
return decoded_tx
def _send_abandon(self, txid, address, amount):
log.info("Abandon " + str(txid) + " " + str(address) + " " + str(amount))
cmd = known_commands['abandonclaim']
func = getattr(self.cmd_runner, cmd.name)
d = threads.deferToThread(func, txid, address, amount)
@ -1079,6 +1084,7 @@ class LBRYumWallet(LBRYWallet):
return d
def _broadcast_transaction(self, raw_tx):
log.info("Broadcast: " + str(raw_tx))
cmd = known_commands['broadcast']
func = getattr(self.cmd_runner, cmd.name)
d = threads.deferToThread(func, raw_tx)

View file

@ -119,7 +119,7 @@ class ManagedLBRYFileDownloaderFactory(object):
def can_download(self, sd_validator):
return True
def make_downloader(self, metadata, options, payment_rate_manager):
def make_downloader(self, metadata, options, payment_rate_manager, download_directory=None):
data_rate = options[0]
upload_allowed = options[1]
@ -137,7 +137,8 @@ class ManagedLBRYFileDownloaderFactory(object):
d.addCallback(lambda stream_hash: self.lbry_file_manager.add_lbry_file(stream_hash,
payment_rate_manager,
data_rate,
upload_allowed))
upload_allowed,
download_directory=download_directory))
return d
@staticmethod

View file

@ -28,7 +28,7 @@ class LBRYFileManager(object):
Keeps track of currently opened LBRY Files, their options, and their LBRY File specific metadata.
"""
def __init__(self, session, stream_info_manager, sd_identifier, delete_data=False):
def __init__(self, session, stream_info_manager, sd_identifier, delete_data=False, download_directory=None):
self.session = session
self.stream_info_manager = stream_info_manager
self.sd_identifier = sd_identifier
@ -36,8 +36,8 @@ class LBRYFileManager(object):
self.sql_db = None
# self.delete_data = delete_data
# self.check_exists_loop = LoopingCall(self.check_files_exist)
if sys.platform.startswith("darwin"):
self.download_directory = os.path.join(os.path.expanduser("~"), 'Downloads')
if download_directory:
self.download_directory = download_directory
else:
self.download_directory = os.getcwd()
log.debug("Download directory for LBRYFileManager: %s", str(self.download_directory))
@ -122,7 +122,10 @@ class LBRYFileManager(object):
d.addCallback(start_lbry_files)
return d
def start_lbry_file(self, rowid, stream_hash, payment_rate_manager, blob_data_rate=None, upload_allowed=True):
def start_lbry_file(self, rowid, stream_hash, payment_rate_manager, blob_data_rate=None, upload_allowed=True,
download_directory=None):
if not download_directory:
download_directory = self.download_directory
payment_rate_manager.min_blob_data_payment_rate = blob_data_rate
lbry_file_downloader = ManagedLBRYFileDownloader(rowid, stream_hash,
self.session.peer_finder,
@ -130,17 +133,17 @@ class LBRYFileManager(object):
self.session.blob_manager,
self.stream_info_manager, self,
payment_rate_manager, self.session.wallet,
self.download_directory,
download_directory,
upload_allowed)
self.lbry_files.append(lbry_file_downloader)
d = lbry_file_downloader.set_stream_info()
d.addCallback(lambda _: lbry_file_downloader)
return d
def add_lbry_file(self, stream_hash, payment_rate_manager, blob_data_rate=None, upload_allowed=True):
def add_lbry_file(self, stream_hash, payment_rate_manager, blob_data_rate=None, upload_allowed=True, download_directory=None):
d = self._save_lbry_file(stream_hash, blob_data_rate)
d.addCallback(lambda rowid: self.start_lbry_file(rowid, stream_hash, payment_rate_manager,
blob_data_rate, upload_allowed))
blob_data_rate, upload_allowed, download_directory))
return d
def delete_lbry_file(self, lbry_file):

View file

@ -5,7 +5,12 @@ import simplejson as json
import binascii
import subprocess
import logging
import logging.handlers
import requests
import base64
import base58
import platform
import json
from twisted.web import server, resource, static
from twisted.internet import defer, threads, error, reactor
@ -15,11 +20,11 @@ from txjsonrpc.web.jsonrpc import Handler
from datetime import datetime
from decimal import Decimal
from StringIO import StringIO
from zipfile import ZipFile
from urllib import urlopen
from appdirs import user_data_dir
from urllib2 import urlopen
from lbrynet import __version__ as lbrynet_version
from lbryum.version import ELECTRUM_VERSION as lbryum_version
from lbrynet.core.PaymentRateManager import PaymentRateManager
from lbrynet.core.server.BlobAvailabilityHandler import BlobAvailabilityHandlerFactory
from lbrynet.core.server.BlobRequestHandler import BlobRequestHandlerFactory
@ -42,7 +47,30 @@ from lbrynet.core.LBRYcrdWallet import LBRYcrdWallet, LBRYumWallet
from lbrynet.lbryfilemanager.LBRYFileManager import LBRYFileManager
from lbrynet.lbryfile.LBRYFileMetadataManager import DBLBRYFileMetadataManager, TempLBRYFileMetadataManager
if sys.platform != "darwin":
log_dir = os.path.join(os.path.expanduser("~"), ".lbrynet")
else:
log_dir = user_data_dir("LBRY")
if not os.path.isdir(log_dir):
os.mkdir(log_dir)
LOG_FILENAME = os.path.join(log_dir, 'lbrynet-daemon.log')
log = logging.getLogger(__name__)
handler = logging.handlers.RotatingFileHandler(LOG_FILENAME, maxBytes=262144, backupCount=5)
log.addHandler(handler)
STARTUP_STAGES = [
('initializing', 'Initializing...'),
('loading_db', 'Loading databases...'),
('loading_wallet', 'Catching up with blockchain... %s'),
('loading_file_manager', 'Setting up file manager'),
('loading_server', 'Starting lbrynet'),
('started', 'Started lbrynet')
]
BAD_REQUEST = 400
NOT_FOUND = 404
@ -60,8 +88,92 @@ class LBRYDaemon(jsonrpc.JSONRPC):
"""
LBRYnet daemon, a jsonrpc interface to lbry functions
"""
isLeaf = True
def __init__(self, wallet_type, check_for_updates, ui_version_info):
jsonrpc.JSONRPC.__init__(self)
reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown)
self.log_file = LOG_FILENAME
self.fetcher = None
self.current_db_revision = 1
self.run_server = True
self.session = None
self.known_dht_nodes = KNOWN_DHT_NODES
if sys.platform != "darwin":
self.db_dir = os.path.join(os.path.expanduser("~"), ".lbrynet")
else:
self.db_dir = user_data_dir("LBRY")
self.blobfile_dir = os.path.join(self.db_dir, "blobfiles")
self.peer_port = 3333
self.dht_node_port = 4444
self.first_run = None
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")
elif sys.platform == "darwin":
self.download_directory = os.path.join(os.path.expanduser("~"), 'Downloads')
if wallet_type == "lbrycrd":
self.wallet_dir = user_data_dir("lbrycrd")
else:
self.wallet_dir = user_data_dir("LBRY")
else:
self.download_directory = os.getcwd()
if wallet_type == "lbrycrd":
self.wallet_dir = os.path.join(os.path.expanduser("~"), ".lbrycrd")
else:
self.wallet_dir = os.path.join(os.path.expanduser("~"), ".lbryum")
self.daemon_conf = os.path.join(self.db_dir, 'daemon_settings.json')
self.wallet_conf = os.path.join(self.wallet_dir, "lbrycrd.conf")
self.wallet_user = None
self.wallet_password = None
self.sd_identifier = StreamDescriptorIdentifier()
self.stream_info_manager = TempLBRYFileMetadataManager()
self.wallet_rpc_port = 8332
self.downloads = []
self.stream_frames = []
self.default_blob_data_payment_rate = MIN_BLOB_DATA_PAYMENT_RATE
self.use_upnp = True
self.start_lbrycrdd = True
if os.name == "nt":
self.lbrycrdd_path = "lbrycrdd.exe"
else:
self.lbrycrdd_path = "./lbrycrdd"
self.delete_blobs_on_remove = True
self.blob_request_payment_rate_manager = None
self.lbry_file_metadata_manager = None
self.lbry_file_manager = None
self.settings = LBRYSettings(self.db_dir)
self.wallet_type = wallet_type
self.check_for_updates = check_for_updates
self.lbrycrd_conf = os.path.join(self.wallet_dir, "lbrycrd.conf")
self.autofetcher_conf = os.path.join(self.wallet_dir, "autofetcher.conf")
self.created_data_dir = False
if not os.path.exists(self.db_dir):
os.mkdir(self.db_dir)
self.created_data_dir = True
self.session_settings = None
self.data_rate = MIN_BLOB_DATA_PAYMENT_RATE
self.max_key_fee = DEFAULT_MAX_KEY_FEE
self.max_search_results = DEFAULT_MAX_SEARCH_RESULTS
self.startup_status = STARTUP_STAGES[0]
self.startup_message = None
self.announced_startup = False
self.search_timeout = 3.0
self.query_handlers = {}
self.default_settings = {
'run_on_startup': False,
'data_rate': MIN_BLOB_DATA_PAYMENT_RATE,
'max_key_fee': 10.0,
'default_download_directory': self.download_directory,
'max_upload': 0.0,
'max_download': 0.0,
'upload_log': True
}
self.ui_version = ui_version_info.replace('\n', '')
def render(self, request):
request.content.seek(0, 0)
# Unmarshal the JSON-RPC data.
@ -69,6 +181,9 @@ class LBRYDaemon(jsonrpc.JSONRPC):
parsed = jsonrpclib.loads(content)
functionPath = parsed.get("method")
args = parsed.get('params')
#TODO convert args to correct types if possible
id = parsed.get('id')
version = parsed.get('jsonrpc')
if version:
@ -81,7 +196,10 @@ class LBRYDaemon(jsonrpc.JSONRPC):
# versions...
if not self.announced_startup:
if functionPath != 'is_running':
if functionPath not in ['is_running', 'is_first_run',
'get_time_behind_blockchain', 'stop',
'daemon_status', 'get_start_notice',
'version', 'check_for_new_version']:
return server.failure
try:
@ -125,101 +243,42 @@ class LBRYDaemon(jsonrpc.JSONRPC):
log.error(failure)
return jsonrpclib.Fault(self.FAILURE, "error")
def setup(self, wallet_type, check_for_updates):
def _set_vars(wallet_type, check_for_updates):
reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown)
def setup(self):
def _log_starting_vals():
def _get_lbry_files_json():
r = []
for f in self.lbry_file_manager.lbry_files:
if f.key:
t = {'completed': f.completed, 'file_name': f.file_name, 'key': binascii.b2a_hex(f.key),
'points_paid': f.points_paid, 'stopped': f.stopped, 'stream_hash': f.stream_hash,
'stream_name': f.stream_name, 'suggested_file_name': f.suggested_file_name,
'upload_allowed': f.upload_allowed}
self.fetcher = None
self.current_db_revision = 1
self.run_server = True
self.session = None
self.known_dht_nodes = KNOWN_DHT_NODES
if sys.platform != "darwin":
self.db_dir = os.path.join(os.path.expanduser("~"), ".lbrynet")
else:
self.db_dir = user_data_dir("LBRY")
# self.db_dir = os.path.join(os.path.expanduser("~"), "Library/Application Support/lbrynet")
self.blobfile_dir = os.path.join(self.db_dir, "blobfiles")
self.peer_port = 3333
self.dht_node_port = 4444
self.first_run = False
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")
elif sys.platform == "darwin":
self.download_directory = os.path.join(os.path.expanduser("~"), 'Downloads')
if wallet_type == "lbrycrd":
self.wallet_dir = user_data_dir("lbrycrd")
else:
self.wallet_dir = user_data_dir("LBRY")
else:
if wallet_type == "lbrycrd":
self.wallet_dir = os.path.join(os.path.expanduser("~"), ".lbrycrd")
else:
self.wallet_dir = os.path.join(os.path.expanduser("~"), ".lbryum")
self.download_directory = os.getcwd()
self.daemon_conf = os.path.join(self.wallet_dir, 'daemon_settings.conf')
self.wallet_conf = os.path.join(self.wallet_dir, "lbrycrd.conf")
self.wallet_user = None
self.wallet_password = None
self.sd_identifier = StreamDescriptorIdentifier()
self.stream_info_manager = TempLBRYFileMetadataManager()
self.wallet_rpc_port = 8332
self.downloads = []
self.stream_frames = []
self.default_blob_data_payment_rate = MIN_BLOB_DATA_PAYMENT_RATE
self.use_upnp = True
self.start_lbrycrdd = True
if os.name == "nt":
self.lbrycrdd_path = "lbrycrdd.exe"
else:
self.lbrycrdd_path = "./lbrycrdd"
self.delete_blobs_on_remove = True
self.blob_request_payment_rate_manager = None
self.lbry_file_metadata_manager = None
self.lbry_file_manager = None
self.settings = LBRYSettings(self.db_dir)
self.wallet_type = wallet_type
self.check_for_updates = check_for_updates
self.lbrycrd_conf = os.path.join(self.wallet_dir, "lbrycrd.conf")
self.autofetcher_conf = os.path.join(self.wallet_dir, "autofetcher.conf")
self.created_data_dir = False
if not os.path.exists(self.db_dir):
os.mkdir(self.db_dir)
self.created_data_dir = True
self.session_settings = None
self.data_rate = MIN_BLOB_DATA_PAYMENT_RATE
self.max_key_fee = DEFAULT_MAX_KEY_FEE
self.max_search_results = DEFAULT_MAX_SEARCH_RESULTS
self.startup_message = ""
self.announced_startup = False
self.search_timeout = 3.0
self.query_handlers = {}
self.default_settings = {
'run_on_startup': False,
'data_rate': MIN_BLOB_DATA_PAYMENT_RATE,
'max_key_fee': 10.0,
'default_download_directory': self.download_directory,
'max_upload': 0.0,
'max_download': 0.0
}
else:
t = {'completed': f.completed, 'file_name': f.file_name, 'key': None,
'points_paid': f.points_paid,
'stopped': f.stopped, 'stream_hash': f.stream_hash, 'stream_name': f.stream_name,
'suggested_file_name': f.suggested_file_name, 'upload_allowed': f.upload_allowed}
r.append(t)
return json.dumps(r)
log.info("LBRY Files: " + _get_lbry_files_json())
log.info("Starting balance: " + str(self.session.wallet.wallet_balance))
return defer.succeed(None)
def _announce_startup():
self.announced_startup = True
return defer.succeed(None)
def _disp_startup():
self.startup_status = STARTUP_STAGES[5]
log.info("[" + str(datetime.now()) + "] Started lbrynet-daemon")
return defer.succeed(None)
log.info("[" + str(datetime.now()) + "] Starting lbrynet-daemon")
d = defer.Deferred()
d.addCallback(lambda _:_set_vars(wallet_type, check_for_updates))
d.addCallback(lambda _: self._setup_daemon_settings())
d.addCallback(lambda _: self._initial_setup())
d.addCallback(self._set_daemon_settings)
d.addCallback(lambda _: threads.deferToThread(self._setup_data_directory))
d.addCallback(lambda _: self._check_db_migration())
d.addCallback(lambda _: self._get_settings())
@ -232,17 +291,47 @@ class LBRYDaemon(jsonrpc.JSONRPC):
d.addCallback(lambda _: self._setup_query_handlers())
d.addCallback(lambda _: self._setup_server())
d.addCallback(lambda _: self._setup_fetcher())
d.addCallback(lambda _: _log_starting_vals())
d.addCallback(lambda _: _announce_startup())
d.addCallback(lambda _: _disp_startup())
d.callback(None)
return defer.succeed(None)
def _initial_setup(self):
return defer.fail(NotImplementedError())
def _log_platform():
msg = {
"processor": platform.processor(),
"python version: ": platform.python_version(),
"lbrynet version: ": lbrynet_version,
"lbryum version: ": lbryum_version,
"ui_version": self.ui_version,
# 'ip': json.load(urlopen('http://jsonip.com'))['ip'],
}
if sys.platform == "darwin":
msg['osx version'] = platform.mac_ver()[0] + " " + platform.mac_ver()[2]
else:
msg['platform'] = platform.platform()
def _setup_daemon_settings(self):
self.session_settings = self.default_settings
log.info("Platform: " + json.dumps(msg))
return defer.succeed(None)
def _load_daemon_conf():
if os.path.isfile(self.daemon_conf):
return json.loads(open(self.daemon_conf, "r").read())
else:
log.info("Writing default settings : " + json.dumps(self.default_settings) + " --> " + str(self.daemon_conf))
f = open(self.daemon_conf, "w")
f.write(json.dumps(self.default_settings))
f.close()
return self.default_settings
d = _log_platform()
d.addCallback(lambda _: _load_daemon_conf())
return d
def _set_daemon_settings(self, settings):
self.session_settings = settings
return defer.succeed(None)
def _start_server(self):
@ -274,6 +363,8 @@ class LBRYDaemon(jsonrpc.JSONRPC):
return self._start_server()
return defer.succeed(True)
self.startup_status = STARTUP_STAGES[4]
dl = self.settings.get_server_running_status()
dl.addCallback(restore_running_status)
return dl
@ -317,33 +408,80 @@ class LBRYDaemon(jsonrpc.JSONRPC):
dl.addCallback(_set_query_handlers)
return dl
def _upload_log(self):
if self.session_settings['upload_log']:
LOG_URL = "https://lbry.io/log-upload"
f = open(self.log_file, "r")
t = datetime.now()
log_name = base58.b58encode(self.lbryid)[:20] + "-" + str(t.month) + "-" + str(t.day) + "-" + str(t.year) + "-" + str(t.hour) + "-" + str(t.minute)
params = {'name': log_name, 'log': f.read()}
f.close()
requests.post(LOG_URL, params)
return defer.succeed(None)
def _shutdown(self):
log.info("Closing lbrynet session")
d = self._stop_server()
d = self._upload_log()
d.addCallback(lambda _: self._stop_server())
d.addErrback(lambda err: log.info("Bad server shutdown: " + err.getTraceback()))
if self.session is not None:
d.addCallback(lambda _: self.session.shut_down())
d.addErrback(lambda err: log.info("Bad session shutdown: " + err.getTraceback()))
return d
def _update_settings(self, settings):
if not isinstance(settings['run_on_startup'], bool):
return defer.fail()
elif not isinstance(settings['data_rate'], float):
return defer.fail()
elif not isinstance(settings['max_key_fee'], float):
return defer.fail()
elif not isinstance(settings['default_download_directory'], unicode):
return defer.fail()
elif not isinstance(settings['max_upload'], float):
return defer.fail()
elif not isinstance(settings['max_download'], float):
return defer.fail()
for k in settings.keys():
if k == 'run_on_startup':
if type(settings['run_on_startup']) is bool:
self.session_settings['run_on_startup'] = settings['run_on_startup']
else:
return defer.fail()
elif k == 'data_rate':
if type(settings['data_rate']) is float:
self.session_settings['data_rate'] = settings['data_rate']
elif type(settings['data_rate']) is int:
self.session_settings['data_rate'] = float(settings['data_rate'])
else:
return defer.fail()
elif k == 'max_key_fee':
if type(settings['max_key_fee']) is float:
self.session_settings['max_key_fee'] = settings['max_key_fee']
elif type(settings['max_key_fee']) is int:
self.session_settings['max_key_fee'] = float(settings['max_key_fee'])
else:
return defer.fail()
elif k == 'default_download_directory':
if type(settings['default_download_directory']) is unicode:
if os.path.isdir(settings['default_download_directory']):
self.session_settings['default_download_directory'] = settings['default_download_directory']
else:
pass
else:
return defer.fail()
elif k == 'max_upload':
if type(settings['max_upload']) is float:
self.session_settings['max_upload'] = settings['max_upload']
elif type(settings['max_upload']) is int:
self.session_settings['max_upload'] = float(settings['max_upload'])
else:
return defer.fail()
elif k == 'max_download':
if type(settings['max_download']) is float:
self.session_settings['max_download'] = settings['max_download']
if type(settings['max_download']) is int:
self.session_settings['max_download'] = float(settings['max_download'])
else:
return defer.fail()
elif k == 'upload_log':
if type(settings['upload_log']) is bool:
self.session_settings['upload_log'] = settings['upload_log']
else:
return defer.fail()
self.session_settings['run_on_startup'] = settings['run_on_startup']
self.session_settings['data_rate'] = settings['data_rate']
self.session_settings['max_key_fee'] = settings['max_key_fee']
self.session_settings['default_download_directory'] = settings['default_download_directory']
self.session_settings['max_upload'] = settings['max_upload']
self.session_settings['max_download'] = settings['max_download']
f = open(self.daemon_conf, "w")
f.write(json.dumps(self.session_settings))
f.close()
return defer.succeed(True)
@ -353,6 +491,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
return defer.succeed(None)
def _setup_data_directory(self):
self.startup_status = STARTUP_STAGES[1]
log.info("Loading databases...")
if self.created_data_dir:
db_revision = open(os.path.join(self.db_dir, "db_revision"), mode='w')
@ -398,14 +537,17 @@ class LBRYDaemon(jsonrpc.JSONRPC):
if lbryid is None:
return self._make_lbryid()
else:
log.info("LBRY ID: " + base58.b58encode(lbryid))
self.lbryid = lbryid
def _make_lbryid(self):
self.lbryid = generate_id()
log.info("Generated new LBRY ID: " + base58.b58encode(self.lbryid))
d = self.settings.save_lbryid(self.lbryid)
return d
def _setup_lbry_file_manager(self):
self.startup_status = STARTUP_STAGES[3]
self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir)
d = self.lbry_file_metadata_manager.setup()
@ -464,6 +606,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
blob_dir=self.blobfile_dir, dht_node_port=self.dht_node_port,
known_dht_nodes=self.known_dht_nodes, peer_port=self.peer_port,
use_upnp=self.use_upnp, wallet=results['wallet'])
self.startup_status = STARTUP_STAGES[2]
dl = defer.DeferredList([d1, d2], fireOnOneErrback=True)
dl.addCallback(combine_results)
@ -474,14 +617,22 @@ class LBRYDaemon(jsonrpc.JSONRPC):
return dl
def _check_first_run(self):
def _set_first_run_false():
log.info("Not first run")
self.first_run = False
return 0.0
d = self.session.wallet.is_first_run()
d.addCallback(lambda is_first_run: self._do_first_run() if is_first_run else 0.0)
d.addCallback(lambda is_first_run: self._do_first_run() if is_first_run else _set_first_run_false())
return d
def _do_first_run(self):
self.first_run = True
d = self.session.wallet.get_new_address()
def send_request(url, data):
log.info("Requesting first run credits")
r = requests.post(url, json=data)
if r.status_code == 200:
return r.json()['credits_sent']
@ -506,7 +657,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
points_string = locale.format_string("%.2f LBC", (round(credits_received, 2),), grouping=True)
self.startup_message = "Thank you for testing the alpha version of 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." % points_string
else:
self.startup_message = "Connected to LBRYnet"
self.startup_message = None
def _get_lbrycrdd_path(self):
def get_lbrycrdd_path_conf_file():
@ -530,7 +681,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
def _setup_stream_identifier(self):
file_saver_factory = LBRYFileSaverFactory(self.session.peer_finder, self.session.rate_limiter,
self.session.blob_manager, self.stream_info_manager,
self.session.wallet, self.download_directory)
self.session.wallet, self.session_settings['default_download_directory'])
self.sd_identifier.add_stream_downloader_factory(LBRYFileStreamType, file_saver_factory)
file_opener_factory = LBRYFileOpenerFactory(self.session.peer_finder, self.session.rate_limiter,
self.session.blob_manager, self.stream_info_manager,
@ -546,9 +697,14 @@ class LBRYDaemon(jsonrpc.JSONRPC):
self.sd_identifier.add_stream_downloader_factory(LBRYFileStreamType, downloader_factory)
return defer.succeed(True)
def _download_name(self, name, timeout=DEFAULT_TIMEOUT):
def _download_name(self, name, timeout=DEFAULT_TIMEOUT, download_directory=None):
if not download_directory:
download_directory = self.session_settings['default_download_directory']
elif not os.path.isdir(download_directory):
download_directory = self.session_settings['default_download_directory']
def _disp_file(f):
file_path = os.path.join(self.download_directory, f.file_name)
file_path = os.path.join(self.session_settings['default_download_directory'], f.file_name)
log.info("[" + str(datetime.now()) + "] Already downloaded: " + str(f.stream_hash) + " --> " + file_path)
return defer.succeed(f)
@ -563,7 +719,8 @@ class LBRYDaemon(jsonrpc.JSONRPC):
d = self.session.wallet.get_stream_info_for_name(name)
stream = GetStream(self.sd_identifier, self.session, self.session.wallet, self.lbry_file_manager,
max_key_fee=self.max_key_fee, data_rate=self.data_rate, timeout=timeout)
max_key_fee=self.max_key_fee, data_rate=self.data_rate, timeout=timeout,
download_directory=download_directory)
d.addCallback(_disp)
d.addCallback(lambda stream_info: stream.start(stream_info))
d.addCallback(lambda _: self._path_from_name(name))
@ -603,7 +760,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
for lbry_file in self.lbry_file_manager.lbry_files:
if lbry_file.stream_name == file_name:
if sys.platform == "darwin":
if os.path.isfile(os.path.join(self.download_directory, lbry_file.stream_name)):
if os.path.isfile(os.path.join(self.session_settings['default_download_directory'], lbry_file.stream_name)):
return lbry_file
else:
return False
@ -644,8 +801,8 @@ class LBRYDaemon(jsonrpc.JSONRPC):
d = self.lbry_file_manager.get_count_for_stream_hash(s_h)
# TODO: could possibly be a timing issue here
d.addCallback(lambda c: self.stream_info_manager.delete_stream(s_h) if c == 0 else True)
d.addCallback(lambda _: os.remove(os.path.join(self.download_directory, lbry_file.file_name)) if
os.path.isfile(os.path.join(self.download_directory, lbry_file.file_name)) else defer.succeed(None))
d.addCallback(lambda _: os.remove(os.path.join(self.session_settings['default_download_directory'], lbry_file.file_name)) if
os.path.isfile(os.path.join(self.session_settings['default_download_directory'], lbry_file.file_name)) else defer.succeed(None))
return d
d.addCallback(lambda _: finish_deletion(lbry_file))
@ -654,14 +811,14 @@ class LBRYDaemon(jsonrpc.JSONRPC):
def _path_from_name(self, name):
d = self._check_history(name)
d.addCallback(lambda lbry_file: {'stream_hash': lbry_file.stream_hash,
'path': os.path.join(self.download_directory, lbry_file.file_name)}
'path': os.path.join(self.session_settings['default_download_directory'], lbry_file.file_name)}
if lbry_file else defer.fail(UnknownNameError))
return d
def _path_from_lbry_file(self, lbry_file):
if lbry_file:
r = {'stream_hash': lbry_file.stream_hash,
'path': os.path.join(self.download_directory, lbry_file.file_name)}
'path': os.path.join(self.session_settings['default_download_directory'], lbry_file.file_name)}
return defer.succeed(r)
else:
return defer.fail(UnknownNameError)
@ -697,21 +854,76 @@ class LBRYDaemon(jsonrpc.JSONRPC):
def _render_response(self, result, code):
return defer.succeed({'result': result, 'code': code})
# def _log_to_slack(self, msg):
# URL = "https://hooks.slack.com/services/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"
# h = httplib2.Http()
# h.request(URL, 'POST', json.dumps({"text": msg}), headers={'Content-Type': 'application/json'})
def jsonrpc_is_running(self):
"""
Returns true if daemon completed startup, otherwise returns false
"""
log.info("[" + str(datetime.now()) + "] is_running: " + str(self.announced_startup))
if self.announced_startup:
return self._render_response(True, OK_CODE)
else:
return self._render_response(False, OK_CODE)
def jsonrpc_daemon_status(self):
"""
Returns {'status_message': startup status message, 'status_code': status_code}
"""
r = {'status_code': self.startup_status[0], 'status_message': self.startup_status[1]}
try:
if self.startup_status[0] == 'loading_wallet':
r['status_message'] = r['status_message'] % (str(self.session.wallet.blocks_behind_alert) + " blocks behind")
except:
pass
log.info("[" + str(datetime.now()) + "] daemon status: " + str(r))
return self._render_response(r, OK_CODE)
def jsonrpc_is_first_run(self):
"""
Get True/False if can be determined, if wallet still is being set up returns None
"""
log.info("[" + str(datetime.now()) + "] Check if is first run")
try:
d = self.session.wallet.is_first_run()
except:
d = defer.fail(None)
d.addCallbacks(lambda r: self._render_response(r, OK_CODE), lambda _: self._render_response(None, OK_CODE))
return d
def jsonrpc_get_start_notice(self):
"""
Get any special message to be displayed at startup, such as a first run notice
"""
log.info("[" + str(datetime.now()) + "] Get startup notice")
if self.first_run and not self.session.wallet.wallet_balance:
return self._render_response(self.startup_message, OK_CODE)
elif self.first_run:
return self._render_response(None, OK_CODE)
else:
self._render_response(self.startup_message, OK_CODE)
def jsonrpc_version(self):
"""
Get lbry version information
"""
msg = {
"lbrynet version: ": lbrynet_version,
"lbryum version: ": lbryum_version,
"ui_version": self.ui_version,
}
log.info("[" + str(datetime.now()) + "] Get version info: " + json.dumps(msg))
return self._render_response(msg, OK_CODE)
def jsonrpc_get_settings(self):
"""
Get LBRY payment settings
@ -733,10 +945,14 @@ class LBRYDaemon(jsonrpc.JSONRPC):
'max_download': float (0.0 for unlimited)}
"""
d = self._update_settings(p)
def _log_settings_change(params):
log.info("[" + str(datetime.now()) + "] Set daemon settings to " + str(params))
log.info("[" + str(datetime.now()) + "] Set daemon settings")
return self._render_response(True, OK_CODE)
d = self._update_settings(p)
d.addCallback(lambda _: _log_settings_change(p))
d.addCallback(lambda _: self._render_response(self.session_settings, OK_CODE))
return d
def jsonrpc_start_fetcher(self):
"""
@ -849,16 +1065,23 @@ class LBRYDaemon(jsonrpc.JSONRPC):
"""
Download stream from a LBRY uri
@param: name
@param: name, optional: download_directory
@return: {'stream_hash': hex string, 'path': path of download}
"""
params = Bunch(p)
if 'timeout' not in p.keys():
params.timeout = DEFAULT_TIMEOUT
timeout = DEFAULT_TIMEOUT
else:
timeout = p['timeout']
if params.name:
d = self._download_name(params.name, timeout=params.timeout)
if 'download_directory' not in p.keys():
download_directory = self.session_settings['default_download_directory']
else:
download_directory = p['download_directory']
if 'name' in p.keys():
name = p['name']
d = self._download_name(name=name, timeout=timeout, download_directory=download_directory)
d.addCallbacks(lambda message: self._render_response(message, OK_CODE),
lambda err: self._render_response('error', NOT_FOUND))
else:
@ -961,18 +1184,16 @@ class LBRYDaemon(jsonrpc.JSONRPC):
@return: confirmation message
"""
params = Bunch(p)
def _disp(file_name):
log.info("[" + str(datetime.now()) + "] Deleted: " + file_name)
return self._render_response("Deleted: " + file_name, OK_CODE)
lbry_files = [self._delete_lbry_file(f) for f in self.lbry_file_manager.lbry_files
if str(params.file_name) == str(f.file_name)]
d = defer.DeferredList(lbry_files)
d.addCallback(lambda _: _disp(params.file_name))
return d
if "file_name" in p.keys():
lbry_files = [self._delete_lbry_file(f) for f in self.lbry_file_manager.lbry_files
if p['file_name'] == f.file_name]
d = defer.DeferredList(lbry_files)
d.addCallback(lambda _: _disp(p['file_name']))
return d
def jsonrpc_publish(self, p):
"""
@ -1018,14 +1239,13 @@ class LBRYDaemon(jsonrpc.JSONRPC):
"""
params = Bunch(p)
def _disp(txid, tx):
log.info("[" + str(datetime.now()) + "] Abandoned name claim tx " + txid)
return self._render_response(txid, OK_CODE)
def _disp(x):
log.info("[" + str(datetime.now()) + "] Abandoned name claim tx " + str(x))
return self._render_response(x, OK_CODE)
d = defer.Deferred()
d.addCallback(lambda _: self.session.wallet.abandon_name(params.txid))
d.addCallback(lambda tx: _disp(params.txid, tx))
d.addErrback(lambda err: self._render_response(err.getTraceback(), BAD_REQUEST))
d.addCallback(_disp)
d.callback(None)
return d
@ -1055,10 +1275,17 @@ class LBRYDaemon(jsonrpc.JSONRPC):
@return: time behind blockchain
"""
d = self.session.wallet.get_most_recent_blocktime()
d.addCallback(get_time_behind_blockchain)
d.addCallbacks(lambda result: self._render_response(str(result), OK_CODE),
lambda result: self._render_response(result, BAD_REQUEST))
def _get_time_behind():
try:
local_height = self.session.wallet.network.get_local_height()
remote_height = self.session.wallet.network.get_server_height()
return defer.succeed(remote_height - local_height)
except:
return defer.fail()
d = _get_time_behind()
d.addCallback(lambda r: self._render_response(r, OK_CODE))
return d
@ -1106,45 +1333,23 @@ class LBRYDaemon(jsonrpc.JSONRPC):
return self._render_response(self.fetcher.verbose, OK_CODE)
def jsonrpc_check_for_new_version(self):
def _check_for_updates(package):
git_version = subprocess.check_output("git ls-remote " + package['git'] + " | grep HEAD | cut -f 1", shell=True)
up_to_date = False
if os.path.isfile(package['version_file']):
f = open(package['version_file'], 'r')
current_version = f.read()
f.close()
def _get_lbryum_version():
r = urlopen("https://rawgit.com/lbryio/lbryum/master/lib/version.py").read().split('\n')
version = next(line.split("=")[1].split("#")[0].replace(" ", "")
for line in r if "ELECTRUM_VERSION" in line)
version = version.replace("'", "")
return version
if git_version == current_version:
r = package['name'] + " is up to date"
up_to_date = True
else:
r = package['name'] + " version is out of date"
else:
r = "Unknown version of " + package['name']
def _get_lbrynet_version():
r = urlopen("https://rawgit.com/lbryio/lbry/master/lbrynet/__init__.py").read().split('\n')
vs = next(i for i in r if 'version =' in i).split("=")[1].replace(" ", "")
vt = tuple(int(x) for x in vs[1:-1].split(','))
return ".".join([str(x) for x in vt])
return (up_to_date, r)
package_infos = {
"lbrynet": {"name": "LBRYnet",
"git": "https://github.com/lbryio/lbry.git",
"version_file": os.path.join(self.db_dir, ".lbrynet_version"),
"clone": ".lbrygit",
},
"lbryum": {"name": "lbryum",
"git": "https://github.com/lbryio/lbryum.git",
"version_file": os.path.join(self.db_dir, ".lbryum_version"),
"clone": ".lbryumgit",
},
"lbry": {"name": "LBRY",
"git": "https://github.com/jackrobison/lbrynet-app.git",
"version_file": os.path.join(self.db_dir, ".lbry_app_version"),
"clone": None,
},
}
r = [_check_for_updates(package_infos[p]) for p in package_infos.keys()]
log.info("[" + str(datetime.now()) + "] Check for new version: " + json.dumps(r))
return self._render_response(r, OK_CODE)
if (lbrynet_version >= _get_lbrynet_version()) and (lbryum_version >= _get_lbryum_version()):
return self._render_response(False, OK_CODE)
else:
return self._render_response(True, OK_CODE)
def jsonrpc___dir__(self):
return ['is_running', 'get_settings', 'set_settings', 'start_fetcher', 'stop_fetcher', 'fetcher_status',
@ -1197,4 +1402,4 @@ class LBRYFileRender(resource.Resource):
return server.NOT_DONE_YET
else:
return server.failure
return server.failure

View file

@ -1,5 +1,6 @@
import argparse
import logging
import logging.handlers
import subprocess
import os
import shutil
@ -18,7 +19,19 @@ from jsonrpc.proxy import JSONRPCProxy
from lbrynet.lbrynet_daemon.LBRYDaemon import LBRYDaemon, LBRYindex, LBRYFileRender
from lbrynet.conf import API_CONNECTION_STRING, API_INTERFACE, API_ADDRESS, API_PORT, DEFAULT_WALLET, UI_ADDRESS
if sys.platform != "darwin":
log_dir = os.path.join(os.path.expanduser("~"), ".lbrynet")
else:
log_dir = user_data_dir("LBRY")
if not os.path.isdir(log_dir):
os.mkdir(log_dir)
LOG_FILENAME = os.path.join(log_dir, 'lbrynet-daemon.log')
log = logging.getLogger(__name__)
handler = logging.handlers.RotatingFileHandler(LOG_FILENAME, maxBytes=262144, backupCount=5)
log.addHandler(handler)
logging.basicConfig(level=logging.INFO)
@ -48,6 +61,9 @@ def start():
parser.add_argument("--ui",
help="path to custom UI folder",
default="")
parser.add_argument("--branch",
help="Branch of lbry-web-ui repo to use, defaults on HEAD",
default="HEAD")
try:
JSONRPCProxy.from_url(API_CONNECTION_STRING).is_running()
@ -60,25 +76,35 @@ def start():
args = parser.parse_args()
if args.branch == "HEAD":
GIT_CMD_STRING = "git ls-remote https://github.com/lbryio/lbry-web-ui.git | grep %s | cut -f 1" % args.branch
DIST_URL = "https://rawgit.com/lbryio/lbry-web-ui/master/dist.zip"
else:
log.info("Using UI branch: " + args.branch)
GIT_CMD_STRING = "git ls-remote https://github.com/lbryio/lbry-web-ui.git | grep refs/heads/%s | cut -f 1" % args.branch
DIST_URL = "https://rawgit.com/lbryio/lbry-web-ui/%s/dist.zip" % args.branch
def getui(ui_dir=None):
if ui_dir:
if os.path.isdir(ui_dir):
log.info("Using user specified UI directory: " + str(ui_dir))
return defer.succeed(ui_dir)
ui_version_info = "user-specified"
return defer.succeed([ui_dir, ui_version_info])
else:
log.info("User specified UI directory doesn't exist: " + str(ui_dir))
def download_ui(dest_dir):
url = urlopen("https://rawgit.com/lbryio/lbry-web-ui/master/dist.zip")
def download_ui(dest_dir, ui_version):
url = urlopen(DIST_URL)
z = ZipFile(StringIO(url.read()))
z.extractall(dest_dir)
return defer.succeed(dest_dir)
names = [i for i in z.namelist() if '.DS_Store' not in i and '__MACOSX' not in i]
z.extractall(dest_dir, members=names)
return defer.succeed([dest_dir, ui_version])
data_dir = user_data_dir("LBRY")
version_dir = os.path.join(data_dir, "ui_version_history")
git_version = subprocess.check_output(
"git ls-remote https://github.com/lbryio/lbry-web-ui.git | grep HEAD | cut -f 1", shell=True)
git_version = subprocess.check_output(GIT_CMD_STRING, shell=True)
ui_version_info = git_version
if not os.path.isdir(data_dir):
os.mkdir(data_dir)
@ -104,28 +130,28 @@ def start():
log.info(version_message)
if os.path.isdir(os.path.join(data_dir, "lbry-web-ui")):
return defer.succeed(os.path.join(data_dir, "lbry-web-ui"))
return defer.succeed([os.path.join(data_dir, "lbry-web-ui"), ui_version_info])
else:
return download_ui((os.path.join(data_dir, "lbry-web-ui")))
return download_ui(os.path.join(data_dir, "lbry-web-ui"), ui_version_info)
def setupserver(ui_dir):
def setupserver(ui_dir, ui_version):
root = LBRYindex(ui_dir)
root.putChild("css", static.File(os.path.join(ui_dir, "css")))
root.putChild("font", static.File(os.path.join(ui_dir, "font")))
root.putChild("img", static.File(os.path.join(ui_dir, "img")))
root.putChild("js", static.File(os.path.join(ui_dir, "js")))
root.putChild("view", LBRYFileRender())
return defer.succeed(root)
return defer.succeed([root, ui_version])
def setupapi(root, wallet):
daemon = LBRYDaemon()
def setupapi(root, wallet, ui_version):
daemon = LBRYDaemon(wallet, "False", ui_version)
root.putChild(API_ADDRESS, daemon)
reactor.listenTCP(API_PORT, server.Site(root), interface=API_INTERFACE)
return daemon.setup(wallet, "False")
return daemon.setup()
d = getui(args.ui)
d.addCallback(setupserver)
d.addCallback(lambda r: setupapi(r, args.wallet))
d.addCallback(lambda r: setupserver(r[0], r[1]))
d.addCallback(lambda r: setupapi(r[0], args.wallet, r[1]))
d.addCallback(lambda _: webbrowser.open(UI_ADDRESS))
reactor.run()

View file

@ -17,7 +17,7 @@ log = logging.getLogger(__name__)
class GetStream(object):
def __init__(self, sd_identifier, session, wallet, lbry_file_manager, max_key_fee, pay_key=True, data_rate=0.5,
timeout=DEFAULT_TIMEOUT):
timeout=DEFAULT_TIMEOUT, download_directory=None):
self.wallet = wallet
self.resolved_name = None
self.description = None
@ -37,6 +37,7 @@ class GetStream(object):
self.d = defer.Deferred(None)
self.timeout = timeout
self.timeout_counter = 0
self.download_directory = download_directory
self.download_path = None
self.checker = LoopingCall(self.check_status)
@ -88,7 +89,10 @@ class GetStream(object):
self.d.addCallback(lambda _: download_sd_blob(self.session, self.stream_hash, self.payment_rate_manager))
self.d.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
self.d.addCallback(lambda metadata: (next(factory for factory in metadata.factories if isinstance(factory, ManagedLBRYFileDownloaderFactory)), metadata))
self.d.addCallback(lambda (factory, metadata): factory.make_downloader(metadata, [self.data_rate, True], self.payment_rate_manager))
self.d.addCallback(lambda (factory, metadata): factory.make_downloader(metadata,
[self.data_rate, True],
self.payment_rate_manager,
download_directory=self.download_directory))
self.d.addErrback(lambda err: err.trap(defer.CancelledError))
self.d.addErrback(lambda err: log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback()))
self.d.addCallback(self._start_download)

View file

@ -103,10 +103,6 @@ class Publisher(object):
def set_sd_hash(sd_hash):
self.sd_hash = sd_hash
if isinstance(self.sources, dict):
self.sources['lbry_sd_hash'] = sd_hash
else:
self.sources = {'lbry_sd_hash': sd_hash}
d.addCallback(set_sd_hash)
return d

View file

@ -19,9 +19,10 @@ qrcode==5.2.2
requests==2.9.1
seccure==0.3.1.3
simplejson==3.8.2
six==1.10.0
six==1.9.0
slowaes==0.1a1
txJSON-RPC==0.3.1
unqlite==0.2.0
wsgiref==0.1.2
zope.interface==4.1.3
base58==0.2.2

View file

@ -26,12 +26,7 @@ console_scripts = ['lbrynet-console = lbrynet.lbrynet_console.LBRYConsole:launch
requires = ['pycrypto', 'twisted', 'miniupnpc', 'yapsy', 'seccure',
'python-bitcoinrpc==0.1', 'txJSON-RPC', 'requests>=2.4.2', 'unqlite==0.2.0',
'leveldb', 'lbryum', 'jsonrpc', 'simplejson', 'appdirs']
if sys.platform == 'darwin':
requires.append('six==1.9.0')
else:
requires.append('six>=1.9.0')
'leveldb', 'lbryum', 'jsonrpc', 'simplejson', 'appdirs', 'six==1.9.0', 'base58']
gui_data_files = ['close2.gif', 'lbry-dark-242x80.gif', 'lbry-dark-icon.xbm', 'lbry-dark-icon.ico',
'drop_down.gif', 'show_options.gif', 'hide_options.gif', 'lbry.conf']