From b3465f3bbfba8e4f831cafa835908e3e24cdfd15 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 29 Mar 2016 16:42:47 -0400 Subject: [PATCH 01/41] fix /view, improve is_running, clean function outputs -Use localhost:5279/view?name=wonderfullife to download and render a file -is_running is now the only function that will work during startup -functions output json, rather than json in your json --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 197 ++++++++++---------- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 12 +- 2 files changed, 103 insertions(+), 106 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index eab1a0bee..faf62264c 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -6,14 +6,12 @@ import binascii import subprocess import logging import requests -# import rumps -# import httplib2 from twisted.web import server, resource, static from twisted.internet import defer, threads, error, reactor from txjsonrpc import jsonrpclib from txjsonrpc.web import jsonrpc -from jsonrpc.proxy import JSONRPCProxy +from txjsonrpc.web.jsonrpc import Handler from datetime import datetime from decimal import Decimal @@ -82,6 +80,17 @@ class LBRYDaemon(jsonrpc.JSONRPC): version = jsonrpclib.VERSION_PRE1 # XXX this all needs to be re-worked to support logic for multiple # versions... + + if not self.announced_startup: + if functionPath != 'is_running': + request.setHeader("Access-Control-Allow-Origin", "*") + request.setHeader("content-type", "text/json") + s = jsonrpclib.dumps("Starting up", version=version) + request.setHeader("content-length", str(len(s))) + request.write(s) + request.finish() + return server.NOT_DONE_YET + try: function = self._getFunction(functionPath) except jsonrpclib.Fault, f: @@ -97,6 +106,32 @@ class LBRYDaemon(jsonrpc.JSONRPC): d.addCallback(self._cbRender, request, id, version) return server.NOT_DONE_YET + def _cbRender(self, result, request, id, version): + if isinstance(result, Handler): + result = result.result + + if isinstance(result, dict): + result = result['result'] + + if version == jsonrpclib.VERSION_PRE1: + if not isinstance(result, jsonrpclib.Fault): + result = (result,) + # Convert the result (python) to JSON-RPC + try: + s = jsonrpclib.dumps(result, version=version) + except: + f = jsonrpclib.Fault(self.FAILURE, "can't serialize output") + s = jsonrpclib.dumps(f, version=version) + request.setHeader("content-length", str(len(s))) + request.write(s) + request.finish() + + def _ebRender(self, failure, id): + if isinstance(failure.value, jsonrpclib.Fault): + return failure.value + 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) @@ -179,9 +214,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): return defer.succeed(None) + def _announce_startup(): + self.announced_startup = True + return defer.succeed(None) + def _disp_startup(): log.info("[" + str(datetime.now()) + "] Started lbrynet-daemon") - return defer.succeed(None) log.info("[" + str(datetime.now()) + "] Starting lbrynet-daemon") @@ -201,6 +239,7 @@ 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 _: _announce_startup()) d.addCallback(lambda _: _disp_startup()) d.callback(None) @@ -653,7 +692,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d def _render_response(self, result, code): - return json.dumps({'result': result, 'code': code}) + return defer.succeed({'result': result, 'code': code}) # def _log_to_slack(self, msg): # URL = "https://hooks.slack.com/services/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" @@ -662,13 +701,10 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_is_running(self): """ - Returns a startup message when the daemon starts, after which it will return True + Returns true if daemon completed startup, otherwise returns false """ - if self.startup_message != "" and self.announced_startup == False: - self.announced_startup = True - return self._render_response(self.startup_message, OK_CODE) - elif self.announced_startup: + if self.announced_startup: return self._render_response(True, OK_CODE) else: return self._render_response(False, OK_CODE) @@ -677,7 +713,9 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Get LBRY payment settings - @return {'data_rate': float, 'max_key_fee': float} + @return {'data_rate': float, 'max_key_fee': float, 'max_upload': float (0.0 for unlimited), + 'default_download_directory': string, 'run_on_startup': bool, + 'max_download': float (0.0 for unlimited)} """ log.info("[" + str(datetime.now()) + "] Get daemon settings") @@ -687,7 +725,9 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Set LBRY payment settings - @param settings: {'settings': {'data_rate': float, 'max_key_fee': float}} + @param settings: {'data_rate': float, 'max_key_fee': float, 'max_upload': float (0.0 for unlimited), + 'default_download_directory': string, 'run_on_startup': bool, + 'max_download': float (0.0 for unlimited)} """ d = self._update_settings(p) @@ -736,7 +776,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ log.info("[" + str(datetime.now()) + "] Get balance") - return self._render_response(self.session.wallet.wallet_balance, OK_CODE) + return self._render_response(float(self.session.wallet.wallet_balance), OK_CODE) def jsonrpc_stop(self): """ @@ -818,36 +858,36 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d - def jsonrpc_stop_lbry_file(self, p): - params = Bunch(p) - - try: - lbry_file = [f for f in self.lbry_file_manager.lbry_files if f.stream_hash == params.stream_hash][0] - except IndexError: - return defer.fail(UnknownNameError) - - if not lbry_file.stopped: - d = self.lbry_file_manager.toggle_lbry_file_running(lbry_file) - d.addCallback(lambda _: self._render_response("Stream has been stopped", OK_CODE)) - d.addErrback(lambda err: self._render_response(err.getTraceback(), )) - return d - else: - return json.dumps({'result': 'Stream was already stopped'}) - - def jsonrpc_start_lbry_file(self, p): - params = Bunch(p) - - try: - lbry_file = [f for f in self.lbry_file_manager.lbry_files if f.stream_hash == params.stream_hash][0] - except IndexError: - return defer.fail(UnknownNameError) - - if lbry_file.stopped: - d = self.lbry_file_manager.toggle_lbry_file_running(lbry_file) - d.callback(None) - return json.dumps({'result': 'Stream started'}) - else: - return json.dumps({'result': 'Stream was already running'}) + # def jsonrpc_stop_lbry_file(self, p): + # params = Bunch(p) + # + # try: + # lbry_file = [f for f in self.lbry_file_manager.lbry_files if f.stream_hash == params.stream_hash][0] + # except IndexError: + # return defer.fail(UnknownNameError) + # + # if not lbry_file.stopped: + # d = self.lbry_file_manager.toggle_lbry_file_running(lbry_file) + # d.addCallback(lambda _: self._render_response("Stream has been stopped", OK_CODE)) + # d.addErrback(lambda err: self._render_response(err.getTraceback(), )) + # return d + # else: + # return json.dumps({'result': 'Stream was already stopped'}) + # + # def jsonrpc_start_lbry_file(self, p): + # params = Bunch(p) + # + # try: + # lbry_file = [f for f in self.lbry_file_manager.lbry_files if f.stream_hash == params.stream_hash][0] + # except IndexError: + # return defer.fail(UnknownNameError) + # + # if lbry_file.stopped: + # d = self.lbry_file_manager.toggle_lbry_file_running(lbry_file) + # d.callback(None) + # return json.dumps({'result': 'Stream started'}) + # else: + # return json.dumps({'result': 'Stream was already running'}) def jsonrpc_search_nametrie(self, p): """ @@ -891,7 +931,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): t['cost_est'] = r[2] consolidated_results.append(t) # log.info(str(t)) - return self._render_response(consolidated_results, OK_CODE) + return consolidated_results log.info('[' + str(datetime.now()) + '] Search nametrie: ' + params.search) @@ -901,6 +941,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): d.addCallback(resolve_claims) d.addCallback(_clean) d.addCallback(_disp) + d.addCallback(lambda results: self._render_response(results, OK_CODE)) return d @@ -918,9 +959,11 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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 params.file_name == f.file_name] + lbry_files = [self._delete_lbry_file(f) for f in self.lbry_file_manager.lbry_files + if params.file_name == f.file_name] d = defer.DeferredList(lbry_files) d.addCallback(lambda _: _disp(params.file_name)) + return d def jsonrpc_publish(self, p): @@ -1001,10 +1044,11 @@ class LBRYDaemon(jsonrpc.JSONRPC): for k in c.keys(): if isinstance(c[k], Decimal): c[k] = float(c[k]) - return self._render_response(claims, OK_CODE) + return defer.succeed(claims) d = self.session.wallet.get_name_claims() d.addCallback(_clean) + d.addCallback(lambda claims: self._render_response(claims, OK_CODE)) return d @@ -1029,10 +1073,11 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ def _disp(address): log.info("[" + str(datetime.now()) + "] Got new wallet address: " + address) - return json.dumps(self._render_response(address, OK_CODE)) + return defer.succeed(address) d = self.session.wallet.get_new_address() d.addCallback(_disp) + d.addCallback(lambda address: self._render_response(address, OK_CODE)) return d # def jsonrpc_update_name(self, metadata): @@ -1147,66 +1192,12 @@ class LBRYindex(resource.Resource): class LBRYFileRender(resource.Resource): isLeaf = False - def _render_path(self, path): - extension = os.path.splitext(path)[1] - if extension in ['mp4', 'flv', 'mov', 'ogv']: - return r'
' - - def _delayed_render(self, request, results): - request.write(str(results)) - request.finish() - def render_GET(self, request): if 'name' in request.args.keys(): api = jsonrpc.Proxy(API_CONNECTION_STRING) d = api.callRemote("get", {'name': request.args['name'][0]}) - d.addCallback(lambda response: self._delayed_render(request, self._render_path(json.loads(response)['result']['path'])) - if json.loads(response)['code'] == 200 - else self._delayed_render(request, "Error")) + d.addCallback(lambda results: static.File(results['path']).render_GET(request)) return server.NOT_DONE_YET else: - self._delayed_render(request, "Error") - return server.NOT_DONE_YET - - -# class LBRYFilePage(resource.Resource): -# isLeaf = False -# -# def _delayed_render(self, request, results): -# request.write(str(results)) -# request.finish() -# -# h = "%s" -# -# d = LBRYDaemonCommandHandler('get_lbry_files').run() -# d.addCallback(lambda r: json.loads(r)['result']) -# d.addCallback(lambda lbry_files: [h % (json.loads(lbry_file)['file_name'], json.loads(lbry_file)['file_name']) for lbry_file in lbry_files]) -# d.addCallback(lambda r: "" + ''.join(r) + "") -# d.addCallbacks(lambda results: self._delayed_render(request, results), -# lambda err: self._delayed_render(request, err.getTraceback())) -# -# return server.NOT_DONE_YET - - -class LBRYDaemonWeb(resource.Resource): - isLeaf = False - - def _delayed_render(self, request, results): - request.write(str(results)) - request.setResponseCode(json.loads(results)['code']) - request.finish() - - def render_GET(self, request): - func = request.args['function'][0] - del request.args['function'] - - p = {} - for k in request.args.keys(): - p[k] = request.args[k][0] - - d = LBRYDaemonCommandHandler(func).run(p) - d.addCallbacks(lambda results: self._delayed_render(request, results), - lambda err: self._delayed_render(request, json.dumps({'message': err.getTraceback(), 'code': BAD_REQUEST}))) - - return server.NOT_DONE_YET \ No newline at end of file + return server.failure diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index 789c4ad84..80d3db2d1 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -12,7 +12,7 @@ from twisted.web import server, static from twisted.internet import reactor, defer from jsonrpc.proxy import JSONRPCProxy -from lbrynet.lbrynet_daemon.LBRYDaemon import LBRYDaemon, LBRYindex, LBRYDaemonWeb, LBRYFileRender +from lbrynet.lbrynet_daemon.LBRYDaemon import LBRYDaemon, LBRYindex, LBRYFileRender from lbrynet.conf import API_CONNECTION_STRING, API_INTERFACE, API_ADDRESS, API_PORT, DEFAULT_WALLET log = logging.getLogger(__name__) @@ -46,6 +46,13 @@ def start(): help="temp or path, default temp, path is the path of the dist folder", default="temp") + try: + JSONRPCProxy.from_url(API_CONNECTION_STRING).is_running() + log.info("lbrynet-daemon is already running") + return + except: + pass + log.info("Starting lbrynet-daemon from command line") args = parser.parse_args() @@ -72,11 +79,10 @@ def start(): root.putChild("img", static.File(os.path.join(ui_dir, "img"))) root.putChild("js", static.File(os.path.join(ui_dir, "js"))) root.putChild(API_ADDRESS, daemon) - root.putChild("webapi", LBRYDaemonWeb()) root.putChild("view", LBRYFileRender()) reactor.listenTCP(API_PORT, server.Site(root), interface=API_INTERFACE) reactor.run() if download_ui: - shutil.rmtree(ui_dir) + shutil.rmtree(ui_dir) \ No newline at end of file From a7fb434f9feda129e1e412fb7fd763f134d39ce0 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 29 Mar 2016 17:04:01 -0400 Subject: [PATCH 02/41] update uri handler for change in daemon output --- lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py b/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py index f1dc04c00..18e5ae366 100644 --- a/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py +++ b/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py @@ -28,7 +28,7 @@ class LBRYURIHandler(object): def check_status(self): status = None try: - status = json.loads(self.daemon.is_running())['result'] + status = self.daemon.is_running() if self.start_timeout < 30 and not status: sleep(1) self.start_timeout += 1 @@ -49,7 +49,7 @@ class LBRYURIHandler(object): lbry_process = [d for d in subprocess.Popen(['ps','aux'], stdout=subprocess.PIPE).stdout.readlines() if 'LBRY.app' in d and 'LBRYURIHandler' not in d] try: - status = json.loads(self.daemon.is_running())['result'] + status = self.daemon.is_running() except: status = None @@ -64,17 +64,7 @@ class LBRYURIHandler(object): if lbry_name == "lbry" or lbry_name == "" and not started: webbrowser.get('safari').open(UI_ADDRESS) else: - r = json.loads(self.daemon.get({'name': lbry_name})) - if r['code'] == 200: - path = r['result']['path'].encode('utf-8') - extension = os.path.splitext(path)[1] - if extension in ['mp4', 'flv', 'mov', 'ogv']: - webbrowser.get('safari').open(UI_ADDRESS + "/view?name=" + lbry_name) - else: - webbrowser.get('safari').open('file://' + path) - else: - webbrowser.get('safari').open('http://lbry.io/get') - + webbrowser.get('safari').open(UI_ADDRESS + "/view?name=" + lbry_name) def main(args): if len(args) != 1: From 4355b799cba4931be3b806578afebd9af854d32a Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 29 Mar 2016 22:02:36 -0400 Subject: [PATCH 03/41] before is_running is true all other methods return a failure --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index faf62264c..6ee478e84 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -85,7 +85,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): if functionPath != 'is_running': request.setHeader("Access-Control-Allow-Origin", "*") request.setHeader("content-type", "text/json") - s = jsonrpclib.dumps("Starting up", version=version) + s = jsonrpclib.Fault(self.FAILURE, "error") request.setHeader("content-length", str(len(s))) request.write(s) request.finish() From 2540b9969f4409381e570cf4c0b88c6889d27bba Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 1 Apr 2016 22:06:06 -0400 Subject: [PATCH 04/41] check UI version from command line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -check UI version, if out of date get a fresh copy. overridden by —ui flag, which is used to specify a ui directory --- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 101 ++++++++++++++------ 1 file changed, 72 insertions(+), 29 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index 80d3db2d1..1899b4419 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -1,19 +1,22 @@ import argparse import logging -import tempfile +import subprocess import os import shutil +import webbrowser +import sys from StringIO import StringIO from zipfile import ZipFile from urllib import urlopen - +from datetime import datetime +from appdirs import user_data_dir from twisted.web import server, static from twisted.internet import reactor, defer 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 +from lbrynet.conf import API_CONNECTION_STRING, API_INTERFACE, API_ADDRESS, API_PORT, DEFAULT_WALLET, UI_ADDRESS log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) @@ -43,8 +46,8 @@ def start(): type=str, default="True") parser.add_argument("--ui", - help="temp or path, default temp, path is the path of the dist folder", - default="temp") + help="path to custom UI folder", + default="") try: JSONRPCProxy.from_url(API_CONNECTION_STRING).is_running() @@ -56,33 +59,73 @@ def start(): log.info("Starting lbrynet-daemon from command line") args = parser.parse_args() - download_ui = True - if args.ui != "temp" and os.path.isdir(args.ui): - download_ui = False - ui_dir = args.ui - log.info("Using user specified UI directory: " + str(ui_dir)) + 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) + else: + log.info("User specified UI directory doesn't exist: " + str(ui_dir)) - if args.ui == "temp" or download_ui: - log.info("Downloading current web ui to temp directory") - ui_dir = tempfile.mkdtemp() - url = urlopen("https://rawgit.com/lbryio/lbry-web-ui/master/dist.zip") - z = ZipFile(StringIO(url.read())) - z.extractall(ui_dir) + def download_ui(dest_dir): + url = urlopen("https://rawgit.com/lbryio/lbry-web-ui/master/dist.zip") + z = ZipFile(StringIO(url.read())) + z.extractall(dest_dir) + return defer.succeed(dest_dir) - daemon = LBRYDaemon() - daemon.setup(args.wallet, args.update) + data_dir = user_data_dir("LBRY") + version_dir = os.path.join(data_dir, "ui_version_history") - 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(API_ADDRESS, daemon) - root.putChild("view", LBRYFileRender()) + git_version = subprocess.check_output( + "git ls-remote https://github.com/lbryio/lbry-web-ui.git | grep HEAD | cut -f 1", shell=True) - reactor.listenTCP(API_PORT, server.Site(root), interface=API_INTERFACE) - reactor.run() + if not os.path.isdir(data_dir): + os.mkdir(data_dir) - if download_ui: - shutil.rmtree(ui_dir) \ No newline at end of file + if not os.path.isdir(os.path.join(data_dir, "ui_version_history")): + os.mkdir(version_dir) + + if not os.path.isfile(os.path.join(version_dir, git_version)): + try: + f = open(os.path.join(version_dir, git_version), "w") + version_message = "[" + str(datetime.now()) + "] Updating UI --> " + git_version + f.write(version_message) + f.close() + log.info(version_message) + except: + log.info("You should have been notified to install xcode command line tools, once it's installed you can start LBRY") + sys.exit(0) + + if os.path.isdir(os.path.join(data_dir, "lbry-web-ui")): + shutil.rmtree(os.path.join(data_dir, "lbry-web-ui")) + else: + version_message = "[" + str(datetime.now()) + "] UI version " + git_version + " up to date" + 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")) + else: + return download_ui((os.path.join(data_dir, "lbry-web-ui"))) + + def setupserver(ui_dir): + 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) + + def setupapi(root, wallet): + daemon = LBRYDaemon() + root.putChild(API_ADDRESS, daemon) + reactor.listenTCP(API_PORT, server.Site(root), interface=API_INTERFACE) + return daemon.setup(wallet, "False") + + d = getui(args.ui) + d.addCallback(setupserver) + d.addCallback(lambda r: setupapi(r, args.wallet)) + d.addCallback(lambda _: webbrowser.open(UI_ADDRESS)) + + reactor.run() \ No newline at end of file From d4b7064d2f8f2fbcbe8a6a74ac163c4c4b44ef57 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 1 Apr 2016 22:11:11 -0400 Subject: [PATCH 05/41] fix sources problems --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 83 ++++++++++++------------ lbrynet/lbrynet_daemon/LBRYDownloader.py | 2 + lbrynet/lbrynet_daemon/LBRYPublisher.py | 9 ++- 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 6ee478e84..1ea1e0a62 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -47,7 +47,6 @@ log = logging.getLogger(__name__) BAD_REQUEST = 400 NOT_FOUND = 404 OK_CODE = 200 - # TODO add login credentials in a conf file # TODO alert if your copy of a lbry file is out of date with the name record @@ -83,13 +82,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): if not self.announced_startup: if functionPath != 'is_running': - request.setHeader("Access-Control-Allow-Origin", "*") - request.setHeader("content-type", "text/json") - s = jsonrpclib.Fault(self.FAILURE, "error") - request.setHeader("content-length", str(len(s))) - request.write(s) - request.finish() - return server.NOT_DONE_YET + return server.failure try: function = self._getFunction(functionPath) @@ -561,7 +554,11 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _get_stream(name): def _disp(stream): - log.info("[" + str(datetime.now()) + "] Start stream: " + stream['stream_hash']) + stream_hash = stream['stream_hash'] + if isinstance(stream_hash, dict): + stream_hash = stream_hash['sd_hash'] + + log.info("[" + str(datetime.now()) + "] Start stream: " + stream_hash) return stream d = self.session.wallet.get_stream_info_for_name(name) @@ -602,6 +599,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): f.close() file_name = l['stream_name'].decode('hex') + for lbry_file in self.lbry_file_manager.lbry_files: if lbry_file.stream_name == file_name: if sys.platform == "darwin": @@ -616,6 +614,9 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _check(info): stream_hash = info['stream_hash'] + if isinstance(stream_hash, dict): + stream_hash = stream_hash['sd_hash'] + path = os.path.join(self.blobfile_dir, stream_hash) if os.path.isfile(path): log.info("[" + str(datetime.now()) + "] Search for lbry_file, returning: " + stream_hash) @@ -680,7 +681,9 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d d = self.session.wallet.get_stream_info_for_name(name) - d.addCallback(lambda info: download_sd_blob(self.session, info['stream_hash'], + d.addCallback(lambda info: info['stream_hash'] if isinstance(info['stream_hash'], str) + else info['stream_hash']['sd_hash']) + d.addCallback(lambda sd_hash: download_sd_blob(self.session, sd_hash, self.blob_request_payment_rate_manager)) d.addCallback(self.sd_identifier.get_metadata_for_sd_blob) d.addCallback(lambda metadata: metadata.validator.info_to_show()) @@ -829,11 +832,16 @@ class LBRYDaemon(jsonrpc.JSONRPC): params = Bunch(p) def _disp(info): - log.info("[" + str(datetime.now()) + "] Resolved info: " + info['stream_hash']) + stream_hash = info['stream_hash'] + if isinstance(stream_hash, dict): + stream_hash = stream_hash['sd_hash'] + + log.info("[" + str(datetime.now()) + "] Resolved info: " + stream_hash) + return self._render_response(info, OK_CODE) d = self._resolve_name(params.name) - d.addCallbacks(_disp, lambda _: self._render_response('error', NOT_FOUND)) + d.addCallbacks(_disp, lambda _: server.failure) d.callback(None) return d @@ -960,7 +968,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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 params.file_name == f.file_name] + if str(params.file_name) == str(f.file_name)] d = defer.DeferredList(lbry_files) d.addCallback(lambda _: _disp(params.file_name)) @@ -974,38 +982,27 @@ class LBRYDaemon(jsonrpc.JSONRPC): @return: """ - params = Bunch(p) + metadata_fields = ["name", "file_path", "bid", "author", "title", + "description", "thumbnail", "key_fee", "key_fee_address", + "content_license", "sources"] - metadata_fields = {"name": unicode, "file_path": unicode, "bid": float, "author": unicode, "title": unicode, - "description": unicode, "thumbnail": unicode, "key_fee": float, "key_fee_address": unicode, - "content_license": unicode, "sources": dict} + for k in metadata_fields: + if k not in p.keys(): + p[k] = None - for k in metadata_fields.keys(): - if k in params.__dict__.keys(): - if isinstance(params.__dict__[k], metadata_fields[k]): - if type(params.__dict__[k]) == unicode: - metadata_fields[k] = str(params.__dict__[k]) - else: - metadata_fields[k] = params.__dict__[k] - else: - metadata_fields[k] = None - else: - metadata_fields[k] = None + pub = Publisher(self.session, self.lbry_file_manager, self.session.wallet) - log.info("[" + str(datetime.now()) + "] Publish: ", metadata_fields) - - p = Publisher(self.session, self.lbry_file_manager, self.session.wallet) - d = p.start(name=metadata_fields['name'], - file_path=metadata_fields['file_path'], - bid=metadata_fields['bid'], - title=metadata_fields['title'], - description=metadata_fields['description'], - thumbnail=metadata_fields['thumbnail'], - key_fee=metadata_fields['key_fee'], - key_fee_address=metadata_fields['key_fee_address'], - content_license=metadata_fields['content_license'], - author=metadata_fields['author'], - sources=metadata_fields['sources']) + d = pub.start(p['name'], + p['file_path'], + p['bid'], + title=p['title'], + description=p['description'], + thumbnail=p['thumbnail'], + key_fee=p['key_fee'], + key_fee_address=p['key_fee_address'], + content_license=p['content_license'], + author=p['author'], + sources=p['sources']) d.addCallbacks(lambda msg: self._render_response(msg, OK_CODE), lambda err: self._render_response(err.getTraceback(), BAD_REQUEST)) @@ -1200,4 +1197,4 @@ class LBRYFileRender(resource.Resource): return server.NOT_DONE_YET else: - return server.failure + return server.failure \ No newline at end of file diff --git a/lbrynet/lbrynet_daemon/LBRYDownloader.py b/lbrynet/lbrynet_daemon/LBRYDownloader.py index 4552cd4af..997dde21c 100644 --- a/lbrynet/lbrynet_daemon/LBRYDownloader.py +++ b/lbrynet/lbrynet_daemon/LBRYDownloader.py @@ -68,6 +68,8 @@ class GetStream(object): self.key_fee_address = None self.stream_hash = self.stream_info['stream_hash'] + if isinstance(self.stream_hash, dict): + self.stream_hash = self.stream_hash['sd_hash'] else: log.error("InvalidStreamInfoError in autofetcher: ", stream_info) diff --git a/lbrynet/lbrynet_daemon/LBRYPublisher.py b/lbrynet/lbrynet_daemon/LBRYPublisher.py index ea7c015a3..f8ee282da 100644 --- a/lbrynet/lbrynet_daemon/LBRYPublisher.py +++ b/lbrynet/lbrynet_daemon/LBRYPublisher.py @@ -43,7 +43,7 @@ class Publisher(object): message = "[" + str(datetime.now()) + "] Published " + self.file_name + " --> lbry://" + \ str(self.publish_name) + " with txid: " + str(self.tx_hash) log.info(message) - return defer.succeed(message) + return defer.succeed(self.tx_hash) self.publish_name = name self.file_path = file_path @@ -103,12 +103,16 @@ 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 def _claim_name(self): - d = self.wallet.claim_name(self.publish_name, {'sd_hash': self.sd_hash}, self.bid_amount, + d = self.wallet.claim_name(self.publish_name, self.sd_hash, self.bid_amount, description=self.description, key_fee=self.key_fee, key_fee_address=self.key_fee_address, thumbnail=self.thumbnail, content_license=self.content_license, author=self.author, @@ -121,6 +125,7 @@ class Publisher(object): return d def _show_publish_error(self, err): + log.info(err.getTraceback()) message = "An error occurred publishing %s to %s. Error: %s." if err.check(InsufficientFundsError): error_message = "Insufficient funds" From f464b3ae7c1f7604edda69130182682f2277f23a Mon Sep 17 00:00:00 2001 From: Jimmy Kiselak Date: Mon, 4 Apr 2016 22:20:15 -0400 Subject: [PATCH 06/41] when decoding lbryum transactions, return values as Decimal --- lbrynet/core/LBRYcrdWallet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lbrynet/core/LBRYcrdWallet.py b/lbrynet/core/LBRYcrdWallet.py index cce937c21..9eb8a7303 100644 --- a/lbrynet/core/LBRYcrdWallet.py +++ b/lbrynet/core/LBRYcrdWallet.py @@ -1067,7 +1067,7 @@ class LBRYumWallet(LBRYWallet): decoded_tx['vout'] = [] for output in tx.outputs(): out = {} - out['value'] = output[2] + out['value'] = Decimal(output[2]) / Decimal(COIN) decoded_tx['vout'].append(out) return decoded_tx From a5362f3170ed4dff7edc92c31424de3f66e252e6 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 7 Apr 2016 03:12:09 -0400 Subject: [PATCH 07/41] daemon settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -set_settings accepts a dict of settings -adds upload_log field, defaulting on true, this uploads the lbry log file to lbry.io to help figure out if and where things aren’t working -default_download_directory is the key of the path where files are saved -gets publish working with sources -adds check_first_run function, returns True/False -previously only is_running would work during startup, check_first_run, get_time_behind_blockchain, and stop have been added -requires six 1.9, 1.10.0 produced errors --- lbrynet/__init__.py | 2 +- lbrynet/core/LBRYcrdWallet.py | 8 +- lbrynet/lbryfilemanager/LBRYFileDownloader.py | 5 +- lbrynet/lbryfilemanager/LBRYFileManager.py | 17 +- lbrynet/lbrynet_daemon/LBRYDaemon.py | 272 +++++++++++++----- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 8 + lbrynet/lbrynet_daemon/LBRYDownloader.py | 8 +- lbrynet/lbrynet_daemon/LBRYPublisher.py | 4 - requirements.txt | 2 +- setup.py | 7 +- 10 files changed, 238 insertions(+), 95 deletions(-) diff --git a/lbrynet/__init__.py b/lbrynet/__init__.py index eb4d8454c..993518cab 100644 --- a/lbrynet/__init__.py +++ b/lbrynet/__init__.py @@ -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]) diff --git a/lbrynet/core/LBRYcrdWallet.py b/lbrynet/core/LBRYcrdWallet.py index 9eb8a7303..f487becd0 100644 --- a/lbrynet/core/LBRYcrdWallet.py +++ b/lbrynet/core/LBRYcrdWallet.py @@ -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 @@ -1072,6 +1074,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 +1082,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) diff --git a/lbrynet/lbryfilemanager/LBRYFileDownloader.py b/lbrynet/lbryfilemanager/LBRYFileDownloader.py index fed0824e5..2afc17588 100644 --- a/lbrynet/lbryfilemanager/LBRYFileDownloader.py +++ b/lbrynet/lbryfilemanager/LBRYFileDownloader.py @@ -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 diff --git a/lbrynet/lbryfilemanager/LBRYFileManager.py b/lbrynet/lbryfilemanager/LBRYFileManager.py index 59f972df3..d0dbca1ae 100644 --- a/lbrynet/lbryfilemanager/LBRYFileManager.py +++ b/lbrynet/lbryfilemanager/LBRYFileManager.py @@ -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): diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 1ea1e0a62..73dc07d4b 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -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,10 @@ 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__ from lbrynet.core.PaymentRateManager import PaymentRateManager from lbrynet.core.server.BlobAvailabilityHandler import BlobAvailabilityHandlerFactory from lbrynet.core.server.BlobRequestHandler import BlobRequestHandlerFactory @@ -42,8 +46,23 @@ 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) + BAD_REQUEST = 400 NOT_FOUND = 404 OK_CODE = 200 @@ -81,7 +100,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): # versions... if not self.announced_startup: - if functionPath != 'is_running': + if functionPath not in ['is_running', 'check_first_run', 'get_time_behind_blockchain', 'stop']: return server.failure try: @@ -129,6 +148,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _set_vars(wallet_type, check_for_updates): reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown) + self.log_file = LOG_FILENAME self.fetcher = None self.current_db_revision = 1 self.run_server = True @@ -142,7 +162,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): self.blobfile_dir = os.path.join(self.db_dir, "blobfiles") self.peer_port = 3333 self.dht_node_port = 4444 - self.first_run = False + self.first_run = "Loading" if os.name == "nt": from lbrynet.winhelpers.knownpaths import get_path, FOLDERID, UserHandle self.download_directory = get_path(FOLDERID.Downloads, UserHandle.current) @@ -154,12 +174,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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.download_directory = os.getcwd() - self.daemon_conf = os.path.join(self.wallet_dir, 'daemon_settings.conf') + 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 @@ -197,21 +217,43 @@ class LBRYDaemon(jsonrpc.JSONRPC): self.search_timeout = 3.0 self.query_handlers = {} self.default_settings = { - 'run_on_startup': False, + '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 + 'max_download': 0.0, + 'upload_log': True } return defer.succeed(None) + 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} + + 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(): log.info("[" + str(datetime.now()) + "] Started lbrynet-daemon") return defer.succeed(None) @@ -219,7 +261,8 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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 +275,45 @@ 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: ": __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): @@ -317,33 +388,72 @@ 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'] + 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'] + 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'] + else: + return defer.fail() + elif k == 'max_download': + if type(settings['max_download']) is float: + self.session_settings['max_download'] = 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) @@ -398,10 +508,12 @@ 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 @@ -474,11 +586,17 @@ class LBRYDaemon(jsonrpc.JSONRPC): return dl def _check_first_run(self): + def _set_first_run_false(): + 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): @@ -530,7 +648,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, @@ -548,7 +666,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _download_name(self, name, timeout=DEFAULT_TIMEOUT): 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 +681,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=self.session_settings['default_download_directory']) d.addCallback(_disp) d.addCallback(lambda stream_info: stream.start(stream_info)) d.addCallback(lambda _: self._path_from_name(name)) @@ -603,7 +722,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 +763,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 +773,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,11 +816,6 @@ 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 @@ -712,6 +826,16 @@ class LBRYDaemon(jsonrpc.JSONRPC): else: return self._render_response(False, OK_CODE) + def jsonrpc_check_first_run(self): + 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("Loading", OK_CODE)) + + return d + def jsonrpc_get_settings(self): """ Get LBRY payment settings @@ -733,10 +857,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): """ @@ -961,18 +1089,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 +1144,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 +1180,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 diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index 1899b4419..b231e10af 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -1,5 +1,6 @@ import argparse import logging +import logging.handlers import subprocess import os import shutil @@ -18,6 +19,13 @@ 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") + +LOG_FILENAME = os.path.join(log_dir, 'lbrynet-daemon.log') + log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) diff --git a/lbrynet/lbrynet_daemon/LBRYDownloader.py b/lbrynet/lbrynet_daemon/LBRYDownloader.py index 997dde21c..5ebc4b59e 100644 --- a/lbrynet/lbrynet_daemon/LBRYDownloader.py +++ b/lbrynet/lbrynet_daemon/LBRYDownloader.py @@ -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) diff --git a/lbrynet/lbrynet_daemon/LBRYPublisher.py b/lbrynet/lbrynet_daemon/LBRYPublisher.py index f8ee282da..eeb8bbed3 100644 --- a/lbrynet/lbrynet_daemon/LBRYPublisher.py +++ b/lbrynet/lbrynet_daemon/LBRYPublisher.py @@ -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 diff --git a/requirements.txt b/requirements.txt index 103294fd4..ffbf27f45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ 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 diff --git a/setup.py b/setup.py index 679781350..7e806198a 100644 --- a/setup.py +++ b/setup.py @@ -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'] 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'] From 9a300d773f3fb4877098e053cb68008e5791be05 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 8 Apr 2016 22:23:37 -0400 Subject: [PATCH 08/41] optional download_directory parameter for get function -optional download_directory parameter to choose the directory a file is saved to, if not given or not a valid directory it uses the default --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 73dc07d4b..e1e352353 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -587,6 +587,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _check_first_run(self): def _set_first_run_false(): + log.info("Not first run") self.first_run = False return 0.0 @@ -600,6 +601,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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'] @@ -664,7 +666,12 @@ 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.session_settings['default_download_directory'], f.file_name) log.info("[" + str(datetime.now()) + "] Already downloaded: " + str(f.stream_hash) + " --> " + file_path) @@ -682,7 +689,7 @@ 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, - download_directory=self.session_settings['default_download_directory']) + download_directory=download_directory) d.addCallback(_disp) d.addCallback(lambda stream_info: stream.start(stream_info)) d.addCallback(lambda _: self._path_from_name(name)) @@ -977,16 +984,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: From 08e25f4622ff251ba09e3a8feac976da697f623f Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 8 Apr 2016 23:38:57 -0400 Subject: [PATCH 09/41] convert ints to floats if given as settings params --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index e1e352353..63d4b2dcc 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -420,11 +420,15 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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': @@ -438,11 +442,15 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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': @@ -828,6 +836,8 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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: @@ -1343,4 +1353,4 @@ class LBRYFileRender(resource.Resource): return server.NOT_DONE_YET else: - return server.failure \ No newline at end of file + return server.failure From 162275992b01758e094c1d7346cd944b1be93b36 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 8 Apr 2016 23:52:43 -0400 Subject: [PATCH 10/41] return fail from check_first_run when is_first_run isn't callable --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 63d4b2dcc..093cc54f4 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -849,7 +849,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): except: d = defer.fail(None) - d.addCallbacks(lambda r: self._render_response(r, OK_CODE), lambda _: self._render_response("Loading", OK_CODE)) + d.addCallbacks(lambda r: self._render_response(r, OK_CODE), lambda _: server.failure) return d From 28a23590efe41d6b01c37b466dec9ba90a9fc4e5 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 9 Apr 2016 01:33:27 -0400 Subject: [PATCH 11/41] add message for startup status -added daemon_status function that returns {'status': startup status message, 'is_running': true/false} --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 093cc54f4..e927d29e7 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -100,7 +100,9 @@ class LBRYDaemon(jsonrpc.JSONRPC): # versions... if not self.announced_startup: - if functionPath not in ['is_running', 'check_first_run', 'get_time_behind_blockchain', 'stop']: + if functionPath not in ['is_running', 'check_first_run', + 'get_time_behind_blockchain', 'stop', + 'daemon_status']: return server.failure try: @@ -212,6 +214,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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 = "Initializing" self.startup_message = "" self.announced_startup = False self.search_timeout = 3.0 @@ -254,6 +257,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _announce_startup(): self.announced_startup = True + self.startus_status = None log.info("[" + str(datetime.now()) + "] Started lbrynet-daemon") return defer.succeed(None) @@ -307,6 +311,8 @@ class LBRYDaemon(jsonrpc.JSONRPC): f.close() return self.default_settings + self.startus_status = "Loading configuration" + d = _log_platform() d.addCallback(lambda _: _load_daemon_conf()) @@ -345,6 +351,8 @@ class LBRYDaemon(jsonrpc.JSONRPC): return self._start_server() return defer.succeed(True) + self.startus_status = "Starting lbrynet" + dl = self.settings.get_server_running_status() dl.addCallback(restore_running_status) return dl @@ -471,6 +479,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return defer.succeed(None) def _setup_data_directory(self): + self.startus_status = "Loading databases" log.info("Loading databases...") if self.created_data_dir: db_revision = open(os.path.join(self.db_dir, "db_revision"), mode='w') @@ -526,6 +535,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d def _setup_lbry_file_manager(self): + self.startus_status = "Loading file manager" self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir) d = self.lbry_file_metadata_manager.setup() @@ -548,6 +558,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d def get_wallet(): + self.startup_status = "Loading wallet" if self.wallet_type == "lbrycrd": log.info("Using lbrycrd wallet") lbrycrdd_path = None @@ -580,6 +591,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return r def create_session(results): + self.startus_status = "Loading lbrynet session" self.session = LBRYSession(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=self.known_dht_nodes, peer_port=self.peer_port, @@ -843,6 +855,15 @@ class LBRYDaemon(jsonrpc.JSONRPC): else: return self._render_response(False, OK_CODE) + def jsonrpc_daemon_status(self): + """ + Returns {'status': startup status message, 'is_running': true/false} + """ + + r = {'status': self.startus_status, 'is_running': self.announced_startup} + log.info("[" + str(datetime.now()) + "] daemon status: " + str(r)) + return self._render_response(r, OK_CODE) + def jsonrpc_check_first_run(self): try: d = self.session.wallet.is_first_run() From c3277d24c3f9406a6f3d1cefe6cf7e6b6f02079f Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 9 Apr 2016 02:09:30 -0400 Subject: [PATCH 12/41] use status_message and status_code return fields for daemon_status() --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 33 ++++++++++++++++++---------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index e927d29e7..250c82c6d 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -63,6 +63,17 @@ handler = logging.handlers.RotatingFileHandler(LOG_FILENAME, maxBytes=262144, ba log.addHandler(handler) +STARTUP_STAGES = [ + ('initializing', 'Initializing...'), + ('loading_db', 'Loading databases...'), + ('loading_wallet', 'Catching up with blockchain... %s'), + ('loading_session', 'Starting session'), + ('loading_file_manager', 'Setting up file manager'), + ('loading_server', 'Starting lbrynet'), + ('started', 'Started lbrynet') + ] + + BAD_REQUEST = 400 NOT_FOUND = 404 OK_CODE = 200 @@ -214,7 +225,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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 = "Initializing" + self.startup_status = STARTUP_STAGES[0] self.startup_message = "" self.announced_startup = False self.search_timeout = 3.0 @@ -257,7 +268,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _announce_startup(): self.announced_startup = True - self.startus_status = None + self.startup_status = STARTUP_STAGES[6] log.info("[" + str(datetime.now()) + "] Started lbrynet-daemon") return defer.succeed(None) @@ -311,8 +322,6 @@ class LBRYDaemon(jsonrpc.JSONRPC): f.close() return self.default_settings - self.startus_status = "Loading configuration" - d = _log_platform() d.addCallback(lambda _: _load_daemon_conf()) @@ -351,7 +360,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return self._start_server() return defer.succeed(True) - self.startus_status = "Starting lbrynet" + self.startup_status = STARTUP_STAGES[5] dl = self.settings.get_server_running_status() dl.addCallback(restore_running_status) @@ -479,7 +488,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return defer.succeed(None) def _setup_data_directory(self): - self.startus_status = "Loading databases" + 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') @@ -535,7 +544,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d def _setup_lbry_file_manager(self): - self.startus_status = "Loading file manager" + self.startup_status = STARTUP_STAGES[4] self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir) d = self.lbry_file_metadata_manager.setup() @@ -558,7 +567,6 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d def get_wallet(): - self.startup_status = "Loading wallet" if self.wallet_type == "lbrycrd": log.info("Using lbrycrd wallet") lbrycrdd_path = None @@ -591,11 +599,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): return r def create_session(results): - self.startus_status = "Loading lbrynet session" + self.startup_status = STARTUP_STAGES[2] self.session = LBRYSession(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=self.known_dht_nodes, peer_port=self.peer_port, use_upnp=self.use_upnp, wallet=results['wallet']) + self.startup_status = STARTUP_STAGES[3] dl = defer.DeferredList([d1, d2], fireOnOneErrback=True) dl.addCallback(combine_results) @@ -857,10 +866,10 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_daemon_status(self): """ - Returns {'status': startup status message, 'is_running': true/false} + Returns {'status_message': startup status message, 'status_code': status_code} """ - - r = {'status': self.startus_status, 'is_running': self.announced_startup} + + r = {'status_code': self.startup_status[0], 'status_message': self.startup_status[1]} log.info("[" + str(datetime.now()) + "] daemon status: " + str(r)) return self._render_response(r, OK_CODE) From a4c83a08c71104d44d25762e7f9f8d16405320e2 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 9 Apr 2016 04:00:31 -0400 Subject: [PATCH 13/41] change name of check_first_run to is_first_run --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 250c82c6d..0ef030026 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -111,7 +111,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): # versions... if not self.announced_startup: - if functionPath not in ['is_running', 'check_first_run', + if functionPath not in ['is_running', 'is_first_run', 'get_time_behind_blockchain', 'stop', 'daemon_status']: return server.failure @@ -873,7 +873,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): log.info("[" + str(datetime.now()) + "] daemon status: " + str(r)) return self._render_response(r, OK_CODE) - def jsonrpc_check_first_run(self): + def jsonrpc_is_first_run(self): try: d = self.session.wallet.is_first_run() except: From f4fe730dc9614f2ecac994a4b206355dc5f77df0 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 9 Apr 2016 04:15:58 -0400 Subject: [PATCH 14/41] add get_start_notice to return startup messages --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 0ef030026..247c96414 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -113,7 +113,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): if not self.announced_startup: if functionPath not in ['is_running', 'is_first_run', 'get_time_behind_blockchain', 'stop', - 'daemon_status']: + 'daemon_status', 'get_start_notice']: return server.failure try: @@ -883,6 +883,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d + def jsonrpc_get_start_notice(self): + if self.startup_message: + return self._render_response(self.startup_message, OK_CODE) + else: + return defer.fail(None) + def jsonrpc_get_settings(self): """ Get LBRY payment settings From c11872a2296a6b693499636e3e5906a7182a17e6 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 9 Apr 2016 04:35:34 -0400 Subject: [PATCH 15/41] default on no startup message --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 247c96414..13dae024d 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -655,7 +655,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(): From f0d39e6081ad5592f645f290ff08dcf8bf50fa63 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 9 Apr 2016 15:43:10 -0400 Subject: [PATCH 16/41] log LBRYDaemonControl and return None from get_start_notice if there is no notice to give --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 21 +++++++++++++-------- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 5 +++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 13dae024d..5dd8f1ead 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -58,9 +58,7 @@ if not os.path.isdir(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 = [ @@ -226,7 +224,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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 = "" + self.startup_message = None self.announced_startup = False self.search_timeout = 3.0 self.query_handlers = {} @@ -874,20 +872,27 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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 _: server.failure) + 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): - if self.startup_message: - return self._render_response(self.startup_message, OK_CODE) - else: - return defer.fail(None) + """ + Get any special message to be displayed at startup, such as a first run notice + """ + + log.info("[" + str(datetime.now()) + "] Get startup notice") + return self._render_response(self.startup_message, OK_CODE) def jsonrpc_get_settings(self): """ diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index b231e10af..699bf000b 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -24,9 +24,14 @@ if sys.platform != "darwin": 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) From 4140fc4d286fff378c6369de611347f3105bd125 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 9 Apr 2016 15:43:25 -0400 Subject: [PATCH 17/41] add base58 --- requirements.txt | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ffbf27f45..d4423b5db 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,3 +25,4 @@ txJSON-RPC==0.3.1 unqlite==0.2.0 wsgiref==0.1.2 zope.interface==4.1.3 +base58==0.2.2 diff --git a/setup.py b/setup.py index 7e806198a..877377190 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +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', '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'] From a931f59dda8dd8eb04b559c022e0cd1bef20d7d5 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 9 Apr 2016 16:14:28 -0400 Subject: [PATCH 18/41] only return first run message until credits arrive --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 5dd8f1ead..13fa760b8 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -173,7 +173,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): self.blobfile_dir = os.path.join(self.db_dir, "blobfiles") self.peer_port = 3333 self.dht_node_port = 4444 - self.first_run = "Loading" + 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) @@ -891,8 +891,15 @@ class LBRYDaemon(jsonrpc.JSONRPC): Get any special message to be displayed at startup, such as a first run notice """ + log.info("[" + str(datetime.now()) + "] Get startup notice") - return self._render_response(self.startup_message, OK_CODE) + + if self.first_run and not self.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_get_settings(self): """ From e48cc40610f7eebb4c762acf01602728815c5977 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 9 Apr 2016 16:18:06 -0400 Subject: [PATCH 19/41] fix incorrect variable --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 13fa760b8..83ce6d389 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -894,7 +894,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): log.info("[" + str(datetime.now()) + "] Get startup notice") - if self.first_run and not self.wallet.balance: + 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) From aa8c362cb8839c936a19a0186133ad13ad30abf2 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 11 Apr 2016 16:15:12 -0400 Subject: [PATCH 20/41] add --branch arg to lbrynet-daemon to specify ui branch --- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index 699bf000b..3818ff55e 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -61,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() @@ -73,6 +76,14 @@ 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): @@ -82,16 +93,16 @@ def start(): 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") + url = urlopen(DIST_URL) z = ZipFile(StringIO(url.read())) - z.extractall(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) 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) if not os.path.isdir(data_dir): os.mkdir(data_dir) From 31fa97437972dca87f6b313631759b6e0bdb1b7a Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 11 Apr 2016 22:28:46 -0400 Subject: [PATCH 21/41] version function, ui version tracking, blocks behind blockchain during startup, cleaner set_vars -adds version() function, which can be called after the daemon is running and returns lbrynet, lbryum, and lbry ui version information. -daemon_status now returns how far behind its behind the blockchain when in the loading_wallet phase of startup -cleans up set_vars by moving to init --- lbrynet/core/LBRYcrdWallet.py | 2 + lbrynet/lbrynet_daemon/LBRYDaemon.py | 208 +++++++++++--------- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 26 +-- 3 files changed, 130 insertions(+), 106 deletions(-) diff --git a/lbrynet/core/LBRYcrdWallet.py b/lbrynet/core/LBRYcrdWallet.py index f487becd0..7a53bc47d 100644 --- a/lbrynet/core/LBRYcrdWallet.py +++ b/lbrynet/core/LBRYcrdWallet.py @@ -902,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): @@ -996,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 diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 83ce6d389..f08ed654d 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -23,7 +23,8 @@ from decimal import Decimal from appdirs import user_data_dir from urllib2 import urlopen -from lbrynet import __version__ +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 @@ -65,7 +66,6 @@ STARTUP_STAGES = [ ('initializing', 'Initializing...'), ('loading_db', 'Loading databases...'), ('loading_wallet', 'Catching up with blockchain... %s'), - ('loading_session', 'Starting session'), ('loading_file_manager', 'Setting up file manager'), ('loading_server', 'Starting lbrynet'), ('started', 'Started lbrynet') @@ -88,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. @@ -97,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: @@ -155,91 +242,7 @@ 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) - - 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.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 = 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 - } - - return defer.succeed(None) - + def setup(self): def _log_starting_vals(): def _get_lbry_files_json(): r = [] @@ -266,14 +269,13 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _announce_startup(): self.announced_startup = True - self.startup_status = STARTUP_STAGES[6] + 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._initial_setup()) d.addCallback(self._set_daemon_settings) d.addCallback(lambda _: threads.deferToThread(self._setup_data_directory)) @@ -299,7 +301,9 @@ class LBRYDaemon(jsonrpc.JSONRPC): msg = { "processor": platform.processor(), "python version: ": platform.python_version(), - "lbrynet version: ": __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": @@ -358,7 +362,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return self._start_server() return defer.succeed(True) - self.startup_status = STARTUP_STAGES[5] + self.startup_status = STARTUP_STAGES[4] dl = self.settings.get_server_running_status() dl.addCallback(restore_running_status) @@ -542,7 +546,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d def _setup_lbry_file_manager(self): - self.startup_status = STARTUP_STAGES[4] + self.startup_status = STARTUP_STAGES[3] self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir) d = self.lbry_file_metadata_manager.setup() @@ -597,12 +601,11 @@ class LBRYDaemon(jsonrpc.JSONRPC): return r def create_session(results): - self.startup_status = STARTUP_STAGES[2] self.session = LBRYSession(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=self.known_dht_nodes, peer_port=self.peer_port, use_upnp=self.use_upnp, wallet=results['wallet']) - self.startup_status = STARTUP_STAGES[3] + self.startup_status = STARTUP_STAGES[2] dl = defer.DeferredList([d1, d2], fireOnOneErrback=True) dl.addCallback(combine_results) @@ -868,6 +871,11 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ 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) @@ -901,6 +909,18 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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, + } + return self._render_response(msg, OK_CODE) + def jsonrpc_get_settings(self): """ Get LBRY payment settings diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index 3818ff55e..fe5c0ea2c 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -88,21 +88,23 @@ def start(): 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): + def download_ui(dest_dir, ui_version): url = urlopen(DIST_URL) z = ZipFile(StringIO(url.read())) 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) + 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_CMD_STRING, shell=True) + ui_version_info = git_version if not os.path.isdir(data_dir): os.mkdir(data_dir) @@ -128,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() \ No newline at end of file From c50f83400a68af5b188e932b73680e6e4ab548e6 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 11 Apr 2016 22:37:42 -0400 Subject: [PATCH 22/41] make version callable during startup --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index f08ed654d..568d74827 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -198,7 +198,8 @@ class LBRYDaemon(jsonrpc.JSONRPC): if not self.announced_startup: if functionPath not in ['is_running', 'is_first_run', 'get_time_behind_blockchain', 'stop', - 'daemon_status', 'get_start_notice']: + 'daemon_status', 'get_start_notice', + 'version']: return server.failure try: @@ -919,6 +920,8 @@ class LBRYDaemon(jsonrpc.JSONRPC): "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): From e04f35af4fb96def95aa482dde0482171fa95477 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 11 Apr 2016 23:13:26 -0400 Subject: [PATCH 23/41] fix check_for_new_version returns true if new version is available, otherwise false check_for_new_version is callable during startup --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 56 +++++++++------------------- 1 file changed, 17 insertions(+), 39 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 568d74827..3c30529d5 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -199,7 +199,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): if functionPath not in ['is_running', 'is_first_run', 'get_time_behind_blockchain', 'stop', 'daemon_status', 'get_start_notice', - 'version']: + 'version', 'check_for_new_version']: return server.failure try: @@ -920,7 +920,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): "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) @@ -1333,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', From 59002413f85b4494cab8130ce3763fac2408f501 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 12 Apr 2016 02:03:57 -0400 Subject: [PATCH 24/41] organize daemon init, move more into daemon_settings.json -also add wallet.catchup_progress to get a rough percentage of how caught up the daemon is, this is accessed through daemon_status() --- lbrynet/core/LBRYcrdWallet.py | 7 ++ lbrynet/lbrynet_daemon/LBRYDaemon.py | 117 ++++++++++++-------- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 2 +- 3 files changed, 78 insertions(+), 48 deletions(-) diff --git a/lbrynet/core/LBRYcrdWallet.py b/lbrynet/core/LBRYcrdWallet.py index 7a53bc47d..c6cb8c4d9 100644 --- a/lbrynet/core/LBRYcrdWallet.py +++ b/lbrynet/core/LBRYcrdWallet.py @@ -903,6 +903,8 @@ class LBRYumWallet(LBRYWallet): self._catch_up_check = None self._caught_up_counter = 0 self.blocks_behind_alert = 0 + self.catchup_progress = 0 + self.max_behind = 0 def _start(self): @@ -998,7 +1000,12 @@ class LBRYumWallet(LBRYWallet): 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 + if self.blocks_behind_alert > self.max_behind: + self.max_behind = self.blocks_behind_alert + self.catchup_progress = int(100 * (self.blocks_behind_alert / (5 + self.max_behind))) alert.info('%d...', (remote_height - local_height)) + alert.info("Catching up: " + str(int(100 * (self.blocks_behind_alert / (5 + self.max_behind)))) + "%") + self._caught_up_counter += 1 diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 3c30529d5..16ff012e4 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -91,88 +91,110 @@ class LBRYDaemon(jsonrpc.JSONRPC): isLeaf = True - def __init__(self, wallet_type, check_for_updates, ui_version_info): + def __init__(self, ui_version_info, wallet_type="lbryum"): jsonrpc.JSONRPC.__init__(self) reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown) + self.startup_status = STARTUP_STAGES[0] + self.startup_message = None + self.announced_startup = False + self.query_handlers = {} + self.ui_version = ui_version_info.replace('\n', '') + self.wallet_type = wallet_type + self.session_settings = None + self.first_run = None 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") + self.db_dir = os.path.join(get_path(FOLDERID.RoamingAppData, UserHandle.current), "lbrynet") + self.lbrycrdd_path = "lbrycrdd.exe" + if wallet_type == "lbrycrd": + self.wallet_dir = os.path.join(get_path(FOLDERID.RoamingAppData, UserHandle.current), "lbrycrd") + else: + self.wallet_dir = os.path.join(get_path(FOLDERID.RoamingAppData, UserHandle.current), "lbryum") elif sys.platform == "darwin": self.download_directory = os.path.join(os.path.expanduser("~"), 'Downloads') + self.db_dir = user_data_dir("LBRY") + self.lbrycrdd_path = "./lbrycrdd" 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() + self.db_dir = os.path.join(os.path.expanduser("~"), ".lbrynet") + self.lbrycrdd_path = "./lbrycrdd" 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.blobfile_dir = os.path.join(self.db_dir, "blobfiles") + self.lbrycrd_conf = os.path.join(self.wallet_dir, "lbrycrd.conf") + self.autofetcher_conf = os.path.join(self.wallet_dir, "autofetcher.conf") + 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.settings = LBRYSettings(self.db_dir) + self.blob_request_payment_rate_manager = None + self.lbry_file_metadata_manager = None + self.lbry_file_manager = None + + #defaults for settings otherwise loaded from daemon_settings.json self.default_settings = { 'run_on_startup': False, 'data_rate': MIN_BLOB_DATA_PAYMENT_RATE, - 'max_key_fee': 10.0, + 'max_key_fee': DEFAULT_MAX_KEY_FEE, 'default_download_directory': self.download_directory, 'max_upload': 0.0, 'max_download': 0.0, - 'upload_log': True + 'upload_log': True, + 'search_timeout': 3.0, + 'max_search_results': DEFAULT_MAX_SEARCH_RESULTS, + 'wallet_type': wallet_type, + 'delete_blobs_on_remove': True, + 'peer_port': 3333, + 'dht_node_port': 4444, + 'use_upnp': True, + 'start_lbrycrdd': True, } - self.ui_version = ui_version_info.replace('\n', '') + if os.path.isfile(self.daemon_conf): + #load given settings, set missing settings to defaults + temp_settings = self.default_settings + f = open(self.daemon_conf, "r") + s = json.loads(f.read()) + f.close() + for k in temp_settings.keys(): + if k in s.keys(): + if type(temp_settings[k]) == type(s[k]): + temp_settings[k] = s[k] + self.__dict__[k] = s[k] + f = open(self.daemon_conf, "w") + f.write(json.dumps(temp_settings)) + f.close() + 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() + for k in self.default_settings.keys(): + self.__dict__[k] = self.default_settings[k] def render(self, request): request.content.seek(0, 0) @@ -875,6 +897,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): try: if self.startup_status[0] == 'loading_wallet': r['status_message'] = r['status_message'] % (str(self.session.wallet.blocks_behind_alert) + " blocks behind") + r['progress'] = self.session.wallet.catchup_progress except: pass log.info("[" + str(datetime.now()) + "] daemon status: " + str(r)) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index fe5c0ea2c..ada6fa83f 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -144,7 +144,7 @@ def start(): return defer.succeed([root, ui_version]) def setupapi(root, wallet, ui_version): - daemon = LBRYDaemon(wallet, "False", ui_version) + daemon = LBRYDaemon(ui_version, wallet_type=wallet) root.putChild(API_ADDRESS, daemon) reactor.listenTCP(API_PORT, server.Site(root), interface=API_INTERFACE) return daemon.setup() From 925e106c438fad61dc0ddba09b55f01a3192f4cc Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Sun, 10 Apr 2016 22:33:44 -0400 Subject: [PATCH 25/41] add ubuntu package scripts, lbry:// uri handler --- packaging/ubuntu/README.md | 5 ++ packaging/ubuntu/lbry-init.conf | 11 +++++ packaging/ubuntu/lbry-uri-handler | 20 ++++++++ packaging/ubuntu/lbry.desktop | 21 ++++++++ packaging/ubuntu/ubuntu_package_setup.sh | 61 ++++++++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 packaging/ubuntu/README.md create mode 100644 packaging/ubuntu/lbry-init.conf create mode 100755 packaging/ubuntu/lbry-uri-handler create mode 100644 packaging/ubuntu/lbry.desktop create mode 100755 packaging/ubuntu/ubuntu_package_setup.sh diff --git a/packaging/ubuntu/README.md b/packaging/ubuntu/README.md new file mode 100644 index 000000000..d1a3d81f8 --- /dev/null +++ b/packaging/ubuntu/README.md @@ -0,0 +1,5 @@ +# package scripts + +How to build LBRY packages. + +For best results, run on a fresh image. diff --git a/packaging/ubuntu/lbry-init.conf b/packaging/ubuntu/lbry-init.conf new file mode 100644 index 000000000..c1e192deb --- /dev/null +++ b/packaging/ubuntu/lbry-init.conf @@ -0,0 +1,11 @@ +description "LBRY Daemon" + +#start on (local-filesystems and net-device-up IFACE=eth0) +stop on runlevel [016] + +#expect fork + +respawn +respawn limit 5 20 + +exec /usr/share/python/lbrynet/bin/lbrynet-daemon diff --git a/packaging/ubuntu/lbry-uri-handler b/packaging/ubuntu/lbry-uri-handler new file mode 100755 index 000000000..17d7910ff --- /dev/null +++ b/packaging/ubuntu/lbry-uri-handler @@ -0,0 +1,20 @@ +#!/bin/bash + +set -euo pipefail + +urlencode() { + local LANG=C + local length="${#1}" + for (( i = 0; i < length; i++ )); do + local c="${1:i:1}" + case $c in + [a-zA-Z0-9.~_-]) printf "$c" ;; + *) printf '%%%02X' "'$c" ;; + esac + done +} + +ARG=${1:-} +NAME=$(urlencode "$(echo "$ARG" | cut -c 8-)") + +/usr/bin/xdg-open http://localhost:5279/view?name="$NAME" diff --git a/packaging/ubuntu/lbry.desktop b/packaging/ubuntu/lbry.desktop new file mode 100644 index 000000000..7e5363782 --- /dev/null +++ b/packaging/ubuntu/lbry.desktop @@ -0,0 +1,21 @@ +[Desktop Entry] +Version=1.0 +Name=LBRY +# Only KDE 4 seems to use GenericName, so we reuse the KDE strings. +# From Ubuntu's language-pack-kde-XX-base packages, version 9.04-20090413. +GenericName=Filesharing +# Gnome and KDE 3 uses Comment. +Comment=Stream. Share. Earn. +#Exec=/usr/bin/xdg-open http://localhost:5279/view?name=%U +Exec=/usr/share/python/lbrynet/bin/lbry-uri-handler %U +Terminal=false +Icon= +Type=Application +Categories=Network;Internet;Filesharing +MimeType=x-scheme-handler/lbry; +X-Ayatana-Desktop-Shortcuts=NewWindow + +[NewWindow Shortcut Group] +Name=New Window +Exec=/home/grin/lbryhandler/testlbry newwindow %U +TargetEnvironment=Unity diff --git a/packaging/ubuntu/ubuntu_package_setup.sh b/packaging/ubuntu/ubuntu_package_setup.sh new file mode 100755 index 000000000..27b13fd1b --- /dev/null +++ b/packaging/ubuntu/ubuntu_package_setup.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Tested on fresh Ubuntu 14.04 install. + +# wget https://raw.githubusercontent.com/lbryio/lbry/master/packaging/ubuntu/ubuntu_package_setup.sh +# bash ubuntu_package_setup.sh master + +set -euo pipefail + +BRANCH=${1:-master} + +# get the required OS packages +sudo add-apt-repository -y ppa:spotify-jyrki/dh-virtualenv +sudo apt-get update +sudo apt-get install -y build-essential git python-dev libffi-dev libssl-dev libgmp3-dev dh-virtualenv debhelper + +# need a modern version of pip (more modern than ubuntu default) +wget https://bootstrap.pypa.io/get-pip.py +sudo python get-pip.py +rm get-pip.py +sudo pip install make-deb + +# check out LBRY +git clone https://github.com/lbryio/lbry.git --branch "$BRANCH" + +# build packages +( + cd lbry + make-deb + dpkg-buildpackage -us -uc +) + + +### insert our extra files + +# extract .deb +PACKAGE="$(ls | grep '.deb')" +ar vx "$PACKAGE" +mkdir control data +tar -xvzf control.tar.gz --directory control +tar -xvJf data.tar.xz --directory data + +# add files +function addfile() { + FILE="$1" + TARGET="$2" + mkdir -p "$(dirname "data/$TARGET")" + cp "$FILE" "data/$TARGET" + echo "$(md5sum "data/$TARGET" | cut -d' ' -f1) $TARGET" >> control/md5sums +} +PACKAGING_DIR='lbry/packaging/ubuntu' +addfile "$PACKAGING_DIR/lbry-uri-handler" usr/share/python/lbrynet/bin/lbry-uri-handler +addfile "$PACKAGING_DIR/lbry.desktop" usr/share/applications/lbry.desktop +#addfile lbry/packaging/ubuntu/lbry-init.conf etc/init/lbry.conf + +# repackage .deb +tar -cvzf control.tar.gz -C control . +tar -cvJf data.tar.xz -C data . +ar r "$PACKAGE" debian-binary control.tar.gz data.tar.xz + +# TODO: we can append to data.tar instead of extracting it all and recompressing From 2ac97736ce289ee3324149fb73477e95b28b6dfc Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Tue, 12 Apr 2016 18:50:47 -0400 Subject: [PATCH 26/41] bunch of changes, ready to roll --- packaging/ubuntu/lbry | 32 ++++++++++++++++++++++++ packaging/ubuntu/lbry-uri-handler | 20 --------------- packaging/ubuntu/lbry.desktop | 12 +++------ packaging/ubuntu/ubuntu_package_setup.sh | 8 +++++- 4 files changed, 42 insertions(+), 30 deletions(-) create mode 100755 packaging/ubuntu/lbry delete mode 100755 packaging/ubuntu/lbry-uri-handler diff --git a/packaging/ubuntu/lbry b/packaging/ubuntu/lbry new file mode 100755 index 000000000..4ad69c838 --- /dev/null +++ b/packaging/ubuntu/lbry @@ -0,0 +1,32 @@ +#!/bin/bash + +set -euo pipefail + +urlencode() { + local LANG=C + local length="${#1}" + for (( i = 0; i < length; i++ )); do + local c="${1:i:1}" + case $c in + [a-zA-Z0-9.~_-]) printf "$c" ;; + *) printf '%%%02X' "'$c" ;; + esac + done +} + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +if [ -z "$(pgrep lbrynet-daemon)" ]; then + echo "running lbrynet-daemon..." + $DIR/lbrynet-daemon 2>&1 >> "$HOME/.lbrynet/daemon.log" & + sleep 3 # let the daemon load before connecting +fi + +ARG=${1:-} + +if [ -z "$ARG" ]; then + URL="" +else + URL="view?name=$(urlencode "$(echo "$ARG" | cut -c 8-)")" +fi + +/usr/bin/xdg-open "http://localhost:5279/$URL" diff --git a/packaging/ubuntu/lbry-uri-handler b/packaging/ubuntu/lbry-uri-handler deleted file mode 100755 index 17d7910ff..000000000 --- a/packaging/ubuntu/lbry-uri-handler +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -urlencode() { - local LANG=C - local length="${#1}" - for (( i = 0; i < length; i++ )); do - local c="${1:i:1}" - case $c in - [a-zA-Z0-9.~_-]) printf "$c" ;; - *) printf '%%%02X' "'$c" ;; - esac - done -} - -ARG=${1:-} -NAME=$(urlencode "$(echo "$ARG" | cut -c 8-)") - -/usr/bin/xdg-open http://localhost:5279/view?name="$NAME" diff --git a/packaging/ubuntu/lbry.desktop b/packaging/ubuntu/lbry.desktop index 7e5363782..33d240950 100644 --- a/packaging/ubuntu/lbry.desktop +++ b/packaging/ubuntu/lbry.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -Version=1.0 +Version=0.2 Name=LBRY # Only KDE 4 seems to use GenericName, so we reuse the KDE strings. # From Ubuntu's language-pack-kde-XX-base packages, version 9.04-20090413. @@ -7,15 +7,9 @@ GenericName=Filesharing # Gnome and KDE 3 uses Comment. Comment=Stream. Share. Earn. #Exec=/usr/bin/xdg-open http://localhost:5279/view?name=%U -Exec=/usr/share/python/lbrynet/bin/lbry-uri-handler %U +Exec=/usr/share/python/lbrynet/bin/lbry %U Terminal=false -Icon= +Icon=/usr/share/python/lbrynet/lbrynet/lbrynet_gui/lbry-dark-icon.ico Type=Application Categories=Network;Internet;Filesharing MimeType=x-scheme-handler/lbry; -X-Ayatana-Desktop-Shortcuts=NewWindow - -[NewWindow Shortcut Group] -Name=New Window -Exec=/home/grin/lbryhandler/testlbry newwindow %U -TargetEnvironment=Unity diff --git a/packaging/ubuntu/ubuntu_package_setup.sh b/packaging/ubuntu/ubuntu_package_setup.sh index 27b13fd1b..4be10c8a7 100755 --- a/packaging/ubuntu/ubuntu_package_setup.sh +++ b/packaging/ubuntu/ubuntu_package_setup.sh @@ -9,6 +9,10 @@ set -euo pipefail BRANCH=${1:-master} +BUILD_DIR="lbry-build-$(date +%Y%m%d-%H%M%S)" +mkdir "$BUILD_DIR" +cd "$BUILD_DIR" + # get the required OS packages sudo add-apt-repository -y ppa:spotify-jyrki/dh-virtualenv sudo apt-get update @@ -49,13 +53,15 @@ function addfile() { echo "$(md5sum "data/$TARGET" | cut -d' ' -f1) $TARGET" >> control/md5sums } PACKAGING_DIR='lbry/packaging/ubuntu' -addfile "$PACKAGING_DIR/lbry-uri-handler" usr/share/python/lbrynet/bin/lbry-uri-handler +addfile "$PACKAGING_DIR/lbry" usr/share/python/lbrynet/bin/lbry addfile "$PACKAGING_DIR/lbry.desktop" usr/share/applications/lbry.desktop #addfile lbry/packaging/ubuntu/lbry-init.conf etc/init/lbry.conf # repackage .deb +sudo chown -R root:root control data tar -cvzf control.tar.gz -C control . tar -cvJf data.tar.xz -C data . +sudo chown root:root debian-binary control.tar.gz data.tar.xz ar r "$PACKAGE" debian-binary control.tar.gz data.tar.xz # TODO: we can append to data.tar instead of extracting it all and recompressing From b9d5d1041cb2f57c4d7620fe3735c034d40284f3 Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Tue, 12 Apr 2016 19:27:26 -0400 Subject: [PATCH 27/41] bump version, better icon --- lbrynet/lbrynet_gui/lbry.png | Bin 0 -> 10651 bytes packaging/ubuntu/lbry | 2 +- packaging/ubuntu/lbry.desktop | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 lbrynet/lbrynet_gui/lbry.png diff --git a/lbrynet/lbrynet_gui/lbry.png b/lbrynet/lbrynet_gui/lbry.png new file mode 100644 index 0000000000000000000000000000000000000000..16c7c4683affa3e73c5bcf4fbd0b6bbb0778f275 GIT binary patch literal 10651 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 lz#oNlK}QRNn5{lM7K&1 >> "$HOME/.lbrynet/daemon.log" & + $DIR/lbrynet-daemon --branch=settings-page & sleep 3 # let the daemon load before connecting fi diff --git a/packaging/ubuntu/lbry.desktop b/packaging/ubuntu/lbry.desktop index 33d240950..f034b97c6 100644 --- a/packaging/ubuntu/lbry.desktop +++ b/packaging/ubuntu/lbry.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -Version=0.2 +Version=0.2.1 Name=LBRY # Only KDE 4 seems to use GenericName, so we reuse the KDE strings. # From Ubuntu's language-pack-kde-XX-base packages, version 9.04-20090413. @@ -9,7 +9,7 @@ Comment=Stream. Share. Earn. #Exec=/usr/bin/xdg-open http://localhost:5279/view?name=%U Exec=/usr/share/python/lbrynet/bin/lbry %U Terminal=false -Icon=/usr/share/python/lbrynet/lbrynet/lbrynet_gui/lbry-dark-icon.ico +Icon=/usr/share/python/lbrynet/lbrynet/lbrynet_gui/lbry.png Type=Application Categories=Network;Internet;Filesharing MimeType=x-scheme-handler/lbry; From b32d096be2185ef95b3c8d63b7a9955c9921e63a Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Tue, 12 Apr 2016 20:44:47 -0400 Subject: [PATCH 28/41] add png to setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 877377190..e4a9432f0 100644 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ requires = ['pycrypto', 'twisted', 'miniupnpc', 'yapsy', 'seccure', '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'] + 'drop_down.gif', 'show_options.gif', 'hide_options.gif', 'lbry.conf', 'lbry.png'] gui_data_paths = [os.path.join(base_dir, 'lbrynet', 'lbrynet_gui', f) for f in gui_data_files] setup(name='lbrynet', From df99d06d11066c89471115c4d6fa566a6e63bafe Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 13 Apr 2016 02:35:31 -0400 Subject: [PATCH 29/41] fix links in check_for_new_version and log version info -also handle situation where function is given a null argument --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 31 +++++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 16ff012e4..56d790626 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -231,7 +231,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): else: request.setHeader("Access-Control-Allow-Origin", "*") request.setHeader("content-type", "text/json") - if args == [{}]: + if args == [{}] or args == [None]: d = defer.maybeDeferred(function) else: d = defer.maybeDeferred(function, *args) @@ -1356,23 +1356,38 @@ class LBRYDaemon(jsonrpc.JSONRPC): return self._render_response(self.fetcher.verbose, OK_CODE) def jsonrpc_check_for_new_version(self): + """ + Checks local version against versions in __init__.py and version.py in the lbrynet and lbryum repos + Returns true/false, true meaning that there is a new version available + """ + def _get_lbryum_version(): - r = urlopen("https://rawgit.com/lbryio/lbryum/master/lib/version.py").read().split('\n') + r = urlopen("https://raw.githubusercontent.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("'", "") + log.info("remote lbryum " + str(version) + " > local lbryum " + str(lbryum_version) + " = " + str(version > lbryum_version)) return version def _get_lbrynet_version(): - r = urlopen("https://rawgit.com/lbryio/lbry/master/lbrynet/__init__.py").read().split('\n') + r = urlopen("https://raw.githubusercontent.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]) + vr = ".".join([str(x) for x in vt]) + log.info("remote lbrynet " + str(vr) + " > local lbrynet " + str(lbrynet_version) + " = " + str(vr > lbrynet_version)) + return vr - 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 _check_version(): + git_lbrynet = _get_lbrynet_version() + git_lbryum = _get_lbryum_version() + if (lbrynet_version >= git_lbrynet) and (lbryum_version >= git_lbryum): + log.info("[" + str(datetime.now()) + "] Up to date") + return self._render_response(False, OK_CODE) + else: + log.info("[" + str(datetime.now()) + "] Updates available") + return self._render_response(True, OK_CODE) + + return _check_version() def jsonrpc___dir__(self): return ['is_running', 'get_settings', 'set_settings', 'start_fetcher', 'stop_fetcher', 'fetcher_status', From cdd44af043e0108a90bf22d17b0ebabf776fb5c0 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 13 Apr 2016 02:39:50 -0400 Subject: [PATCH 30/41] fix links in LBRYDaemonControl https was failing --- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index ada6fa83f..86c2699e7 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -78,11 +78,11 @@ def start(): 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" + DIST_URL = "http://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 + DIST_URL = "http://rawgit.com/lbryio/lbry-web-ui/%s/dist.zip" % args.branch def getui(ui_dir=None): if ui_dir: From 2000a1b33474d9468e9ffd1339572d041a76584b Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 13 Apr 2016 02:52:41 -0400 Subject: [PATCH 31/41] replace rawgit with raw.githubusercontent --- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index 86c2699e7..e509c7c81 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -78,11 +78,11 @@ def start(): 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 = "http://rawgit.com/lbryio/lbry-web-ui/master/dist.zip" + DIST_URL = "https://raw.githubusercontent.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 = "http://rawgit.com/lbryio/lbry-web-ui/%s/dist.zip" % args.branch + DIST_URL = "https://raw.githubusercontent.com/lbryio/lbry-web-ui/%s/dist.zip" % args.branch def getui(ui_dir=None): if ui_dir: From 65a0583c85492b2c5118ad98f2d7a5eab1a7e887 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 13 Apr 2016 14:47:34 -0400 Subject: [PATCH 32/41] add help function and documentation for functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -calling help() will return the list of functions -setting the ‘function’ param in the help function will return the doc string for that function -setting the ‘callable_on_startup’ in the help function will return the list of functions callable during the startup sequence --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 294 +++++++++++++++++++++------ 1 file changed, 228 insertions(+), 66 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 56d790626..5914048cd 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -71,6 +71,10 @@ STARTUP_STAGES = [ ('started', 'Started lbrynet') ] +ALLOWED_DURING_STARTUP = ['is_running', 'is_first_run', + 'get_time_behind_blockchain', 'stop', + 'daemon_status', 'get_start_notice', + 'version', 'check_for_new_version'] BAD_REQUEST = 400 NOT_FOUND = 404 @@ -79,11 +83,6 @@ OK_CODE = 200 # TODO alert if your copy of a lbry file is out of date with the name record -class Bunch: - def __init__(self, params): - self.__dict__.update(params) - - class LBRYDaemon(jsonrpc.JSONRPC): """ LBRYnet daemon, a jsonrpc interface to lbry functions @@ -218,10 +217,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): # versions... if not self.announced_startup: - if functionPath not in ['is_running', 'is_first_run', - 'get_time_behind_blockchain', 'stop', - 'daemon_status', 'get_start_notice', - 'version', 'check_for_new_version']: + if functionPath not in ALLOWED_DURING_STARTUP: return server.failure try: @@ -878,7 +874,11 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_is_running(self): """ - Returns true if daemon completed startup, otherwise returns false + Check if lbrynet daemon is running + + Args: + None + Returns: true if daemon completed startup, otherwise false """ log.info("[" + str(datetime.now()) + "] is_running: " + str(self.announced_startup)) @@ -890,7 +890,14 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_daemon_status(self): """ - Returns {'status_message': startup status message, 'status_code': status_code} + Get lbrynet daemon status information + + Args: + None + Returns: + 'status_message': startup status message + 'status_code': status_code + if status_code is 'loading_wallet', also contains key 'progress': blockchain catchup progress """ r = {'status_code': self.startup_status[0], 'status_message': self.startup_status[1]} @@ -905,7 +912,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_is_first_run(self): """ - Get True/False if can be determined, if wallet still is being set up returns None + Check if this is the first time lbrynet daemon has been run + + Args: + None + Returns: + True if first run, otherwise False """ log.info("[" + str(datetime.now()) + "] Check if is first run") @@ -920,9 +932,13 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_get_start_notice(self): """ - Get any special message to be displayed at startup, such as a first run notice - """ + Get special message to be displayed at startup + Args: + None + Returns: + Startup message, such as first run notification + """ log.info("[" + str(datetime.now()) + "] Get startup notice") @@ -936,11 +952,18 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_version(self): """ Get lbry version information + + Args: + None + Returns: + 'lbrynet version': lbrynet version + 'lbryum version': lbryum version + 'ui_version': commit hash of ui """ msg = { - "lbrynet version: ": lbrynet_version, - "lbryum version: ": lbryum_version, + "lbrynet_version: ": lbrynet_version, + "lbryum_version: ": lbryum_version, "ui_version": self.ui_version, } @@ -949,11 +972,26 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_get_settings(self): """ - Get LBRY payment settings + Get lbrynet daemon settings - @return {'data_rate': float, 'max_key_fee': float, 'max_upload': float (0.0 for unlimited), - 'default_download_directory': string, 'run_on_startup': bool, - 'max_download': float (0.0 for unlimited)} + Args: + None + Returns: + 'run_on_startup': bool, + 'data_rate': float, + 'max_key_fee': float, + 'default_download_directory': string, + 'max_upload': float, 0.0 for unlimited + 'max_download': float, 0.0 for unlimited + 'upload_log': bool, + 'search_timeout': float, + 'max_search_results': int, + 'wallet_type': string, + 'delete_blobs_on_remove': bool, + 'peer_port': int, + 'dht_node_port': int, + 'use_upnp': bool, + 'start_lbrycrdd': bool, """ log.info("[" + str(datetime.now()) + "] Get daemon settings") @@ -961,11 +999,26 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_set_settings(self, p): """ - Set LBRY payment settings + Set lbrynet daemon settings - @param settings: {'data_rate': float, 'max_key_fee': float, 'max_upload': float (0.0 for unlimited), - 'default_download_directory': string, 'run_on_startup': bool, - 'max_download': float (0.0 for unlimited)} + Args: + 'run_on_startup': bool, + 'data_rate': float, + 'max_key_fee': float, + 'default_download_directory': string, + 'max_upload': float, 0.0 for unlimited + 'max_download': float, 0.0 for unlimited + 'upload_log': bool, + 'search_timeout': float, + 'max_search_results': int, + 'wallet_type': string, + 'delete_blobs_on_remove': bool, + 'peer_port': int, + 'dht_node_port': int, + 'use_upnp': bool, + 'start_lbrycrdd': bool, + Returns: + settings dict """ def _log_settings_change(params): @@ -977,11 +1030,43 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d + def jsonrpc_help(self, p=None): + """ + Function to retrieve docstring for API function + + Args: + optional 'function': function to retrieve documentation for + optional 'callable_during_startup': + Returns: + if given a function, returns given documentation + if given callable_during_startup flag, returns list of functions callable during the startup sequence + if no params are given, returns the list of callable functions + """ + + if not p: + return self._render_response(['is_running', 'get_settings', 'set_settings', 'start_fetcher', 'stop_fetcher', + 'fetcher_status', 'get_balance', 'stop', 'get_lbry_files', 'resolve_name', + 'get', 'search_nametrie', 'delete_lbry_file', 'check', 'publish', + 'abandon_name', 'get_name_claims', 'get_time_behind_blockchain', + 'get_new_address', 'toggle_fetcher_verbose', 'check_for_new_version'], + OK_CODE) + elif 'callable_during_start' in p.keys(): + return self._render_response(ALLOWED_DURING_STARTUP, OK_CODE) + elif 'function' in p.keys(): + func_path = p['function'] + function = self._getFunction(func_path) + return self._render_response(function.__doc__, OK_CODE) + else: + return self._render_response(self.jsonrpc_help.__doc__, OK_CODE) + def jsonrpc_start_fetcher(self): """ - Start automatically downloading new name claims as they happen + Start automatically downloading new name claims as they occur (off by default) - @return: confirmation message + Args: + None + Returns: + confirmation message """ self.fetcher.start() @@ -991,9 +1076,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_stop_fetcher(self): """ - Stop automatically downloading new name claims as they happen + Stop automatically downloading new name claims as they occur - @return: confirmation message + Args: + None + Returns: + confirmation message """ self.fetcher.stop() @@ -1004,7 +1092,10 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Get fetcher status - @return: True/False + Args: + None + Returns: + True/False """ log.info("[" + str(datetime.now()) + "] Get fetcher status") @@ -1012,9 +1103,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_get_balance(self): """ - Get LBC balance + Get balance - @return: balance + Args: + None + Returns: + balance, float """ log.info("[" + str(datetime.now()) + "] Get balance") @@ -1024,7 +1118,10 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Stop lbrynet-daemon - @return: shutdown message + Args: + None + Returns: + shutdown message """ def _disp_shutdown(): @@ -1040,7 +1137,19 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Get LBRY files - @return: List of managed LBRY files + Args: + None + Returns: + List of lbry files: + 'completed': bool + 'file_name': string + 'key': hex string + 'points_paid': float + 'stopped': bool + 'stream_hash': base 58 string + 'stream_name': string + 'suggested_file_name': string + 'upload_allowed': bool """ r = [] @@ -1065,10 +1174,16 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Resolve stream info from a LBRY uri - @param: {'name': name to look up} - @return: info for name claim + Args: + 'name': name to look up, string, do not include lbry:// prefix + Returns: + metadata from name claim """ - params = Bunch(p) + + if 'name' in p.keys(): + name = p['name'] + else: + return self._render_response(None, BAD_REQUEST) def _disp(info): stream_hash = info['stream_hash'] @@ -1079,7 +1194,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): return self._render_response(info, OK_CODE) - d = self._resolve_name(params.name) + d = self._resolve_name(name) d.addCallbacks(_disp, lambda _: server.failure) d.callback(None) return d @@ -1088,8 +1203,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Download stream from a LBRY uri - @param: name, optional: download_directory - @return: {'stream_hash': hex string, 'path': path of download} + Args: + 'name': name to download, string + optional 'download_directory': path to directory where file will be saved, string + Returns: + 'stream_hash': hex string + 'path': path of download """ if 'timeout' not in p.keys(): @@ -1145,13 +1264,18 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_search_nametrie(self, p): """ - Search the nametrie for claims beginning with search + Search the nametrie for claims beginning with search (yes, this is a dumb search, it'll be made better) - @param {'search': search string} - @return: List of search results + Args: + 'search': search query, string + Returns: + List of search results """ - params = Bunch(p) + if 'search' in p.keys(): + search = p['search'] + else: + return self._render_response(None, BAD_REQUEST) def _clean(n): t = [] @@ -1187,10 +1311,10 @@ class LBRYDaemon(jsonrpc.JSONRPC): # log.info(str(t)) return consolidated_results - log.info('[' + str(datetime.now()) + '] Search nametrie: ' + params.search) + log.info('[' + str(datetime.now()) + '] Search nametrie: ' + search) d = self.session.wallet.get_nametrie() - d.addCallback(lambda trie: [claim for claim in trie if claim['name'].startswith(params.search) and 'txid' in claim]) + d.addCallback(lambda trie: [claim for claim in trie if claim['name'].startswith(search) and 'txid' in claim]) d.addCallback(lambda claims: claims[:self.max_search_results]) d.addCallback(resolve_claims) d.addCallback(_clean) @@ -1203,8 +1327,10 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Delete a lbry file - @param {'file_name': string} - @return: confirmation message + Args: + 'file_name': downloaded file name, string + Returns: + confirmation message """ def _disp(file_name): @@ -1222,8 +1348,20 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Make a new name claim - @param: - @return: + Args: + 'name': name to be claimed, string + 'file_path': path to file to be associated with name, string + 'bid': amount of credits to commit in this claim, float + optional 'author': author, string + optional 'title': title, description + optional 'description': content description, string + optional 'thumbnail': thumbnail image url + optional 'key_fee': key fee to be paid to publisher, float (default 0.0) + optional 'key_fee_address': address for key fee to be sent to, string (defaults on new address) + optional 'content_license': content license string + optional 'sources': alternative sources dict, keys 'lbry_sd_hash', 'btih', 'url' + Returns: + Confirmation message """ metadata_fields = ["name", "file_path", "bid", "author", "title", @@ -1255,19 +1393,25 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_abandon_name(self, p): """ - Abandon and reclaim credits from a name claim + Abandon a name and reclaim credits from the claim - @param: {'txid': string} - @return: txid + Args: + 'txid': txid of claim, string + Return: + Confirmation message """ - params = Bunch(p) + + if 'txid' in p.keys(): + txid = p['txid'] + else: + return server.failure 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 _: self.session.wallet.abandon_name(txid)) d.addCallback(_disp) d.callback(None) @@ -1275,10 +1419,14 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_get_name_claims(self): """ - Get name claims + Get my name claims - @return: list of name claims + Args: + None + Returns + list of name claims """ + def _clean(claims): for c in claims: for k in c.keys(): @@ -1294,9 +1442,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_get_time_behind_blockchain(self): """ - Get time behind blockchain + Get number of blocks behind the blockchain - @return: time behind blockchain + Args: + None + Returns: + number of blocks behind blockchain, int """ def _get_time_behind(): @@ -1316,8 +1467,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ Generate a new wallet address - @return: new wallet address + Args: + None + Returns: + new wallet address, base 58 string """ + def _disp(address): log.info("[" + str(datetime.now()) + "] Got new wallet address: " + address) return defer.succeed(address) @@ -1348,6 +1503,15 @@ class LBRYDaemon(jsonrpc.JSONRPC): # return d def jsonrpc_toggle_fetcher_verbose(self): + """ + Toggle fetcher verbose mode + + Args: + None + Returns: + Fetcher verbose status, bool + """ + if self.fetcher.verbose: self.fetcher.verbose = False else: @@ -1358,7 +1522,11 @@ class LBRYDaemon(jsonrpc.JSONRPC): def jsonrpc_check_for_new_version(self): """ Checks local version against versions in __init__.py and version.py in the lbrynet and lbryum repos - Returns true/false, true meaning that there is a new version available + + Args: + None + Returns: + true/false, true meaning that there is a new version available """ def _get_lbryum_version(): @@ -1389,12 +1557,6 @@ class LBRYDaemon(jsonrpc.JSONRPC): return _check_version() - def jsonrpc___dir__(self): - return ['is_running', 'get_settings', 'set_settings', 'start_fetcher', 'stop_fetcher', 'fetcher_status', - 'get_balance', 'stop', 'get_lbry_files', 'resolve_name', 'get', 'search_nametrie', - 'delete_lbry_file', 'check', 'publish', 'abandon_name', 'get_name_claims', - 'get_time_behind_blockchain', 'get_new_address', 'toggle_fetcher_verbose', 'check_for_new_version'] - class LBRYDaemonCommandHandler(object): def __init__(self, command): From 87e09efff57e22ded8ae6399510eaacf95b75428 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 13 Apr 2016 20:52:51 -0400 Subject: [PATCH 33/41] update lbryum version in setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e4a9432f0..1863dad82 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +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', 'six==1.9.0', 'base58'] + 'leveldb', 'lbryum>=2.6.0.1', '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', 'lbry.png'] From 8b966c61d8f6b807d230bcec1ba42e3988fb12d0 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 13 Apr 2016 22:07:27 -0400 Subject: [PATCH 34/41] check version during startup --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 96 ++++++++++++++-------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 5914048cd..537f667de 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -99,6 +99,8 @@ class LBRYDaemon(jsonrpc.JSONRPC): self.announced_startup = False self.query_handlers = {} self.ui_version = ui_version_info.replace('\n', '') + self.git_lbrynet_version = None + self.git_lbryum_version = None self.wallet_type = wallet_type self.session_settings = None self.first_run = None @@ -264,23 +266,31 @@ class LBRYDaemon(jsonrpc.JSONRPC): 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} - - 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) + r = self._get_lbry_files() return json.dumps(r) + def _get_lbryum_version(): + r = urlopen("https://raw.githubusercontent.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("'", "") + log.info("remote lbryum " + str(version) + " > local lbryum " + str(lbryum_version) + " = " + str( + version > lbryum_version)) + return version + + def _get_lbrynet_version(): + r = urlopen("https://raw.githubusercontent.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(',')) + vr = ".".join([str(x) for x in vt]) + log.info("remote lbrynet " + str(vr) + " > local lbrynet " + str(lbrynet_version) + " = " + str( + vr > lbrynet_version)) + return vr + + self.git_lbrynet_version = _get_lbrynet_version() + self.git_lbryum_version = _get_lbryum_version() + log.info("LBRY Files: " + _get_lbry_files_json()) log.info("Starting balance: " + str(self.session.wallet.wallet_balance)) @@ -869,6 +879,24 @@ class LBRYDaemon(jsonrpc.JSONRPC): return d + def _get_lbry_files(self): + 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} + + 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 r + def _render_response(self, result, code): return defer.succeed({'result': result, 'code': code}) @@ -959,12 +987,16 @@ class LBRYDaemon(jsonrpc.JSONRPC): 'lbrynet version': lbrynet version 'lbryum version': lbryum version 'ui_version': commit hash of ui + "remote_lbrynet": most recent lbrynet version available from github + "remote_lbryum": most recent lbryum version available from github """ msg = { "lbrynet_version: ": lbrynet_version, "lbryum_version: ": lbryum_version, "ui_version": self.ui_version, + "remote_lbrynet": self.git_lbrynet_version, + "remote_lbryum": self.git_lbryum_version, } log.info("[" + str(datetime.now()) + "] Get version info: " + json.dumps(msg)) @@ -1152,21 +1184,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): 'upload_allowed': bool """ - 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} - - 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(json.dumps(t)) - + r = self._get_lbry_files() log.info("[" + str(datetime.now()) + "] Get LBRY files") return self._render_response(r, OK_CODE) @@ -1529,26 +1547,10 @@ class LBRYDaemon(jsonrpc.JSONRPC): true/false, true meaning that there is a new version available """ - def _get_lbryum_version(): - r = urlopen("https://raw.githubusercontent.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("'", "") - log.info("remote lbryum " + str(version) + " > local lbryum " + str(lbryum_version) + " = " + str(version > lbryum_version)) - return version - def _get_lbrynet_version(): - r = urlopen("https://raw.githubusercontent.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(',')) - vr = ".".join([str(x) for x in vt]) - log.info("remote lbrynet " + str(vr) + " > local lbrynet " + str(lbrynet_version) + " = " + str(vr > lbrynet_version)) - return vr def _check_version(): - git_lbrynet = _get_lbrynet_version() - git_lbryum = _get_lbryum_version() - if (lbrynet_version >= git_lbrynet) and (lbryum_version >= git_lbryum): + if (lbrynet_version >= self.git_lbrynet_version) and (lbryum_version >= self.git_lbryum_version): log.info("[" + str(datetime.now()) + "] Up to date") return self._render_response(False, OK_CODE) else: From 6b9f1d519e82fde3f3ae60b6efce979ccd001dbb Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 13 Apr 2016 23:10:17 -0400 Subject: [PATCH 35/41] remove null handling used to fix a now resolved bug, update daemon_status outputs per alex's suggestions --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 537f667de..38f504800 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -229,7 +229,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): else: request.setHeader("Access-Control-Allow-Origin", "*") request.setHeader("content-type", "text/json") - if args == [{}] or args == [None]: + if args == [{}]: d = defer.maybeDeferred(function) else: d = defer.maybeDeferred(function, *args) @@ -928,13 +928,10 @@ class LBRYDaemon(jsonrpc.JSONRPC): if status_code is 'loading_wallet', also contains key 'progress': blockchain catchup progress """ - 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") - r['progress'] = self.session.wallet.catchup_progress - except: - pass + r = {'code': self.startup_status[0], 'message': self.startup_status[1], 'progress': None} + if self.startup_status[0] == 'loading_wallet': + r['message'] = r['message'] % (str(self.session.wallet.blocks_behind_alert) + " blocks behind") + r['progress'] = self.session.wallet.catchup_progress log.info("[" + str(datetime.now()) + "] daemon status: " + str(r)) return self._render_response(r, OK_CODE) From 47d897b48d26b1fd18101458b88f0c68e189063d Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 14 Apr 2016 00:29:40 -0400 Subject: [PATCH 36/41] is_lagging indicator and internet connection check -adds is_lagging indicator as a key from daemon_status, which is set to True during a phase of the startup sequence, presently only during loading_wallet if catching up with the blockchain takes longer than a minute. -checks if connected to internet before trying to start --- lbrynet/core/LBRYcrdWallet.py | 14 ++++--- lbrynet/lbrynet_daemon/LBRYDaemon.py | 4 +- lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 45 ++++++++++++++------- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/lbrynet/core/LBRYcrdWallet.py b/lbrynet/core/LBRYcrdWallet.py index c6cb8c4d9..895dbfa49 100644 --- a/lbrynet/core/LBRYcrdWallet.py +++ b/lbrynet/core/LBRYcrdWallet.py @@ -70,6 +70,8 @@ class LBRYWallet(object): self.max_expected_payment_time = datetime.timedelta(minutes=3) self.stopped = True + self.is_lagging = None + self.manage_running = False self._manage_count = 0 self._balance_refresh_time = 3 @@ -996,15 +998,17 @@ class LBRYumWallet(LBRYWallet): self._catch_up_check = None blockchain_caught_d.callback(True) elif remote_height != 0: + self.blocks_behind_alert = remote_height - local_height + if self.blocks_behind_alert > self.max_behind: + self.max_behind = self.blocks_behind_alert + self.catchup_progress = int(100 * (self.blocks_behind_alert / (5 + self.max_behind))) 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 - if self.blocks_behind_alert > self.max_behind: - self.max_behind = self.blocks_behind_alert - self.catchup_progress = int(100 * (self.blocks_behind_alert / (5 + self.max_behind))) alert.info('%d...', (remote_height - local_height)) - alert.info("Catching up: " + str(int(100 * (self.blocks_behind_alert / (5 + self.max_behind)))) + "%") + alert.info("Catching up: " + str(self.catchup_progress) + "%") + if self._caught_up_counter >= 600: + self.is_lagging = True self._caught_up_counter += 1 diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 38f504800..e0b7c92bb 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -928,10 +928,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): if status_code is 'loading_wallet', also contains key 'progress': blockchain catchup progress """ - r = {'code': self.startup_status[0], 'message': self.startup_status[1], 'progress': None} + r = {'code': self.startup_status[0], 'message': self.startup_status[1], 'progress': None, 'is_lagging': None} if self.startup_status[0] == 'loading_wallet': r['message'] = r['message'] % (str(self.session.wallet.blocks_behind_alert) + " blocks behind") r['progress'] = self.session.wallet.catchup_progress + r['is_lagging'] = self.session.wallet.is_lagging + log.info("[" + str(datetime.now()) + "] daemon status: " + str(r)) return self._render_response(r, OK_CODE) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index e509c7c81..32fc8ec9c 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -6,6 +6,8 @@ import os import shutil import webbrowser import sys +import socket + from StringIO import StringIO from zipfile import ZipFile @@ -34,6 +36,16 @@ handler = logging.handlers.RotatingFileHandler(LOG_FILENAME, maxBytes=262144, ba log.addHandler(handler) logging.basicConfig(level=logging.INFO) +REMOTE_SERVER = "www.google.com" + +def test_internet_connection(): + try: + host = socket.gethostbyname(REMOTE_SERVER) + s = socket.create_connection((host, 80), 2) + return True + except: + return False + def stop(): def _disp_shutdown(): @@ -104,6 +116,10 @@ def start(): version_dir = os.path.join(data_dir, "ui_version_history") git_version = subprocess.check_output(GIT_CMD_STRING, shell=True) + if not git_version: + log.info("You should have been notified to install xcode command line tools, once it's installed you can start LBRY") + sys.exit(0) + ui_version_info = git_version if not os.path.isdir(data_dir): @@ -113,15 +129,11 @@ def start(): os.mkdir(version_dir) if not os.path.isfile(os.path.join(version_dir, git_version)): - try: - f = open(os.path.join(version_dir, git_version), "w") - version_message = "[" + str(datetime.now()) + "] Updating UI --> " + git_version - f.write(version_message) - f.close() - log.info(version_message) - except: - log.info("You should have been notified to install xcode command line tools, once it's installed you can start LBRY") - sys.exit(0) + f = open(os.path.join(version_dir, git_version), "w") + version_message = "[" + str(datetime.now()) + "] Updating UI --> " + git_version + f.write(version_message) + f.close() + log.info(version_message) if os.path.isdir(os.path.join(data_dir, "lbry-web-ui")): shutil.rmtree(os.path.join(data_dir, "lbry-web-ui")) @@ -149,9 +161,12 @@ def start(): reactor.listenTCP(API_PORT, server.Site(root), interface=API_INTERFACE) return daemon.setup() - d = getui(args.ui) - 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() \ No newline at end of file + if test_internet_connection(): + d = getui(args.ui) + 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() + else: + log.info("Not connected to internet, unable to start") + return From 57138d9629c10565322718afb88e0fc735dad403 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 14 Apr 2016 16:50:11 -0400 Subject: [PATCH 37/41] is_lagging message --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index e0b7c92bb..c62d065b2 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -65,7 +65,7 @@ log.addHandler(handler) STARTUP_STAGES = [ ('initializing', 'Initializing...'), ('loading_db', 'Loading databases...'), - ('loading_wallet', 'Catching up with blockchain... %s'), + ('loading_wallet', 'Catching up with the blockchain... %s'), ('loading_file_manager', 'Setting up file manager'), ('loading_server', 'Starting lbrynet'), ('started', 'Started lbrynet') @@ -930,9 +930,12 @@ class LBRYDaemon(jsonrpc.JSONRPC): r = {'code': self.startup_status[0], 'message': self.startup_status[1], 'progress': None, 'is_lagging': None} if self.startup_status[0] == 'loading_wallet': - r['message'] = r['message'] % (str(self.session.wallet.blocks_behind_alert) + " blocks behind") - r['progress'] = self.session.wallet.catchup_progress r['is_lagging'] = self.session.wallet.is_lagging + if r['is_lagging'] == True: + r['message'] = "Synchronization with the blockchain is lagging... if this continues try restarting LBRY" + else: + r['message'] = r['message'] % (str(self.session.wallet.blocks_behind_alert) + " blocks behind") + r['progress'] = self.session.wallet.catchup_progress log.info("[" + str(datetime.now()) + "] daemon status: " + str(r)) return self._render_response(r, OK_CODE) From 9a26d869fe2c8e396e68147b9e35fd908f892c82 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 14 Apr 2016 17:01:05 -0400 Subject: [PATCH 38/41] better first run message --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index c62d065b2..937f4c6e3 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -683,7 +683,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _show_first_run_result(self, credits_received): if credits_received != 0.0: 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 + self.startup_message = "Thank you for testing the alpha version of LBRY! You have been given %s for free because we love you. Please hang on for a few minutes for the next block to be mined. When you refresh this page and see your credits you're ready to go!." % points_string else: self.startup_message = None From b3b5581f2d1cb7538d13dffd0802372c58f1a071 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 15 Apr 2016 19:37:27 -0400 Subject: [PATCH 39/41] don't log to console, add --no-launch flag, fix help() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit by default, the ui opens in the lbrynet-daemon startup sequence, the —no-launch flag stops the ui from launching --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 8 ++------ lbrynet/lbrynet_daemon/LBRYDaemonControl.py | 22 +++++++++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 937f4c6e3..9dff721d5 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -61,6 +61,7 @@ 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) +log.setLevel(logging.INFO) STARTUP_STAGES = [ ('initializing', 'Initializing...'), @@ -1078,12 +1079,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): """ if not p: - return self._render_response(['is_running', 'get_settings', 'set_settings', 'start_fetcher', 'stop_fetcher', - 'fetcher_status', 'get_balance', 'stop', 'get_lbry_files', 'resolve_name', - 'get', 'search_nametrie', 'delete_lbry_file', 'check', 'publish', - 'abandon_name', 'get_name_claims', 'get_time_behind_blockchain', - 'get_new_address', 'toggle_fetcher_verbose', 'check_for_new_version'], - OK_CODE) + return self._render_response(self._listFunctions(), OK_CODE) elif 'callable_during_start' in p.keys(): return self._render_response(ALLOWED_DURING_STARTUP, OK_CODE) elif 'function' in p.keys(): diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py index 32fc8ec9c..5fc6f98ff 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemonControl.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemonControl.py @@ -8,7 +8,6 @@ import webbrowser import sys import socket - from StringIO import StringIO from zipfile import ZipFile from urllib import urlopen @@ -30,14 +29,14 @@ 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) +log.setLevel(logging.INFO) REMOTE_SERVER = "www.google.com" + def test_internet_connection(): try: host = socket.gethostbyname(REMOTE_SERVER) @@ -66,16 +65,14 @@ def start(): help="lbrycrd or lbryum, default lbryum", type=str, default=DEFAULT_WALLET) - parser.add_argument("--update", - help="True or false, default true", - type=str, - default="True") 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") + parser.add_argument('--no-launch', dest='launchui', action="store_false") + parser.set_defaults(launchui=True) try: JSONRPCProxy.from_url(API_CONNECTION_STRING).is_running() @@ -85,6 +82,11 @@ def start(): pass log.info("Starting lbrynet-daemon from command line") + print "Starting lbrynet-daemon from command line" + print "To view activity, view the log file here: " + LOG_FILENAME + print "Web UI is available at http://%s:%i" %(API_INTERFACE, API_PORT) + print "JSONRPC API is available at " + API_CONNECTION_STRING + print "To quit press ctrl-c or call 'stop' via the API" args = parser.parse_args() @@ -118,6 +120,7 @@ def start(): git_version = subprocess.check_output(GIT_CMD_STRING, shell=True) if not git_version: log.info("You should have been notified to install xcode command line tools, once it's installed you can start LBRY") + print "You should have been notified to install xcode command line tools, once it's installed you can start LBRY" sys.exit(0) ui_version_info = git_version @@ -165,8 +168,11 @@ def start(): d = getui(args.ui) 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)) + if args.launchui: + d.addCallback(lambda _: webbrowser.open(UI_ADDRESS)) reactor.run() + print "\nClosing lbrynet-daemon" else: log.info("Not connected to internet, unable to start") + print "Not connected to internet, unable to start" return From bac7ea5dc05fb79825c724424986458d0de2ce32 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 15 Apr 2016 22:31:06 -0400 Subject: [PATCH 40/41] include platform information in version() --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 47 +++++++++++++++------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 9dff721d5..95340be0d 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -111,6 +111,16 @@ class LBRYDaemon(jsonrpc.JSONRPC): self.run_server = True self.session = None self.known_dht_nodes = KNOWN_DHT_NODES + self.platform_info = { + "processor": platform.processor(), + "python_version: ": platform.python_version(), + "platform": platform.platform(), + "os_release": platform.release(), + "os_system": platform.system(), + "lbrynet_version: ": lbrynet_version, + "lbryum_version: ": lbryum_version, + "ui_version": self.ui_version, + } if os.name == "nt": from lbrynet.winhelpers.knownpaths import get_path, FOLDERID, UserHandle @@ -328,20 +338,7 @@ class LBRYDaemon(jsonrpc.JSONRPC): def _initial_setup(self): 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() - - log.info("Platform: " + json.dumps(msg)) + log.info("Platform: " + json.dumps(self.platform_info)) return defer.succeed(None) def _load_daemon_conf(): @@ -987,19 +984,25 @@ class LBRYDaemon(jsonrpc.JSONRPC): Args: None Returns: - 'lbrynet version': lbrynet version - 'lbryum version': lbryum version - 'ui_version': commit hash of ui + "platform": platform string + "os_release": os release string + "os_system": os name + "lbrynet_version: ": lbrynet_version, + "lbryum_version: ": lbryum_version, + "ui_version": commit hash of ui version being used "remote_lbrynet": most recent lbrynet version available from github "remote_lbryum": most recent lbryum version available from github """ msg = { - "lbrynet_version: ": lbrynet_version, - "lbryum_version: ": lbryum_version, - "ui_version": self.ui_version, - "remote_lbrynet": self.git_lbrynet_version, - "remote_lbryum": self.git_lbryum_version, + 'platform': self.platform_info['platform'], + 'os_release': self.platform_info['os_release'], + 'os_system': self.platform_info['os_system'], + 'lbrynet_version': lbrynet_version, + 'lbryum_version': lbryum_version, + 'ui_version': self.ui_version, + 'remote_lbrynet': self.git_lbrynet_version, + 'remote_lbryum': self.git_lbryum_version } log.info("[" + str(datetime.now()) + "] Get version info: " + json.dumps(msg)) From cdab127b98422a3e712354df2d5920a080d72c8c Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 15 Apr 2016 23:57:52 -0400 Subject: [PATCH 41/41] have separate handlers for uris on linux and os x --- lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py b/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py index 18e5ae366..c748a1015 100644 --- a/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py +++ b/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py @@ -45,7 +45,7 @@ class LBRYURIHandler(object): else: raise Timeout("Timed out trying to start LBRY daemon") - def handle(self, lbry_name): + def handle_osx(self, lbry_name): lbry_process = [d for d in subprocess.Popen(['ps','aux'], stdout=subprocess.PIPE).stdout.readlines() if 'LBRY.app' in d and 'LBRYURIHandler' not in d] try: @@ -62,17 +62,33 @@ class LBRYURIHandler(object): started = True if lbry_name == "lbry" or lbry_name == "" and not started: - webbrowser.get('safari').open(UI_ADDRESS) + webbrowser.open(UI_ADDRESS) else: - webbrowser.get('safari').open(UI_ADDRESS + "/view?name=" + lbry_name) + webbrowser.open(UI_ADDRESS + "/view?name=" + lbry_name) + + def handle_linux(self, lbry_name): + try: + is_running = self.daemon.is_running() + if not is_running: + sys.exit(0) + except: + sys.exit(0) + + if lbry_name == "lbry": + webbrowser.open(UI_ADDRESS) + else: + webbrowser.open(UI_ADDRESS + "/view?name=" + lbry_name) + def main(args): if len(args) != 1: args = ['lbry://lbry'] name = args[0][7:] - LBRYURIHandler().handle(lbry_name=name) - + if sys.platform == "darwin": + LBRYURIHandler().handle_osx(lbry_name=name) + else: + LBRYURIHandler().handle_linux(lbry_name=name) if __name__ == "__main__": main(sys.argv[1:])