mirror of
https://github.com/LBRYFoundation/lbry-sdk.git
synced 2025-08-26 23:13:24 +00:00
Adds a daemon for lbrynet. Currently commands are limited the following: download_name(name) resolve_name(name) get_downloads stop This allows other programs to easily interact with lbrynet, such as LBRYURIHandler. LBRYURIHandler can be built with py2app, the resulting plist file must be edited in the same way the committed plist file has been edited. When built and installed to the /Applications folder lbry:// domain names will download and open the corresponding file so long as the daemon is running.
282 lines
No EOL
11 KiB
Python
282 lines
No EOL
11 KiB
Python
import os
|
|
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.core.client.AutoDownloader import GetStream
|
|
from lbrynet.core.utils import generate_id
|
|
from lbrynet.lbrynet_console.LBRYSettings import LBRYSettings
|
|
from lbrynet.conf import MIN_BLOB_DATA_PAYMENT_RATE
|
|
from lbrynet.core.StreamDescriptor import StreamDescriptorIdentifier
|
|
from lbrynet.core.Session import LBRYSession
|
|
from lbrynet.core.PTCWallet import PTCWallet
|
|
from lbrynet.core.LBRYcrdWallet import LBRYcrdWallet
|
|
from lbrynet.lbryfilemanager.LBRYFileManager import LBRYFileManager
|
|
from lbrynet.lbryfile.LBRYFileMetadataManager import DBLBRYFileMetadataManager, TempLBRYFileMetadataManager
|
|
from twisted.web import xmlrpc, server
|
|
from twisted.internet import defer, threads, reactor
|
|
from datetime import datetime
|
|
|
|
|
|
class LBRYDaemon(xmlrpc.XMLRPC):
|
|
"""
|
|
LBRYnet daemon
|
|
"""
|
|
|
|
def setup(self):
|
|
def _set_vars():
|
|
self.run_server = True
|
|
self.session = None
|
|
self.known_dht_nodes = [('104.236.42.182', 4000)]
|
|
self.db_dir = os.path.join(os.path.expanduser("~"), ".lbrynet")
|
|
self.blobfile_dir = os.path.join(self.db_dir, "blobfiles")
|
|
self.peer_port = 3333
|
|
self.dht_node_port = 4444
|
|
self.first_run = False
|
|
self.current_db_revision = 1
|
|
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")
|
|
else:
|
|
self.download_directory = os.path.join(os.path.expanduser("~"), 'Downloads')
|
|
self.wallet_dir = os.path.join(os.path.expanduser("~"), ".lbrycrd")
|
|
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.download_deferreds = []
|
|
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 = "lbrycrd"
|
|
self.lbrycrd_dir = os.path.join(os.path.expanduser("~"), ".lbrycrd")
|
|
self.lbrycrd_conf = os.path.join(self.lbrycrd_dir, "lbrycrd.conf")
|
|
self.rpc_conn = None
|
|
return defer.succeed(None)
|
|
|
|
d = defer.Deferred()
|
|
d.addCallback(lambda _: _set_vars())
|
|
d.addCallback(lambda _: self._get_settings())
|
|
d.addCallback(lambda _: self.get_lbrycrdd_path())
|
|
d.addCallback(lambda _: self._get_session())
|
|
d.addCallback(lambda _: add_lbry_file_to_sd_identifier(self.sd_identifier))
|
|
d.addCallback(lambda _: self._setup_stream_identifier())
|
|
d.addCallback(lambda _: self._setup_lbry_file_manager())
|
|
d.addCallback(lambda _: self._setup_lbry_file_opener())
|
|
d.callback(None)
|
|
|
|
return defer.succeed(None)
|
|
|
|
def _get_settings(self):
|
|
d = self.settings.start()
|
|
d.addCallback(lambda _: self.settings.get_lbryid())
|
|
d.addCallback(self.set_lbryid)
|
|
d.addCallback(lambda _: self.get_lbrycrdd_path())
|
|
return d
|
|
|
|
def set_lbryid(self, lbryid):
|
|
if lbryid is None:
|
|
return self._make_lbryid()
|
|
else:
|
|
self.lbryid = lbryid
|
|
|
|
def _make_lbryid(self):
|
|
self.lbryid = generate_id()
|
|
d = self.settings.save_lbryid(self.lbryid)
|
|
return d
|
|
|
|
def _setup_lbry_file_manager(self):
|
|
self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir)
|
|
d = self.lbry_file_metadata_manager.setup()
|
|
|
|
def set_lbry_file_manager():
|
|
self.lbry_file_manager = LBRYFileManager(self.session, self.lbry_file_metadata_manager, self.sd_identifier)
|
|
return self.lbry_file_manager.setup()
|
|
|
|
d.addCallback(lambda _: set_lbry_file_manager())
|
|
|
|
return d
|
|
|
|
def _get_session(self):
|
|
def get_default_data_rate():
|
|
d = self.settings.get_default_data_payment_rate()
|
|
d.addCallback(lambda rate: {"default_data_payment_rate":
|
|
rate if rate is not None else MIN_BLOB_DATA_PAYMENT_RATE})
|
|
return d
|
|
|
|
def get_wallet():
|
|
if self.wallet_type == "lbrycrd":
|
|
lbrycrdd_path = None
|
|
if self.start_lbrycrdd is True:
|
|
lbrycrdd_path = self.lbrycrdd_path
|
|
if not lbrycrdd_path:
|
|
lbrycrdd_path = self.default_lbrycrdd_path
|
|
d = defer.succeed(LBRYcrdWallet(self.db_dir, wallet_dir=self.lbrycrd_dir, wallet_conf=self.lbrycrd_conf,
|
|
lbrycrdd_path=lbrycrdd_path))
|
|
else:
|
|
d = defer.succeed(PTCWallet(self.db_dir))
|
|
d.addCallback(lambda wallet: {"wallet": wallet})
|
|
return d
|
|
|
|
d1 = get_default_data_rate()
|
|
d2 = get_wallet()
|
|
|
|
def combine_results(results):
|
|
r = {}
|
|
for success, result in results:
|
|
if success is True:
|
|
r.update(result)
|
|
return r
|
|
|
|
def create_session(results):
|
|
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.rpc_conn = self.session.wallet.get_rpc_conn_x()
|
|
|
|
dl = defer.DeferredList([d1, d2], fireOnOneErrback=True)
|
|
|
|
dl.addCallback(combine_results)
|
|
|
|
dl.addCallback(create_session)
|
|
|
|
dl.addCallback(lambda _: self.session.setup())
|
|
|
|
return dl
|
|
|
|
def get_lbrycrdd_path(self):
|
|
def get_lbrycrdd_path_conf_file():
|
|
lbrycrdd_path_conf_path = os.path.join(os.path.expanduser("~"), ".lbrycrddpath.conf")
|
|
if not os.path.exists(lbrycrdd_path_conf_path):
|
|
return ""
|
|
lbrycrdd_path_conf = open(lbrycrdd_path_conf_path)
|
|
lines = lbrycrdd_path_conf.readlines()
|
|
return lines
|
|
|
|
d = threads.deferToThread(get_lbrycrdd_path_conf_file)
|
|
|
|
def load_lbrycrdd_path(conf):
|
|
for line in conf:
|
|
if len(line.strip()) and line.strip()[0] != "#":
|
|
self.lbrycrdd_path = line.strip()
|
|
print self.lbrycrdd_path
|
|
|
|
d.addCallback(load_lbrycrdd_path)
|
|
return d
|
|
|
|
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.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,
|
|
self.session.wallet)
|
|
self.sd_identifier.add_stream_downloader_factory(LBRYFileStreamType, file_opener_factory)
|
|
return defer.succeed(None)
|
|
|
|
def _setup_lbry_file_manager(self):
|
|
self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir)
|
|
d = self.lbry_file_metadata_manager.setup()
|
|
|
|
def set_lbry_file_manager():
|
|
self.lbry_file_manager = LBRYFileManager(self.session, self.lbry_file_metadata_manager, self.sd_identifier)
|
|
return self.lbry_file_manager.setup()
|
|
|
|
d.addCallback(lambda _: set_lbry_file_manager())
|
|
|
|
return d
|
|
|
|
def _setup_lbry_file_opener(self):
|
|
|
|
downloader_factory = LBRYFileOpenerFactory(self.session.peer_finder, self.session.rate_limiter,
|
|
self.session.blob_manager, self.stream_info_manager,
|
|
self.session.wallet)
|
|
self.sd_identifier.add_stream_downloader_factory(LBRYFileStreamType, downloader_factory)
|
|
return defer.succeed(True)
|
|
|
|
def xmlrpc_getbalance(self):
|
|
"""
|
|
Get LBC balance
|
|
"""
|
|
return str(self.session.wallet.wallet_balance)
|
|
|
|
def xmlrpc_stop(self):
|
|
"""
|
|
Stop the reactor
|
|
"""
|
|
|
|
reactor.stop()
|
|
return defer.succeed('Stopping')
|
|
|
|
def xmlrpc_resolve_name(self, name):
|
|
"""
|
|
Resolve stream info from a LBRY uri
|
|
"""
|
|
|
|
def _disp(info):
|
|
print '[' + str(datetime.now()) + ']' + ' Resolved info: ' + str(info)
|
|
return info
|
|
|
|
d = defer.Deferred()
|
|
d.addCallback(lambda _: self.session.wallet.get_stream_info_for_name(name))
|
|
d.addCallback(_disp)
|
|
d.callback(None)
|
|
return d
|
|
|
|
def xmlrpc_get_downloads(self):
|
|
"""
|
|
Get downloads
|
|
"""
|
|
|
|
downloads = [{'stream_hash': stream.stream_hash,
|
|
'path': os.path.join(stream.downloader.download_directory, stream.downloader.file_name)}
|
|
for stream in self.download_deferreds]
|
|
return downloads
|
|
|
|
def xmlrpc_download_name(self, name):
|
|
"""
|
|
Download stream from a LBRY uri
|
|
"""
|
|
|
|
def _disp():
|
|
try:
|
|
stream = self.download_deferreds[-1]
|
|
print '[' + str(datetime.now()) + ']' + ' Downloading: ' + str(stream.stream_hash)
|
|
return defer.succeed(None)
|
|
except:
|
|
pass
|
|
|
|
stream = GetStream(None, self.sd_identifier, self.session, self.session.wallet,
|
|
self.lbry_file_manager, 25.0, console_on=False, pay_key=True)
|
|
self.download_deferreds.append(stream)
|
|
|
|
d = defer.Deferred()
|
|
d.addCallback(lambda _: self.session.wallet.get_stream_info_for_name(name))
|
|
d.addCallback(lambda stream_info: stream.start(stream_info))
|
|
d.addCallback(lambda _: _disp())
|
|
d.callback(None)
|
|
msg = {'ts': datetime.now(),'name': name}
|
|
return defer.succeed(str(msg))
|
|
|
|
def main():
|
|
daemon = LBRYDaemon()
|
|
daemon.setup()
|
|
reactor.listenTCP(7080, server.Site(daemon))
|
|
reactor.run()
|
|
|
|
if __name__ == '__main__':
|
|
main() |