diff --git a/lbrynet/lbryfilemanager/LBRYFileManager.py b/lbrynet/lbryfilemanager/LBRYFileManager.py index ed4c75a79..fb14ec199 100644 --- a/lbrynet/lbryfilemanager/LBRYFileManager.py +++ b/lbrynet/lbryfilemanager/LBRYFileManager.py @@ -3,17 +3,19 @@ Keep track of which LBRY Files are downloading and store their LBRY File specifi """ import logging - -from twisted.enterprise import adbapi - +import datetime import os import sys + +from twisted.internet.task import LoopingCall +from twisted.enterprise import adbapi +from twisted.internet import defer, task, reactor +from twisted.python.failure import Failure + from lbrynet.lbryfilemanager.LBRYFileDownloader import ManagedLBRYFileDownloader from lbrynet.lbryfilemanager.LBRYFileDownloader import ManagedLBRYFileDownloaderFactory from lbrynet.lbryfile.StreamDescriptor import LBRYFileStreamType from lbrynet.core.PaymentRateManager import PaymentRateManager -from twisted.internet import defer, task, reactor -from twisted.python.failure import Failure from lbrynet.cryptstream.client.CryptStreamDownloader import AlreadyStoppedError, CurrentlyStoppingError from lbrynet.core.sqlite_helpers import rerun_if_locked @@ -32,6 +34,7 @@ class LBRYFileManager(object): self.sd_identifier = sd_identifier self.lbry_files = [] self.sql_db = None + self.check_exists_loop = LoopingCall(self.check_files_exist) if sys.platform.startswith("darwin"): self.download_directory = os.path.join(os.path.expanduser("~"), 'Downloads') else: @@ -39,11 +42,25 @@ class LBRYFileManager(object): log.debug("Download directory for LBRYFileManager: %s", str(self.download_directory)) def setup(self): + self.check_exists_loop.start(1) + d = self._open_db() d.addCallback(lambda _: self._add_to_sd_identifier()) d.addCallback(lambda _: self._start_lbry_files()) return d + def check_files_exist(self): + def _disp(deleted_files): + if deleted_files[0][0]: + for file in bad_files: + print "[" + str(datetime.datetime.now()) + "] Detected " + file.file_name + " was deleted, removing from file manager" + + bad_files = [lbry_file for lbry_file in self.lbry_files + if lbry_file.completed == True and + os.path.isfile(os.path.join(self.download_directory, lbry_file.file_name)) == False] + d = defer.DeferredList([self.delete_lbry_file(lbry_file) for lbry_file in bad_files], consumeErrors=True) + d.addCallback(lambda files: _disp(files) if len(files) else defer.succeed(None)) + def get_lbry_file_status(self, lbry_file): return self._get_lbry_file_status(lbry_file.rowid) @@ -152,6 +169,8 @@ class LBRYFileManager(object): return defer.fail(Failure(ValueError("Could not find that LBRY file"))) def stop(self): + self.check_exists_loop.stop() + ds = [] def wait_for_finished(lbry_file, count=2): diff --git a/lbrynet/lbrynet_daemon/Apps/LBRYOSXStatusBar.py b/lbrynet/lbrynet_daemon/Apps/LBRYOSXStatusBar.py index c55fed0d2..5ca433f72 100644 --- a/lbrynet/lbrynet_daemon/Apps/LBRYOSXStatusBar.py +++ b/lbrynet/lbrynet_daemon/Apps/LBRYOSXStatusBar.py @@ -39,7 +39,7 @@ class DaemonStatusBarApp(rumps.App): daemon = xmlrpclib.ServerProxy("http://localhost:7080/") try: daemon.is_running() - webbrowser.open("lbry://lbry") + webbrowser.get('safari').open("lbry://lbry") except: try: rumps.notification(title='LBRY', subtitle='', message="Couldn't connect to lbrynet daemon", sound=True) @@ -51,7 +51,7 @@ class DaemonStatusBarApp(rumps.App): daemon = xmlrpclib.ServerProxy("http://localhost:7080/") try: daemon.is_running() - webbrowser.open("lbry://settings") + webbrowser.get('safari').open("lbry://settings") except: rumps.notification(title='LBRY', subtitle='', message="Couldn't connect to lbrynet daemon", sound=True) diff --git a/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py b/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py index eea94cb94..1cc1bf3f8 100644 --- a/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py +++ b/lbrynet/lbrynet_daemon/Apps/LBRYURIHandler.py @@ -30,22 +30,25 @@ def main(args): else: r = daemon.get(args[0][7:]) - path = r['path'] - if path[0] != '/': - path = '/' + path + if r[0] == 200: + path = r[1]['path'] + if path[0] != '/': + path = '/' + path - filename = os.path.basename(path) - extension = os.path.splitext(filename)[1] + filename = os.path.basename(path) + extension = os.path.splitext(filename)[1] - if extension in ['mp4', 'flv', 'mov']: - html = render_video(path) - daemon.render_html(html) + if extension in ['mp4', 'flv', 'mov']: + html = render_video(path) + daemon.render_html(html) + else: + webbrowser.get('safari').open('file://' + str(path)) else: - webbrowser.open('file://' + str(path)) + webbrowser.get('safari').open('http://lbry.io/get') except: - webbrowser.open('http://lbry.io/get') + webbrowser.get('safari').open('http://lbry.io/get') if __name__ == "__main__": diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py index 1e68f0f76..410da8a81 100644 --- a/lbrynet/lbrynet_daemon/LBRYDaemon.py +++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py @@ -41,21 +41,21 @@ from lbrynet.lbryfilemanager.LBRYFileManager import LBRYFileManager from lbrynet.lbryfile.LBRYFileMetadataManager import DBLBRYFileMetadataManager, TempLBRYFileMetadataManager log = logging.getLogger(__name__) - - # logging.basicConfig(level=logging.DEBUG) # TODO add login credentials in a conf file - -# issues with delete: -# TODO when stream is stopped the generated file is deleted - # functions to add: # TODO send credits to address # TODO alert if your copy of a lbry file is out of date with the name record +BAD_REQUEST = (400, "Bad request") +NOT_FOUND = (404, "Not found") + +OK_CODE = 200 + + class LBRYDaemon(xmlrpc.XMLRPC): """ LBRYnet daemon @@ -556,8 +556,11 @@ class LBRYDaemon(xmlrpc.XMLRPC): d = self._check_history(name) d.addCallback(lambda lbry_file: _get_stream(name) if not lbry_file else _disp_file(lbry_file)) d.addCallback(lambda _: self._check_history(name)) - d.addCallback(lambda lbry_file: self._path_from_lbry_file(lbry_file) if lbry_file else 'Not found') - d.addErrback(lambda err: str(err)) + d.addCallback(lambda lbry_file: (OK_CODE, {'stream_hash': lbry_file.stream_hash, + 'path': os.path.join(self.download_directory, + lbry_file.file_name)}) + if lbry_file else NOT_FOUND) + d.addErrback(lambda _: NOT_FOUND) return d @@ -612,6 +615,7 @@ class LBRYDaemon(xmlrpc.XMLRPC): def finish_deletion(lbry_file): d = lbry_file.delete_data() d.addCallback(lambda _: _delete_stream_data(lbry_file)) + d.addCallback(lambda _: _delete_file(lbry_file)) return d def _delete_stream_data(lbry_file): @@ -621,6 +625,9 @@ class LBRYDaemon(xmlrpc.XMLRPC): d.addCallback(lambda c: self.stream_info_manager.delete_stream(s_h) if c == 0 else True) return d + def _delete_file(lbry_file): + os.remove(os.path.join(self.download_directory, lbry_file.file_name)) + d.addCallback(lambda _: finish_deletion(lbry_file)) return d @@ -807,7 +814,7 @@ class LBRYDaemon(xmlrpc.XMLRPC): if name: d = self._download_name(name) else: - d = defer.succeed('No name provided') + d = defer.succeed(BAD_REQUEST) return d def xmlrpc_stop_lbry_file(self, stream_hash): @@ -875,8 +882,12 @@ class LBRYDaemon(xmlrpc.XMLRPC): return err d = defer.Deferred() - d.addCallback(lambda _: webbrowser.open( - "file://" + str(os.path.join(self.download_directory, "lbryio/view/page/gui.html")))) + if sys.platform == 'darwin': + d.addCallback(lambda _: webbrowser.get('safari').open( + "file://" + str(os.path.join(self.download_directory, "lbryio/view/page/gui.html")))) + else: + d.addCallback(lambda _: webbrowser.open( + "file://" + str(os.path.join(self.download_directory, "lbryio/view/page/gui.html")))) d.addErrback(_disp_err) d.callback(None) @@ -967,13 +978,16 @@ class LBRYDaemon(xmlrpc.XMLRPC): return d def xmlrpc_publish(self, metadata): - metadata = json.loads(metadata) + try: + metadata = json.loads(metadata) + except: + return defer.succeed(BAD_REQUEST) required = ['name', 'file_path', 'bid'] for r in required: if not r in metadata.keys(): - return defer.fail() + return defer.succeed(BAD_REQUEST) # if not os.path.isfile(metadata['file_path']): # return defer.fail() @@ -1023,6 +1037,7 @@ class LBRYDaemon(xmlrpc.XMLRPC): 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, content_license) + d.addCallback(lambda msg: (OK_CODE, msg)) return d @@ -1145,6 +1160,12 @@ class LBRYDaemon(xmlrpc.XMLRPC): else: return "Status bar not implemented on non OS X" + def xmlrpc___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'] + def stop(): daemon = xmlrpclib.ServerProxy("http://localhost:7080/") diff --git a/lbrynet/lbrynet_daemon/LBRYDownloader.py b/lbrynet/lbrynet_daemon/LBRYDownloader.py index 4ea161c81..c5bfea81f 100644 --- a/lbrynet/lbrynet_daemon/LBRYDownloader.py +++ b/lbrynet/lbrynet_daemon/LBRYDownloader.py @@ -7,6 +7,7 @@ from twisted.internet.task import LoopingCall from lbrynet.core.Error import InvalidStreamInfoError, InsufficientFundsError from lbrynet.core.PaymentRateManager import PaymentRateManager from lbrynet.core.StreamDescriptor import download_sd_blob +from lbrynet.lbryfilemanager.LBRYFileDownloader import ManagedLBRYFileDownloaderFactory log = logging.getLogger(__name__) @@ -62,8 +63,8 @@ class GetStream(object): d = defer.Deferred(None) d.addCallback(lambda _: download_sd_blob(self.session, self.stream_hash, self.payment_rate_manager)) d.addCallback(self.sd_identifier.get_metadata_for_sd_blob) - d.addCallback(lambda metadata: - metadata.factories[1].make_downloader(metadata, [self.data_rate, True], self.payment_rate_manager)) + d.addCallback(lambda metadata: (next(factory for factory in metadata.factories if isinstance(factory, ManagedLBRYFileDownloaderFactory)), metadata)) + d.addCallback(lambda (factory, metadata): factory.make_downloader(metadata, [self.data_rate, True], self.payment_rate_manager)) d.addErrback(lambda err: err.trap(defer.CancelledError)) d.addErrback(lambda err: log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback())) d.addCallback(self._start_download)