From 23b6a8c495a039f2a65e9f1d43a5f741914583d3 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 20 Jan 2016 22:00:28 -0500 Subject: [PATCH 1/4] Add publish Add publish function --- lbrynet/lbrynet_daemon/LBRYDaemon.py | 58 ++++++++++- lbrynet/lbrynet_daemon/LBRYPublisher.py | 124 ++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 lbrynet/lbrynet_daemon/LBRYPublisher.py diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 8c7eede53..092f3120f 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -3,6 +3,7 @@ from lbrynet.lbryfile.StreamDescriptor import LBRYFileStreamType from lbrynet.lbryfile.client.LBRYFileDownloader import LBRYFileSaverFactory, LBRYFileOpenerFactory from lbrynet.lbryfile.client.LBRYFileOptions import add_lbry_file_to_sd_identifier from lbrynet.lbrynet_daemon.LBRYDownloader import GetStream, FetcherDaemon +from lbrynet.lbrynet_daemon.LBRYPublisher import Publisher from lbrynet.core.utils import generate_id from lbrynet.lbrynet_console.LBRYSettings import LBRYSettings from lbrynet.conf import MIN_BLOB_DATA_PAYMENT_RATE @@ -28,13 +29,10 @@ log = logging.getLogger(__name__) #TODO add login credentials in a conf file #issues with delete: -#TODO when stream is complete the generated file doesn't delete, but blobs do #TODO when stream is stopped the generated file is deleted #functions to add: -#TODO publish #TODO send credits to address -#TODO get new address #TODO alert if your copy of a lbry file is out of date with the name record @@ -126,7 +124,7 @@ class LBRYDaemon(xmlrpc.XMLRPC): if self.session is not None: d = self.session.shut_down() else: - d = defer.Deferred() + d = defer.succeed(True) return d def _update_settings(self): @@ -574,7 +572,7 @@ class LBRYDaemon(xmlrpc.XMLRPC): print str(err.getTraceback()) return err d = defer.Deferred() - d.addCallback(lambda _: webbrowser.open("https://rawgit.com/jackrobison/lbry.io/local/view/page/demo.html")) + d.addCallback(lambda _: webbrowser.open("https://cdn.rawgit.com/jackrobison/lbry.io/local/view/page/demo.html")) d.addErrback(_disp_err) d.callback(None) @@ -651,6 +649,56 @@ class LBRYDaemon(xmlrpc.XMLRPC): return d + def xmlrpc_publish(self, metadata): + metadata = json.loads(metadata) + + required = ['name', 'file_path', 'bid'] + + for r in required: + if not r in metadata.keys(): + return defer.fail() + + # if not os.path.isfile(metadata['file_path']): + # return defer.fail() + + if not type(metadata['bid']) is float and metadata['bid'] > 0.0: + return defer.fail() + + name = metadata['name'] + file_path = metadata['file_path'] + bid = metadata['bid'] + + if 'title' in metadata.keys(): + title = metadata['title'] + else: + title = None + + if 'description' in metadata.keys(): + description = metadata['description'] + else: + description = None + + if 'thumbnail' in metadata.keys(): + thumbnail = metadata['thumbnail'] + else: + thumbnail = None + + if 'key_fee' in metadata.keys(): + if not 'key_fee_address' in metadata.keys(): + return defer.fail() + key_fee = metadata['key_fee'] + else: + key_fee = None + + if 'key_fee_address' in metadata.keys(): + key_fee_address = metadata['key_fee_address'] + else: + key_fee_address = None + + p = Publisher(self.session, self.lbry_file_manager, self.session.wallet) + d = p.start(name, file_path, bid, title, description, thumbnail, key_fee, key_fee_address) + + return d def main(): daemon = LBRYDaemon() diff --git a/lbrynet/lbrynet_daemon/LBRYPublisher.py b/lbrynet/lbrynet_daemon/LBRYPublisher.py new file mode 100644 index 000000000..4856fd4e7 --- /dev/null +++ b/lbrynet/lbrynet_daemon/LBRYPublisher.py @@ -0,0 +1,124 @@ +from lbrynet.core.Error import InsufficientFundsError +from lbrynet.lbryfilemanager.LBRYFileCreator import create_lbry_file +from lbrynet.lbryfile.StreamDescriptor import publish_sd_blob +from lbrynet.core.PaymentRateManager import PaymentRateManager +from lbrynet.lbryfilemanager.LBRYFileDownloader import ManagedLBRYFileDownloader +from twisted.internet import threads, defer +import os +import logging +from datetime import datetime + + +log = logging.getLogger(__name__) + + +class Publisher(object): + def __init__(self, session, lbry_file_manager, wallet): + self.session = session + self.lbry_file_manager = lbry_file_manager + self.wallet = wallet + self.received_file_name = False + self.file_path = None + self.file_name = None + self.thumbnail = None + self.title = None + self.publish_name = None + self.bid_amount = None + self.key_fee = None + self.key_fee_address = None + self.key_fee_address_chosen = False + self.description = None + self.verified = False + self.lbry_file = None + self.sd_hash = None + self.tx_hash = None + + def start(self, name, file_path, bid, title=None, description=None, thumbnail=None, + key_fee=None, key_fee_address=None): + + def _show_result(): + message = "[" + str(datetime.now()) + " ] Published " + self.file_name + " --> lbry://" + \ + str(self.publish_name) + " with txid: " + str(self.tx_hash) + print message + return defer.succeed(message) + + self.publish_name = name + self.file_path = file_path + self.bid_amount = bid + self.title = title + self.description = description + self.thumbnail = thumbnail + self.key_fee = key_fee + self.key_fee_address = key_fee_address + + d = self._check_file_path(self.file_path) + d.addCallback(lambda _: create_lbry_file(self.session, self.lbry_file_manager, + self.file_name, open(self.file_path))) + d.addCallback(self.add_to_lbry_files) + d.addCallback(lambda _: self._create_sd_blob()) + d.addCallback(lambda _: self._claim_name()) + d.addCallbacks(lambda _: _show_result(), self._show_publish_error) + + return d + + def _check_file_path(self, file_path): + def check_file_threaded(): + f = open(file_path) + f.close() + self.file_name = os.path.basename(self.file_path) + return True + return threads.deferToThread(check_file_threaded) + + def _get_new_address(self): + d = self.wallet.get_new_address() + + def set_address(address): + self.key_fee_address = address + return True + + d.addCallback(set_address) + return d + + def set_status(self, lbry_file_downloader): + self.lbry_file = lbry_file_downloader + d = self.lbry_file_manager.change_lbry_file_status(self.lbry_file, ManagedLBRYFileDownloader.STATUS_FINISHED) + d.addCallback(lambda _: lbry_file_downloader.restore()) + return d + + def add_to_lbry_files(self, stream_hash): + prm = PaymentRateManager(self.session.base_payment_rate_manager) + d = self.lbry_file_manager.add_lbry_file(stream_hash, prm) + d.addCallback(self.set_status) + return d + + def _create_sd_blob(self): + d = publish_sd_blob(self.lbry_file_manager.stream_info_manager, self.session.blob_manager, + self.lbry_file.stream_hash) + + def set_sd_hash(sd_hash): + self.sd_hash = sd_hash + + d.addCallback(set_sd_hash) + return d + + def _claim_name(self): + 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) + + def set_tx_hash(tx_hash): + self.tx_hash = tx_hash + + d.addCallback(set_tx_hash) + return d + + def _show_publish_error(self, err): + message = "An error occurred publishing %s to %s. Error: %s." + if err.check(InsufficientFundsError): + error_message = "Insufficient funds" + else: + d = defer.succeed(True) + error_message = err.getErrorMessage() + print message % (str(self.file_name), str(self.publish_name), error_message) + log.error(message, str(self.file_name), str(self.publish_name), err.getTraceback()) + return d From 9ef9220689580a0f1bcb0d9888aaffebdaebd23b Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 20 Jan 2016 22:01:03 -0500 Subject: [PATCH 2/4] Add thumbnail option to name claim Add thumbnail option to name claim --- lbrynet/core/LBRYcrdWallet.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lbrynet/core/LBRYcrdWallet.py b/lbrynet/core/LBRYcrdWallet.py index aff9fd6ed..3a773e8f3 100644 --- a/lbrynet/core/LBRYcrdWallet.py +++ b/lbrynet/core/LBRYcrdWallet.py @@ -294,7 +294,7 @@ class LBRYcrdWallet(object): return d def claim_name(self, name, sd_hash, amount, description=None, key_fee=None, - key_fee_address=None): + key_fee_address=None, thumbnail=None): value = {"stream_hash": sd_hash} if description is not None: value['description'] = description @@ -302,6 +302,8 @@ class LBRYcrdWallet(object): value['key_fee'] = key_fee if key_fee_address is not None: value['key_fee_address'] = key_fee_address + if thumbnail is not None: + value['thumbnail'] = thumbnail d = threads.deferToThread(self._claim_name, name, json.dumps(value), amount) def _save_metadata(txid): From 574cd304e39b74ee4dbd7a7902d0e941d899351f Mon Sep 17 00:00:00 2001 From: jackrobison Date: Wed, 20 Jan 2016 22:52:58 -0500 Subject: [PATCH 3/4] Test ability to download from lbrynet This tries to download a small image with a five minute timeout. After this, the bot waits ten minutes and tries again. Any failures get posted to slack. --- tests/lbrynet_test_bot.py | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tests/lbrynet_test_bot.py diff --git a/tests/lbrynet_test_bot.py b/tests/lbrynet_test_bot.py new file mode 100644 index 000000000..a76a366d8 --- /dev/null +++ b/tests/lbrynet_test_bot.py @@ -0,0 +1,60 @@ +import xmlrpclib +import json +from datetime import datetime +from time import sleep +from slackclient import SlackClient + +def get_conf(): + f = open('testbot.conf', 'r') + token = f.readline().replace('\n', '') + channel = f.readline().replace('\n', '') + f.close() + return token, channel + +def test_lbrynet(lbry, slack, channel): + logfile = open('lbrynet_test_log.txt', 'a') + + try: + path = lbry.get('testlbrynet')['path'] + except: + msg = '[' + str(datetime.now()) + '] ! Failed to obtain LBRYnet test file' + slack.rtm_connect() + slack.rtm_send_message(channel, msg) + print msg + logfile.write(msg + '\n') + + file_name = path.split('/')[len(path.split('/'))-1] + + for n in range(10): + files = [f for f in lbry.get_lbry_files() if (json.loads(f)['file_name'] == file_name) and json.loads(f)['completed']] + if files: + break + sleep(30) + + if files: + msg = '[' + str(datetime.now()) + '] LBRYnet download test successful' + slack.rtm_connect() + # slack.rtm_send_message(channel, msg) + print msg + logfile.write(msg + '\n') + + else: + msg = '[' + str(datetime.now()) + '] ! Failed to obtain LBRYnet test file' + slack.rtm_connect() + slack.rtm_send_message(channel, msg) + print msg + logfile.write(msg + '\n') + + lbry.delete_lbry_file('test.jpg') + logfile.close() + +token, channel = get_conf() + +sc = SlackClient(token) +sc.rtm_connect() +print 'Connected to slack' +daemon = xmlrpclib.ServerProxy("http://localhost:7080") + +while True: + test_lbrynet(daemon, sc, channel) + sleep(600) From 1e73b2437df014ba1b02ebe1f553e321760bb4fb Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 22 Jan 2016 09:44:38 -0500 Subject: [PATCH 4/4] Update daemon and uri handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add command to stop daemon from the terminal If lbrynet-daemon isn’t running the uri handler will now redirect to lbry.io/get --- lbrynet/lbrynet_daemon/LBRYDaemonStopper.py | 21 +++++++++++++++++++ .../LBRYURIHandler/LBRYURIHandler.py | 10 +++++++-- setup.py | 3 ++- 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 lbrynet/lbrynet_daemon/LBRYDaemonStopper.py diff --git a/lbrynet/lbrynet_daemon/LBRYDaemonStopper.py b/lbrynet/lbrynet_daemon/LBRYDaemonStopper.py new file mode 100644 index 000000000..4e42708e9 --- /dev/null +++ b/lbrynet/lbrynet_daemon/LBRYDaemonStopper.py @@ -0,0 +1,21 @@ +import xmlrpclib + + +def main(): + daemon = xmlrpclib.ServerProxy("http://localhost:7080/") + try: + b = daemon.get_balance() + is_running = True + except: + is_running = False + + if is_running: + try: + daemon.stop() + except: + print "LBRYnet daemon stopped" + else: + print "LBRYnet daemon wasn't running" + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py b/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py index 153b6eb95..e4e66a500 100644 --- a/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py +++ b/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py @@ -15,11 +15,17 @@ def main(args): daemon = xmlrpclib.ServerProxy('http://localhost:7080/') + try: + b = daemon.get_balance() + is_running = True + except: + webbrowser.open('http://lbry.io/get') + is_running = False + if len(args) > 1: print 'Too many args', args - else: - + elif is_running: if args[0][7:] == 'lbry': daemon.render_gui() diff --git a/setup.py b/setup.py index 9caa0e8eb..948dff97d 100644 --- a/setup.py +++ b/setup.py @@ -22,6 +22,7 @@ setup(name='lbrynet', 'lbrynet-lookup-hosts-for-hash = lbrynet.dht_scripts:get_hosts_for_hash_in_dht', 'lbrynet-announce_hash_to_dht = lbrynet.dht_scripts:announce_hash_to_dht', 'lbrynet-daemon = lbrynet.lbrynet_daemon.LBRYDaemon:main', + 'stop-lbrynet-daemon = lbrynet.lbrynet_daemon.LBRYDaemonStopper:main', ] }, data_files=[ @@ -43,4 +44,4 @@ setup(name='lbrynet', ] ) ] - ) + ) \ No newline at end of file