lbry-sdk/lbrynet/lbrynet_daemon/LBRYPublisher.py

165 lines
5.9 KiB
Python
Raw Normal View History

import logging
import mimetypes
import os
import sys
2016-08-09 18:26:34 +02:00
import random
from appdirs import user_data_dir
2016-01-21 04:00:28 +01:00
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.metadata.LBRYMetadata import Metadata
2016-01-21 04:00:28 +01:00
from lbrynet.lbryfilemanager.LBRYFileDownloader import ManagedLBRYFileDownloader
2016-08-10 14:44:41 +02:00
from lbrynet import reflector
2016-08-09 18:26:34 +02:00
from lbrynet.conf import LOG_FILE_NAME, REFLECTOR_SERVERS
from twisted.internet import threads, defer, reactor
2016-01-21 04:00:28 +01:00
2016-06-07 10:19:51 +02:00
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)
2016-06-07 10:30:22 +02:00
lbrynet_log = os.path.join(log_dir, LOG_FILE_NAME)
2016-01-21 04:00:28 +01:00
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.publish_name = None
self.bid_amount = None
self.verified = False
self.lbry_file = None
self.txid = None
2016-07-27 03:24:58 +02:00
self.stream_hash = None
2016-08-09 18:26:34 +02:00
reflector_server = random.choice(REFLECTOR_SERVERS)
self.reflector_server, self.reflector_port = reflector_server[0], reflector_server[1]
self.metadata = {}
2016-01-21 04:00:28 +01:00
def start(self, name, file_path, bid, metadata):
2016-08-11 02:04:03 +02:00
log.info('Starting publish for %s', name)
2016-01-21 04:00:28 +01:00
def _show_result():
2016-08-11 02:04:03 +02:00
log.info("Success! Published %s --> lbry://%s txid: %s", self.file_name, self.publish_name, self.txid)
return defer.succeed(self.txid)
2016-01-21 04:00:28 +01:00
self.publish_name = name
self.file_path = file_path
self.bid_amount = bid
self.metadata = metadata
2016-01-21 04:00:28 +01:00
2016-08-23 01:55:08 +02:00
if os.name == "nt":
file_mode = 'rb'
else:
file_mode = 'r'
2016-01-21 04:00:28 +01:00
d = self._check_file_path(self.file_path)
d.addCallback(lambda _: create_lbry_file(self.session, self.lbry_file_manager,
2016-08-23 01:55:08 +02:00
self.file_name, open(self.file_path, file_mode)))
2016-01-21 04:00:28 +01:00
d.addCallback(self.add_to_lbry_files)
d.addCallback(lambda _: self._create_sd_blob())
d.addCallback(lambda _: self._claim_name())
2016-07-27 03:24:58 +02:00
d.addCallback(lambda _: self.set_status())
2016-08-09 18:07:26 +02:00
d.addCallback(lambda _: self.start_reflector())
2016-01-21 04:00:28 +01:00
d.addCallbacks(lambda _: _show_result(), self._show_publish_error)
return d
2016-08-09 18:07:26 +02:00
def start_reflector(self):
2016-08-11 07:06:51 +02:00
reflector_server = random.choice(REFLECTOR_SERVERS)
reflector_address, reflector_port = reflector_server[0], reflector_server[1]
2016-08-21 06:58:25 +02:00
log.info("Reflecting new publication")
2016-08-10 14:44:41 +02:00
factory = reflector.ClientFactory(
self.session.blob_manager,
self.lbry_file_manager.stream_info_manager,
self.stream_hash
)
2016-08-11 07:06:51 +02:00
d = reactor.resolve(reflector_address)
d.addCallback(lambda ip: reactor.connectTCP(ip, reflector_port, factory))
d.addCallback(lambda _: factory.finished_deferred)
return d
2016-08-09 18:07:26 +02:00
2016-01-21 04:00:28 +01:00
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)
2016-07-27 03:24:58 +02:00
def set_lbry_file(self, lbry_file_downloader):
2016-01-21 04:00:28 +01:00
self.lbry_file = lbry_file_downloader
2016-07-27 03:24:58 +02:00
return defer.succeed(None)
2016-01-21 04:00:28 +01:00
def add_to_lbry_files(self, stream_hash):
2016-07-27 03:24:58 +02:00
self.stream_hash = stream_hash
2016-01-21 04:00:28 +01:00
prm = PaymentRateManager(self.session.base_payment_rate_manager)
d = self.lbry_file_manager.add_lbry_file(stream_hash, prm)
2016-07-27 03:24:58 +02:00
d.addCallback(self.set_lbry_file)
2016-01-21 04:00:28 +01:00
return d
def _create_sd_blob(self):
2016-08-11 02:04:03 +02:00
log.debug('Creating stream descriptor blob')
d = publish_sd_blob(self.lbry_file_manager.stream_info_manager,
self.session.blob_manager,
2016-01-21 04:00:28 +01:00
self.lbry_file.stream_hash)
def set_sd_hash(sd_hash):
2016-08-11 02:04:03 +02:00
log.debug('stream descriptor hash: %s', sd_hash)
if 'sources' not in self.metadata:
self.metadata['sources'] = {}
self.metadata['sources']['lbry_sd_hash'] = sd_hash
2016-01-21 04:00:28 +01:00
d.addCallback(set_sd_hash)
return d
2016-07-27 03:24:58 +02:00
def set_status(self):
2016-08-11 02:04:03 +02:00
log.debug('Setting status')
2016-07-27 03:24:58 +02:00
d = self.lbry_file_manager.change_lbry_file_status(self.lbry_file, ManagedLBRYFileDownloader.STATUS_FINISHED)
d.addCallback(lambda _: self.lbry_file.restore())
return d
2016-01-21 04:00:28 +01:00
def _claim_name(self):
2016-08-11 02:04:03 +02:00
log.debug('Claiming name')
self._update_metadata()
m = Metadata(self.metadata)
def set_tx_hash(txid):
2016-08-11 02:04:03 +02:00
log.debug('Name claimed using txid: %s', txid)
self.txid = txid
2016-01-21 04:00:28 +01:00
d = self.wallet.claim_name(self.publish_name, self.bid_amount, m)
2016-01-21 04:00:28 +01:00
d.addCallback(set_tx_hash)
return d
2016-08-11 02:04:03 +02:00
def _update_metadata(self):
filename = os.path.join(self.lbry_file.download_directory, self.lbry_file.file_name)
self.metadata['content_type'] = get_content_type(filename)
self.metadata['ver'] = Metadata.current_version
2016-08-11 02:04:03 +02:00
2016-01-21 04:00:28 +01:00
def _show_publish_error(self, err):
2016-04-02 04:11:11 +02:00
log.info(err.getTraceback())
2016-01-21 04:00:28 +01:00
message = "An error occurred publishing %s to %s. Error: %s."
if err.check(InsufficientFundsError):
error_message = "Insufficient funds"
else:
error_message = err.getErrorMessage()
2016-07-12 03:57:34 +02:00
log.error(error_message)
2016-01-21 04:00:28 +01:00
log.error(message, str(self.file_name), str(self.publish_name), err.getTraceback())
2016-07-12 03:57:34 +02:00
return defer.fail(Exception("Publish failed"))
2016-08-11 02:04:03 +02:00
def get_content_type(filename):
return mimetypes.guess_type(filename)[0]