From a1e827fb3b4069c34f2f6767a518fc29f2d5b94f Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Tue, 10 Nov 2015 11:33:35 -0500
Subject: [PATCH 01/21] LBRY autodownloader

Aquire LBRY files as they are published
---
 lbrynet/lbrynet_console/ControlHandlers.py | 220 ++++++++++++++++++++-
 lbrynet/lbrynet_console/LBRYConsole.py     |   9 +-
 2 files changed, 227 insertions(+), 2 deletions(-)

diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py
index c1754b9e2..0e9335f6c 100644
--- a/lbrynet/lbrynet_console/ControlHandlers.py
+++ b/lbrynet/lbrynet_console/ControlHandlers.py
@@ -1,4 +1,8 @@
+import json
 import logging
+from time import sleep
+
+from bitcoinrpc.authproxy import AuthServiceProxy
 from zope.interface import implements
 #from lbrynet.core.StreamDescriptor import PlainStreamDescriptorWriter, BlobStreamDescriptorWriter
 from lbrynet.core.PaymentRateManager import PaymentRateManager
@@ -2027,6 +2031,9 @@ class ImmediateAnnounceAllBlobs(CommandHandler):
 
 class ImmediateAnnounceAllBlobsFactory(CommandHandlerFactory):
     control_handler_class = ImmediateAnnounceAllBlobs
+    command = "announce-blobs"
+    full_help = "Immediately re-broadcast all hashes associated with the server to " \
+                "the distributed hash table."
 
 
 class ModifyServerSettings(RecursiveCommandHandler):
@@ -2349,4 +2356,215 @@ class StatusFactory(CommandHandlerFactory):
                 "Show the list of files that are currently downloading " \
                 "or have been downloaded, and give the option to " \
                 "toggle whether the file is actively downloading or " \
-                "to remove the file."
\ No newline at end of file
+                "to remove the file."
+
+
+class AutoAddStream(object):
+    def __init__(self, sd_identifier, base_payment_rate_manager, lbry_file_manager):
+        self.lbry_file_manager = lbry_file_manager
+        self.sd_identifier = sd_identifier
+        self.loading_metadata_deferred = None
+        self.finished_deferred = defer.Deferred()
+        self.metadata = None
+        self.downloader = None
+        self.loading_failed = False
+        self.payment_rate_manager = PaymentRateManager(base_payment_rate_manager)
+
+    def start(self):
+        self.loading_metadata_deferred.addCallback(self._handle_metadata)
+        self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
+        self.loading_metadata_deferred.addErrback(self._handle_load_failed)
+        self._start_download()
+
+    def _load_metadata(self, sd_file):
+        return defer.fail(NotImplementedError())
+
+    def _handle_load_canceled(self, err):
+        err.trap(defer.CancelledError)
+        self.finished_deferred.callback(None)
+
+    def _handle_load_failed(self, err):
+        self.loading_failed = True
+        log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback())
+        self.finished_deferred.callback(None)
+
+    def _handle_metadata(self, metadata):
+        self.loading_metadata_deferred = None
+        self.metadata = metadata
+
+    def _start_download(self):
+        d = self._make_downloader()
+        d.addCallback(lambda stream_downloader: stream_downloader.start())
+        d.addErrback(self._handle_download_error)
+        return d
+
+    def _handle_download_error(self, err):
+        if err.check(InsufficientFundsError):
+            print "Download stopped due to insufficient funds."
+        else:
+            print "An unexpected error has caused the download to stop: %s" % err.getTraceback()
+
+    #TODO fix this, shouldn't be a LBRYFileManager object, it doesn't have a make_downloader method
+    def _make_downloader(self):
+        return self.lbry_file_manager.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
+
+
+class AutoAddStreamFromHash(AutoAddStream):
+    def __init__(self, sd_identifier, session, lbry_file_manager):
+        AutoAddStream.__init__(self, sd_identifier, session.base_payment_rate_manager, lbry_file_manager)
+        self.session = session
+
+    def start(self, sd_hash):
+        self.loading_metadata_deferred = download_sd_blob(self.session, sd_hash,
+                                                          self.payment_rate_manager)
+        self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
+        AutoAddStream.start(self)
+
+    def _handle_load_failed(self, err):
+        self.loading_failed = True
+        if err.check(InvalidBlobHashError):
+            self.finished_deferred.callback(None)
+            return
+        if err.check(InsufficientFundsError):
+            self.finished_deferred.callback(None)
+            return
+        return AutoAddStream._handle_load_failed(self, err)
+
+
+class AutoAddStreamFromLBRYcrdName(AutoAddStreamFromHash):
+    def __init__(self, sd_identifier, session, wallet, lbry_file_manager):
+        AutoAddStreamFromHash.__init__(self, sd_identifier, session, lbry_file_manager)
+        self.wallet = wallet
+        self.resolved_name = None
+        self.description = None
+        self.key_fee = None
+        self.key_fee_address = None
+        self.name = None
+
+    def start(self, name):
+        self.name = name
+        self.loading_metadata_deferred = self._resolve_name(name)
+        self.loading_metadata_deferred.addCallback(lambda stream_hash: download_sd_blob(self.session,
+                                                                                        stream_hash,
+                                                                                        self.payment_rate_manager))
+        self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
+        log.error("Starting AutoAddStream")
+        AutoAddStream.start(self)
+
+    def _resolve_name(self, name):
+        def get_name_from_info(stream_info):
+            if 'stream_hash' not in stream_info:
+                raise InvalidStreamInfoError(name)
+            self.resolved_name = stream_info.get('name', None)
+            self.description = stream_info.get('description', None)
+            try:
+                if 'key_fee' in stream_info:
+                    self.key_fee = float(stream_info['key_fee'])
+            except ValueError:
+                self.key_fee = None
+            self.key_fee_address = stream_info.get('key_fee_address', None)
+            return stream_info['stream_hash']
+        d = self.wallet.get_stream_info_for_name(name)
+        d.addCallback(get_name_from_info)
+        return d
+
+    def _handle_load_failed(self, err):
+        self.loading_failed = True
+        if err.check(UnknownNameError):
+            if is_valid_blobhash(self.name):
+                self.loading_failed = False
+                self.loading_metadata_deferred = None
+                AutoAddStreamFromHash.start(self, self.name)
+                return
+            else:
+                self.finished_deferred.callback(None)
+                return
+        elif err.check(InvalidBlobHashError):
+            self.finished_deferred.callback(None)
+            return
+        return AutoAddStreamFromHash._handle_load_failed(self, err)
+
+    def _start_download(self):
+        d = self._pay_key_fee()
+        d.addCallback(lambda _: AutoAddStream._start_download(self))
+        return d
+
+    def _pay_key_fee(self):
+        if self.key_fee is not None and self.key_fee_address is not None:
+            reserved_points = self.wallet.reserve_points(self.key_fee_address, self.key_fee)
+            if reserved_points is None:
+                return defer.fail(InsufficientFundsError())
+            return self.wallet.send_points_to_address(reserved_points, self.key_fee)
+        return defer.succeed(True)
+
+
+#TODO see problem on line 2408
+class AutoFetcher(CommandHandler):
+    def __init__(self, console, session, lbry_file_manager, lbry_file_metadata_manager, wallet, sd_identifier):
+        CommandHandler.__init__(self, console)
+        self.sd_identifier = sd_identifier
+        self.wallet = wallet
+        self.session = session
+        self.lbry_file_manager = lbry_file_manager
+        self.lbry_metadata_manager = lbry_file_metadata_manager
+        self.seen = []
+
+        settings = self.session.wallet.get_rpc_conf()
+        rpc_user = settings["username"]
+        rpc_pass = settings["password"]
+        rpc_port = settings["rpc_port"]
+        rpc_url = "127.0.0.1"
+        rpc_conn_string = "http://%s:%s@%s:%s" % (rpc_user, rpc_pass, rpc_url, str(rpc_port))
+        self.rpc_conn = AuthServiceProxy(rpc_conn_string)
+
+    def start(self):
+        self._listen_for_names()
+
+    def _listen_for_names(self):
+        l = 0
+        firstrun = True
+        while True:
+            c = self.rpc_conn.getblockchaininfo()
+            if l != c:
+                block = self.rpc_conn.getblock(c['bestblockhash'])
+                txids = block['tx']
+                transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
+                claimflag = False
+                claims = None
+                nmsg = []
+                tmsg = []
+                for t in transactions:
+                    claims = self.rpc_conn.getclaimsfortx(t['txid'])
+                    if firstrun:
+                        claims = [{'name': 'wonderfullife'}]
+                    if claims:
+                        for claim in claims:
+                            if claim not in self.seen:
+                                print claim
+                                print '* Trying to get claim', claim['name']
+                                get_name = AutoAddStreamFromLBRYcrdName(self.sd_identifier, self.session,
+                                                                        self.wallet, self.lbry_file_manager)
+                                get_name.start(claim['name'])
+                                nmsg.append(claim['name'])
+                                self.seen.append(claim)
+                                claimflag = True
+                    else:
+                        tmsg.append("Transaction: " + str(t['txid']))
+                if claimflag:
+                    print '! New name claims'
+                    for c in nmsg:
+                        print '     ' + str(c)
+                else:
+                    print 'No name claims in this block'
+                    for t in tmsg:
+                        print '     ' + str(t)
+
+                l = c
+            firstrun = False
+            sleep(1)
+
+
+class AutoFetcherFactory(CommandHandlerFactory):
+    control_handler_class = AutoFetcher
+    command = "start-autofetching"
+    short_help = "Download all lbry files as they are published"
\ No newline at end of file
diff --git a/lbrynet/lbrynet_console/LBRYConsole.py b/lbrynet/lbrynet_console/LBRYConsole.py
index 60dac2679..4f0b35074 100644
--- a/lbrynet/lbrynet_console/LBRYConsole.py
+++ b/lbrynet/lbrynet_console/LBRYConsole.py
@@ -21,6 +21,7 @@ from lbrynet.lbryfile.StreamDescriptor import LBRYFileStreamType
 from lbrynet.lbryfile.LBRYFileMetadataManager import DBLBRYFileMetadataManager, TempLBRYFileMetadataManager
 #from lbrynet.lbrylive.PaymentRateManager import LiveStreamPaymentRateManager
 from lbrynet.lbrynet_console.ControlHandlers import ApplicationStatusFactory, GetWalletBalancesFactory, ShutDownFactory
+from lbrynet.lbrynet_console.ControlHandlers import AutoFetcherFactory, ImmediateAnnounceAllBlobsFactory
 from lbrynet.lbrynet_console.ControlHandlers import LBRYFileStatusFactory, DeleteLBRYFileChooserFactory
 from lbrynet.lbrynet_console.ControlHandlers import ToggleLBRYFileRunningChooserFactory
 from lbrynet.lbrynet_console.ControlHandlers import ModifyApplicationDefaultsFactory
@@ -311,7 +312,10 @@ class LBRYConsole():
             ModifyLBRYFileOptionsChooserFactory(self.lbry_file_manager),
             AddStreamFromHashFactory(self.sd_identifier, self.session),
             StatusFactory(self, self.session.rate_limiter, self.lbry_file_manager,
-                          self.session.blob_manager, self.session.wallet if self.wallet_type == 'lbrycrd' else None)
+                          self.session.blob_manager, self.session.wallet if self.wallet_type == 'lbrycrd' else None),
+            AutoFetcherFactory(self.session, self.lbry_file_manager, self.lbry_file_metadata_manager,
+                               self.session.wallet, self.sd_identifier),
+            ImmediateAnnounceAllBlobsFactory(self.session.blob_manager)
         ]
         self.add_control_handlers(handlers)
         if self.wallet_type == 'lbrycrd':
@@ -537,3 +541,6 @@ def launch_lbry_console():
 
     reactor.addSystemEventTrigger('before', 'shutdown', console.shut_down)
     reactor.run()
+
+if __name__ == "__main__":
+    launch_lbry_console()
\ No newline at end of file

From 657c1a46269769a5e3a50673f2e6d449bdac5927 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Thu, 12 Nov 2015 00:03:49 -0500
Subject: [PATCH 02/21] Adds a command to automatically download files as names
 are claimed

Defaults on only trying to download wonderfullife
---
 lbrynet/lbrynet_console/ControlHandlers.py | 168 ++++++++++++---------
 1 file changed, 100 insertions(+), 68 deletions(-)

diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py
index 0e9335f6c..55fb16889 100644
--- a/lbrynet/lbrynet_console/ControlHandlers.py
+++ b/lbrynet/lbrynet_console/ControlHandlers.py
@@ -415,6 +415,7 @@ class AddStream(CommandHandler):
         self.payment_rate_manager = PaymentRateManager(base_payment_rate_manager)
 
     def start(self):
+        self.console.sendLine("Starting addstream...")
         self.console.sendLine(self.cancel_prompt)
         self.loading_metadata_deferred.addCallback(self._handle_metadata)
         self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
@@ -649,6 +650,7 @@ class AddStream(CommandHandler):
         return choice_string
 
     def _start_download(self):
+        print 'Starting addstream._start_download'
         d = self._make_downloader()
         d.addCallback(lambda stream_downloader: stream_downloader.start())
         d.addErrback(self._handle_download_error)
@@ -662,6 +664,7 @@ class AddStream(CommandHandler):
             self.console.sendLine("An unexpected error has caused the download to stop. See console.log for details.")
 
     def _make_downloader(self):
+        print 'Making downloader'
         return self.factory.make_downloader(self.metadata, self.options_chosen,
                                             self.payment_rate_manager)
 
@@ -693,6 +696,7 @@ class AddStreamFromHash(AddStream):
         self.session = session
 
     def start(self, sd_hash):
+        print 'Starting addstreamfromhash'
         self.loading_metadata_deferred = download_sd_blob(self.session, sd_hash,
                                                           self.payment_rate_manager)
         self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
@@ -736,12 +740,14 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash):
         self.name = None
 
     def start(self, name):
+        print 'Starting addstreamfromlbrycrdname'
         self.name = name
         self.loading_metadata_deferred = self._resolve_name(name)
         self.loading_metadata_deferred.addCallback(lambda stream_hash: download_sd_blob(self.session,
                                                                                         stream_hash,
                                                                                         self.payment_rate_manager))
         self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
+        print 'Sending addstream.start from crdname'
         AddStream.start(self)
 
     def _resolve_name(self, name):
@@ -759,6 +765,7 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash):
             return stream_info['stream_hash']
         d = self.wallet.get_stream_info_for_name(name)
         d.addCallback(get_name_from_info)
+        print 'Resolved name'
         return d
 
     def _handle_load_failed(self, err):
@@ -780,11 +787,13 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash):
         return AddStreamFromHash._handle_load_failed(self, err)
 
     def _start_download(self):
+        print 'Startind download in addstreamlbrycrd'
         d = self._pay_key_fee()
         d.addCallback(lambda _: AddStream._start_download(self))
         return d
 
     def _pay_key_fee(self):
+        print 'Paying kee fee'
         if self.key_fee is not None and self.key_fee_address is not None:
             reserved_points = self.wallet.reserve_points(self.key_fee_address, self.key_fee)
             if reserved_points is None:
@@ -2032,6 +2041,7 @@ class ImmediateAnnounceAllBlobs(CommandHandler):
 class ImmediateAnnounceAllBlobsFactory(CommandHandlerFactory):
     control_handler_class = ImmediateAnnounceAllBlobs
     command = "announce-blobs"
+    short_help = "Announce all blobs to the dht"
     full_help = "Immediately re-broadcast all hashes associated with the server to " \
                 "the distributed hash table."
 
@@ -2360,20 +2370,28 @@ class StatusFactory(CommandHandlerFactory):
 
 
 class AutoAddStream(object):
-    def __init__(self, sd_identifier, base_payment_rate_manager, lbry_file_manager):
-        self.lbry_file_manager = lbry_file_manager
-        self.sd_identifier = sd_identifier
+    def __init__(self):
+        self.console = None
+        self.session = None
         self.loading_metadata_deferred = None
-        self.finished_deferred = defer.Deferred()
+        self.lbry_file_manager = None
+        self.sd_identifier = None
+        self.finished_deferred = None
         self.metadata = None
         self.downloader = None
         self.loading_failed = False
-        self.payment_rate_manager = PaymentRateManager(base_payment_rate_manager)
+        self.factory = None
+        self.description = None
+        self.key_fee = None
+        self.key_fee_address = None
+        self.payment_rate_manager = None
 
     def start(self):
+        self.console.sendLine("Started autoaddstream")
         self.loading_metadata_deferred.addCallback(self._handle_metadata)
         self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
         self.loading_metadata_deferred.addErrback(self._handle_load_failed)
+        self.console.sendLine("AutoAddStream starting download")
         self._start_download()
 
     def _load_metadata(self, sd_file):
@@ -2385,36 +2403,41 @@ class AutoAddStream(object):
 
     def _handle_load_failed(self, err):
         self.loading_failed = True
+        self.console.sendLine("handle load failed: " + str(err.getTraceback()))
         log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback())
         self.finished_deferred.callback(None)
 
     def _handle_metadata(self, metadata):
-        self.loading_metadata_deferred = None
+        self.console.sendLine("Metadata: " + str(metadata))
         self.metadata = metadata
+        self.factory = self.metadata.factories[0]
 
     def _start_download(self):
+        self.console.sendLine("Autoaddstream _start_download, making downloader")
         d = self._make_downloader()
+        self.console.sendLine("Autoaddstream starting download")
         d.addCallback(lambda stream_downloader: stream_downloader.start())
         d.addErrback(self._handle_download_error)
         return d
 
     def _handle_download_error(self, err):
         if err.check(InsufficientFundsError):
-            print "Download stopped due to insufficient funds."
+            self.console.sendLine("Download stopped due to insufficient funds.")
         else:
-            print "An unexpected error has caused the download to stop: %s" % err.getTraceback()
+            self.console.sendLine("Autoaddstream: An unexpected error has caused the download to stop: %s" % err.getTraceback())
 
-    #TODO fix this, shouldn't be a LBRYFileManager object, it doesn't have a make_downloader method
     def _make_downloader(self):
-        return self.lbry_file_manager.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
+        self.console.sendLine("making downloader, factory: " + str(self.factory))
+        self.downloader = self.factory.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
+        return defer.succeed(self.downloader)
 
 
 class AutoAddStreamFromHash(AutoAddStream):
-    def __init__(self, sd_identifier, session, lbry_file_manager):
-        AutoAddStream.__init__(self, sd_identifier, session.base_payment_rate_manager, lbry_file_manager)
-        self.session = session
+    def __init__(self):
+        AutoAddStream.__init__(self)
 
     def start(self, sd_hash):
+        self.console.sendLine("Started AutoAddStreamFromHash")
         self.loading_metadata_deferred = download_sd_blob(self.session, sd_hash,
                                                           self.payment_rate_manager)
         self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
@@ -2432,27 +2455,39 @@ class AutoAddStreamFromHash(AutoAddStream):
 
 
 class AutoAddStreamFromLBRYcrdName(AutoAddStreamFromHash):
-    def __init__(self, sd_identifier, session, wallet, lbry_file_manager):
-        AutoAddStreamFromHash.__init__(self, sd_identifier, session, lbry_file_manager)
+    def __init__(self, console, sd_identifier, session, wallet, lbry_file_manager):
+        AutoAddStreamFromHash.__init__(self)
         self.wallet = wallet
         self.resolved_name = None
         self.description = None
         self.key_fee = None
         self.key_fee_address = None
         self.name = None
+        self.session = session
+        self.payment_rate_manager = PaymentRateManager(self.session.base_payment_rate_manager)
+        self.console = console
+        self.loading_metadata_deferred = None
+        self.lbry_file_manager = lbry_file_manager
+        self.sd_identifier = sd_identifier
+        self.finished_deferred = None
+        self.metadata = None
+        self.loading_failed = False
 
     def start(self, name):
+        self.console.sendLine("Started AutoAddStreamFromLBRYcrdName, file: " + name)
         self.name = name
         self.loading_metadata_deferred = self._resolve_name(name)
         self.loading_metadata_deferred.addCallback(lambda stream_hash: download_sd_blob(self.session,
                                                                                         stream_hash,
                                                                                         self.payment_rate_manager))
         self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
-        log.error("Starting AutoAddStream")
-        AutoAddStream.start(self)
+        self.console.sendLine("Starting autoaddstream...")
+        self.loading_metadata_deferred.addCallback(AutoAddStream.start(self))
+        self.loading_metadata_deferred.addCallback(self._start_download())
 
     def _resolve_name(self, name):
         def get_name_from_info(stream_info):
+            self.console.sendLine("1 Stream info: " + str(stream_info))
             if 'stream_hash' not in stream_info:
                 raise InvalidStreamInfoError(name)
             self.resolved_name = stream_info.get('name', None)
@@ -2463,8 +2498,10 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStreamFromHash):
             except ValueError:
                 self.key_fee = None
             self.key_fee_address = stream_info.get('key_fee_address', None)
+            self.stream_hash = stream_info['stream_hash']
             return stream_info['stream_hash']
         d = self.wallet.get_stream_info_for_name(name)
+        self.console.sendLine("2 Stream info: " + str(d))
         d.addCallback(get_name_from_info)
         return d
 
@@ -2485,6 +2522,7 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStreamFromHash):
         return AutoAddStreamFromHash._handle_load_failed(self, err)
 
     def _start_download(self):
+        self.console.sendLine("crd name _start_download")
         d = self._pay_key_fee()
         d.addCallback(lambda _: AutoAddStream._start_download(self))
         return d
@@ -2495,73 +2533,67 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStreamFromHash):
             if reserved_points is None:
                 return defer.fail(InsufficientFundsError())
             return self.wallet.send_points_to_address(reserved_points, self.key_fee)
+        self.console.sendLine("Sent key fee" + str(self.key_fee_address) + " | " + str(self.key_fee))
         return defer.succeed(True)
 
 
-#TODO see problem on line 2408
 class AutoFetcher(CommandHandler):
     def __init__(self, console, session, lbry_file_manager, lbry_file_metadata_manager, wallet, sd_identifier):
         CommandHandler.__init__(self, console)
+        self.d = None
+        self.console = console
         self.sd_identifier = sd_identifier
         self.wallet = wallet
         self.session = session
         self.lbry_file_manager = lbry_file_manager
         self.lbry_metadata_manager = lbry_file_metadata_manager
         self.seen = []
-
-        settings = self.session.wallet.get_rpc_conf()
-        rpc_user = settings["username"]
-        rpc_pass = settings["password"]
-        rpc_port = settings["rpc_port"]
-        rpc_url = "127.0.0.1"
-        rpc_conn_string = "http://%s:%s@%s:%s" % (rpc_user, rpc_pass, rpc_url, str(rpc_port))
-        self.rpc_conn = AuthServiceProxy(rpc_conn_string)
+        self.lastbestblock = None
+        self.rpc_conn = self.wallet.get_rpc_conn_x()
 
     def start(self):
-        self._listen_for_names()
+        self.d = self._get_names()
+        self.d.addCallback(self._download_claims)
+        self.d.addErrback(self.finished_deferred.callback(None))
 
-    def _listen_for_names(self):
-        l = 0
-        firstrun = True
-        while True:
-            c = self.rpc_conn.getblockchaininfo()
-            if l != c:
-                block = self.rpc_conn.getblock(c['bestblockhash'])
-                txids = block['tx']
-                transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
-                claimflag = False
-                claims = None
-                nmsg = []
-                tmsg = []
-                for t in transactions:
-                    claims = self.rpc_conn.getclaimsfortx(t['txid'])
-                    if firstrun:
-                        claims = [{'name': 'wonderfullife'}]
-                    if claims:
-                        for claim in claims:
-                            if claim not in self.seen:
-                                print claim
-                                print '* Trying to get claim', claim['name']
-                                get_name = AutoAddStreamFromLBRYcrdName(self.sd_identifier, self.session,
-                                                                        self.wallet, self.lbry_file_manager)
-                                get_name.start(claim['name'])
-                                nmsg.append(claim['name'])
-                                self.seen.append(claim)
-                                claimflag = True
-                    else:
-                        tmsg.append("Transaction: " + str(t['txid']))
-                if claimflag:
-                    print '! New name claims'
-                    for c in nmsg:
-                        print '     ' + str(c)
-                else:
-                    print 'No name claims in this block'
-                    for t in tmsg:
-                        print '     ' + str(t)
+    def _get_names(self):
+        c = self.rpc_conn.getblockchaininfo()
+        if self.lastbestblock != c:
+            block = self.rpc_conn.getblock(c['bestblockhash'])
+            txids = block['tx']
+            transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
+            rtn = []
+            for t in transactions:
+                #claims = self.rpc_conn.getclaimsfortx(t['txid'])
+                claims = self.rpc_conn.getclaimsfortx("c3684bd587856ba5cc38c4afdbcd2c6efc60cb2d1ed21188485ea58048b419a8")
+                if claims:
+                    for claim in claims:
+                        if claim not in self.seen:
+                            #self.console.sendLine(str(claim))
+                            self.console.sendLine("lbry://" + str(claim['name']) + " | stream hash: " +
+                                                        str(json.loads(claim['value'])['stream_hash']))
+                            self.console.sendLine(str(json.loads(claim['value'])))
+                            rtn.append(claim['name'])
+                            self.seen.append(claim)
+            if not len(rtn):
+                self.console.sendLine("No claims in block " + str(block['hash']) + ", height: " + str(block['height']))
 
-                l = c
-            firstrun = False
-            sleep(1)
+        self.lastbestblock = c
+        if len(rtn):
+            return defer.succeed(rtn)
+        else:
+            return defer.failure(None)
+
+    def _download_claims(self, claims):
+        for claim in claims:
+            # stream = AutoAddStreamFromHash(self.console, self.sd_identifier,
+            #                                 self.session, self.lbry_file_manager, stream_hash,
+            #                                 description, key_fee, key_fee_address)
+            stream = AutoAddStreamFromLBRYcrdName(self.console, self.sd_identifier, self.session,
+                                                  self.wallet, self.lbry_file_manager)
+            d = threads.deferToThread(stream.start(str(claim)))
+            self.console.sendLine("Download complete")
+        return defer.succeed(d)
 
 
 class AutoFetcherFactory(CommandHandlerFactory):

From f16eec2ad2c7e45be81a8af38754ff4d9ebd26f9 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Sat, 14 Nov 2015 20:36:53 -0500
Subject: [PATCH 03/21] Automatic downloading now works

---
 lbrynet/core/LBRYcrdWallet.py              |   3 +
 lbrynet/lbrynet_console/ControlHandlers.py | 138 ++++++++-------------
 2 files changed, 57 insertions(+), 84 deletions(-)

diff --git a/lbrynet/core/LBRYcrdWallet.py b/lbrynet/core/LBRYcrdWallet.py
index 936a441cb..510d949f2 100644
--- a/lbrynet/core/LBRYcrdWallet.py
+++ b/lbrynet/core/LBRYcrdWallet.py
@@ -339,6 +339,9 @@ class LBRYcrdWallet(object):
     def _get_rpc_conn(self):
         return AuthServiceProxy(self.rpc_conn_string)
 
+    def get_rpc_conn_x(self):
+        return AuthServiceProxy(self.rpc_conn_string)
+
     def _start_daemon(self):
 
         tries = 0
diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py
index 55fb16889..ad9a1ef9d 100644
--- a/lbrynet/lbrynet_console/ControlHandlers.py
+++ b/lbrynet/lbrynet_console/ControlHandlers.py
@@ -2369,14 +2369,13 @@ class StatusFactory(CommandHandlerFactory):
                 "to remove the file."
 
 
-class AutoAddStream(object):
-    def __init__(self):
-        self.console = None
+class AutoAddStream(CommandHandler):
+    def __init__(self, console):
+        CommandHandler.__init__(self, console)
         self.session = None
         self.loading_metadata_deferred = None
         self.lbry_file_manager = None
         self.sd_identifier = None
-        self.finished_deferred = None
         self.metadata = None
         self.downloader = None
         self.loading_failed = False
@@ -2388,30 +2387,10 @@ class AutoAddStream(object):
 
     def start(self):
         self.console.sendLine("Started autoaddstream")
-        self.loading_metadata_deferred.addCallback(self._handle_metadata)
-        self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
-        self.loading_metadata_deferred.addErrback(self._handle_load_failed)
-        self.console.sendLine("AutoAddStream starting download")
-        self._start_download()
 
     def _load_metadata(self, sd_file):
         return defer.fail(NotImplementedError())
 
-    def _handle_load_canceled(self, err):
-        err.trap(defer.CancelledError)
-        self.finished_deferred.callback(None)
-
-    def _handle_load_failed(self, err):
-        self.loading_failed = True
-        self.console.sendLine("handle load failed: " + str(err.getTraceback()))
-        log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback())
-        self.finished_deferred.callback(None)
-
-    def _handle_metadata(self, metadata):
-        self.console.sendLine("Metadata: " + str(metadata))
-        self.metadata = metadata
-        self.factory = self.metadata.factories[0]
-
     def _start_download(self):
         self.console.sendLine("Autoaddstream _start_download, making downloader")
         d = self._make_downloader()
@@ -2429,34 +2408,12 @@ class AutoAddStream(object):
     def _make_downloader(self):
         self.console.sendLine("making downloader, factory: " + str(self.factory))
         self.downloader = self.factory.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
-        return defer.succeed(self.downloader)
+        return self.downloader
 
 
-class AutoAddStreamFromHash(AutoAddStream):
-    def __init__(self):
-        AutoAddStream.__init__(self)
-
-    def start(self, sd_hash):
-        self.console.sendLine("Started AutoAddStreamFromHash")
-        self.loading_metadata_deferred = download_sd_blob(self.session, sd_hash,
-                                                          self.payment_rate_manager)
-        self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
-        AutoAddStream.start(self)
-
-    def _handle_load_failed(self, err):
-        self.loading_failed = True
-        if err.check(InvalidBlobHashError):
-            self.finished_deferred.callback(None)
-            return
-        if err.check(InsufficientFundsError):
-            self.finished_deferred.callback(None)
-            return
-        return AutoAddStream._handle_load_failed(self, err)
-
-
-class AutoAddStreamFromLBRYcrdName(AutoAddStreamFromHash):
+class AutoAddStreamFromLBRYcrdName(AutoAddStream):
     def __init__(self, console, sd_identifier, session, wallet, lbry_file_manager):
-        AutoAddStreamFromHash.__init__(self)
+        AutoAddStream.__init__(self, console)
         self.wallet = wallet
         self.resolved_name = None
         self.description = None
@@ -2465,30 +2422,40 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStreamFromHash):
         self.name = None
         self.session = session
         self.payment_rate_manager = PaymentRateManager(self.session.base_payment_rate_manager)
-        self.console = console
-        self.loading_metadata_deferred = None
+        self.loading_metadata_deferred = defer.Deferred()
         self.lbry_file_manager = lbry_file_manager
         self.sd_identifier = sd_identifier
-        self.finished_deferred = None
         self.metadata = None
         self.loading_failed = False
+        self.downloading_metadata_deferred = defer.Deferred()
+        self.resolved_name = None
+        self.description = None
+        self.key_fee = None
+        self.key_fee_address = None
+        self.stream_hash = None
 
     def start(self, name):
         self.console.sendLine("Started AutoAddStreamFromLBRYcrdName, file: " + name)
         self.name = name
-        self.loading_metadata_deferred = self._resolve_name(name)
-        self.loading_metadata_deferred.addCallback(lambda stream_hash: download_sd_blob(self.session,
-                                                                                        stream_hash,
-                                                                                        self.payment_rate_manager))
+
+        self.loading_metadata_deferred = defer.Deferred(None)
+        self.loading_metadata_deferred.addCallback(lambda _: self._resolve_name(str(name)))
+
+        #self.downloading_metadata_deferred.addCallback(lambda _: self.loading_metadata_deferred.callback(None))
+        self.loading_metadata_deferred.addCallback(lambda stream_hash: download_sd_blob(self.session, stream_hash, self.payment_rate_manager))
         self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
-        self.console.sendLine("Starting autoaddstream...")
-        self.loading_metadata_deferred.addCallback(AutoAddStream.start(self))
-        self.loading_metadata_deferred.addCallback(self._start_download())
+        self.loading_metadata_deferred.addCallback(self._handle_metadata)
+        #self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
+        #self.loading_metadata_deferred.addErrback(self._handle_load_failed)
+
+        self.finished_deferred.addCallback(lambda _: self.loading_metadata_deferred.callback(None))
+
+        return self.finished_deferred.callback(None)
 
     def _resolve_name(self, name):
         def get_name_from_info(stream_info):
-            self.console.sendLine("1 Stream info: " + str(stream_info))
             if 'stream_hash' not in stream_info:
+                print 'InvalidStreamInfoError'
                 raise InvalidStreamInfoError(name)
             self.resolved_name = stream_info.get('name', None)
             self.description = stream_info.get('description', None)
@@ -2499,28 +2466,12 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStreamFromHash):
                 self.key_fee = None
             self.key_fee_address = stream_info.get('key_fee_address', None)
             self.stream_hash = stream_info['stream_hash']
+            print "Stream info ", stream_info
             return stream_info['stream_hash']
         d = self.wallet.get_stream_info_for_name(name)
-        self.console.sendLine("2 Stream info: " + str(d))
         d.addCallback(get_name_from_info)
         return d
 
-    def _handle_load_failed(self, err):
-        self.loading_failed = True
-        if err.check(UnknownNameError):
-            if is_valid_blobhash(self.name):
-                self.loading_failed = False
-                self.loading_metadata_deferred = None
-                AutoAddStreamFromHash.start(self, self.name)
-                return
-            else:
-                self.finished_deferred.callback(None)
-                return
-        elif err.check(InvalidBlobHashError):
-            self.finished_deferred.callback(None)
-            return
-        return AutoAddStreamFromHash._handle_load_failed(self, err)
-
     def _start_download(self):
         self.console.sendLine("crd name _start_download")
         d = self._pay_key_fee()
@@ -2534,7 +2485,28 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStreamFromHash):
                 return defer.fail(InsufficientFundsError())
             return self.wallet.send_points_to_address(reserved_points, self.key_fee)
         self.console.sendLine("Sent key fee" + str(self.key_fee_address) + " | " + str(self.key_fee))
-        return defer.succeed(True)
+        return defer.succeed(None)
+
+    def _handle_load_canceled(self, err):
+        err.trap(defer.CancelledError)
+        self.finished_deferred.callback(None)
+
+    def _handle_load_failed(self, err):
+        self.loading_failed = True
+        self.console.sendLine("handle load failed: " + str(err.getTraceback()))
+        log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback())
+        self.finished_deferred.callback(None)
+
+    def _handle_metadata(self, metadata):
+        self.console.sendLine("Metadata: " + str(metadata))
+        self.metadata = metadata
+        self.factory = self.metadata.factories[0]
+        self.console.sendLine("Factory: " + str(self.factory))
+
+        self.finished_deferred.addCallback(lambda _: self.console.sendLine("Factoryx " + str(self.factory)))
+        self.finished_deferred.addCallback(lambda _: AutoAddStream.start(self))
+        self.finished_deferred.addCallback(lambda _: self._start_download())
+        self.finished_deferred.addCallback(lambda _: AutoAddStream._start_download(self))
 
 
 class AutoFetcher(CommandHandler):
@@ -2572,7 +2544,6 @@ class AutoFetcher(CommandHandler):
                             #self.console.sendLine(str(claim))
                             self.console.sendLine("lbry://" + str(claim['name']) + " | stream hash: " +
                                                         str(json.loads(claim['value'])['stream_hash']))
-                            self.console.sendLine(str(json.loads(claim['value'])))
                             rtn.append(claim['name'])
                             self.seen.append(claim)
             if not len(rtn):
@@ -2586,14 +2557,13 @@ class AutoFetcher(CommandHandler):
 
     def _download_claims(self, claims):
         for claim in claims:
-            # stream = AutoAddStreamFromHash(self.console, self.sd_identifier,
-            #                                 self.session, self.lbry_file_manager, stream_hash,
-            #                                 description, key_fee, key_fee_address)
+            download = defer.Deferred()
             stream = AutoAddStreamFromLBRYcrdName(self.console, self.sd_identifier, self.session,
                                                   self.wallet, self.lbry_file_manager)
-            d = threads.deferToThread(stream.start(str(claim)))
+            download.addCallback(lambda _: stream.start(str(claim)))
+            download.callback(None)
             self.console.sendLine("Download complete")
-        return defer.succeed(d)
+        return defer.succeed(None)
 
 
 class AutoFetcherFactory(CommandHandlerFactory):

From 6e93c68a7757564df428e5f785130c9b8af1e2c5 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Sat, 14 Nov 2015 21:53:16 -0500
Subject: [PATCH 04/21] Run AutoFetcher in the background

---
 lbrynet/lbrynet_console/ControlHandlers.py | 118 +++++++++++++++------
 1 file changed, 83 insertions(+), 35 deletions(-)

diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py
index ad9a1ef9d..b391d8818 100644
--- a/lbrynet/lbrynet_console/ControlHandlers.py
+++ b/lbrynet/lbrynet_console/ControlHandlers.py
@@ -3,6 +3,7 @@ import logging
 from time import sleep
 
 from bitcoinrpc.authproxy import AuthServiceProxy
+from twisted.internet.task import LoopingCall
 from zope.interface import implements
 #from lbrynet.core.StreamDescriptor import PlainStreamDescriptorWriter, BlobStreamDescriptorWriter
 from lbrynet.core.PaymentRateManager import PaymentRateManager
@@ -16,6 +17,7 @@ from lbrynet.core.Error import UnknownNameError, InvalidBlobHashError, Insuffici
 from lbrynet.core.Error import InvalidStreamInfoError
 from lbrynet.core.utils import is_valid_blobhash
 from twisted.internet import defer, threads
+import datetime
 import os
 
 
@@ -2386,15 +2388,13 @@ class AutoAddStream(CommandHandler):
         self.payment_rate_manager = None
 
     def start(self):
-        self.console.sendLine("Started autoaddstream")
+        pass
 
     def _load_metadata(self, sd_file):
         return defer.fail(NotImplementedError())
 
     def _start_download(self):
-        self.console.sendLine("Autoaddstream _start_download, making downloader")
         d = self._make_downloader()
-        self.console.sendLine("Autoaddstream starting download")
         d.addCallback(lambda stream_downloader: stream_downloader.start())
         d.addErrback(self._handle_download_error)
         return d
@@ -2406,7 +2406,6 @@ class AutoAddStream(CommandHandler):
             self.console.sendLine("Autoaddstream: An unexpected error has caused the download to stop: %s" % err.getTraceback())
 
     def _make_downloader(self):
-        self.console.sendLine("making downloader, factory: " + str(self.factory))
         self.downloader = self.factory.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
         return self.downloader
 
@@ -2427,7 +2426,6 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStream):
         self.sd_identifier = sd_identifier
         self.metadata = None
         self.loading_failed = False
-        self.downloading_metadata_deferred = defer.Deferred()
         self.resolved_name = None
         self.description = None
         self.key_fee = None
@@ -2435,14 +2433,12 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStream):
         self.stream_hash = None
 
     def start(self, name):
-        self.console.sendLine("Started AutoAddStreamFromLBRYcrdName, file: " + name)
         self.name = name
 
         self.loading_metadata_deferred = defer.Deferred(None)
         self.loading_metadata_deferred.addCallback(lambda _: self._resolve_name(str(name)))
-
-        #self.downloading_metadata_deferred.addCallback(lambda _: self.loading_metadata_deferred.callback(None))
-        self.loading_metadata_deferred.addCallback(lambda stream_hash: download_sd_blob(self.session, stream_hash, self.payment_rate_manager))
+        self.loading_metadata_deferred.addCallback(lambda stream_hash: download_sd_blob(self.session,
+                                                                            stream_hash, self.payment_rate_manager))
         self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
         self.loading_metadata_deferred.addCallback(self._handle_metadata)
         #self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
@@ -2466,14 +2462,12 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStream):
                 self.key_fee = None
             self.key_fee_address = stream_info.get('key_fee_address', None)
             self.stream_hash = stream_info['stream_hash']
-            print "Stream info ", stream_info
             return stream_info['stream_hash']
         d = self.wallet.get_stream_info_for_name(name)
         d.addCallback(get_name_from_info)
         return d
 
     def _start_download(self):
-        self.console.sendLine("crd name _start_download")
         d = self._pay_key_fee()
         d.addCallback(lambda _: AutoAddStream._start_download(self))
         return d
@@ -2484,7 +2478,7 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStream):
             if reserved_points is None:
                 return defer.fail(InsufficientFundsError())
             return self.wallet.send_points_to_address(reserved_points, self.key_fee)
-        self.console.sendLine("Sent key fee" + str(self.key_fee_address) + " | " + str(self.key_fee))
+        #self.console.sendLine("Sent key fee" + str(self.key_fee_address) + " | " + str(self.key_fee))
         return defer.succeed(None)
 
     def _handle_load_canceled(self, err):
@@ -2498,15 +2492,12 @@ class AutoAddStreamFromLBRYcrdName(AutoAddStream):
         self.finished_deferred.callback(None)
 
     def _handle_metadata(self, metadata):
-        self.console.sendLine("Metadata: " + str(metadata))
         self.metadata = metadata
         self.factory = self.metadata.factories[0]
-        self.console.sendLine("Factory: " + str(self.factory))
+        #self.console.sendLine("Factory: " + str(self.factory))
 
-        self.finished_deferred.addCallback(lambda _: self.console.sendLine("Factoryx " + str(self.factory)))
         self.finished_deferred.addCallback(lambda _: AutoAddStream.start(self))
         self.finished_deferred.addCallback(lambda _: self._start_download())
-        self.finished_deferred.addCallback(lambda _: AutoAddStream._start_download(self))
 
 
 class AutoFetcher(CommandHandler):
@@ -2524,49 +2515,106 @@ class AutoFetcher(CommandHandler):
         self.rpc_conn = self.wallet.get_rpc_conn_x()
 
     def start(self):
-        self.d = self._get_names()
-        self.d.addCallback(self._download_claims)
-        self.d.addErrback(self.finished_deferred.callback(None))
+        #TODO add a stop function
+        #TODO detect if it's already running
+        #TODO first search through the nametrie before monitoring live updates
+        #TODO load previously downloaded streams
+
+        search = LoopingCall(self._looped_search)
+        search.start(10)
+        self.finished_deferred.callback(None)
 
     def _get_names(self):
         c = self.rpc_conn.getblockchaininfo()
+        rtn = []
         if self.lastbestblock != c:
             block = self.rpc_conn.getblock(c['bestblockhash'])
             txids = block['tx']
             transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
-            rtn = []
             for t in transactions:
-                #claims = self.rpc_conn.getclaimsfortx(t['txid'])
-                claims = self.rpc_conn.getclaimsfortx("c3684bd587856ba5cc38c4afdbcd2c6efc60cb2d1ed21188485ea58048b419a8")
+                claims = self.rpc_conn.getclaimsfortx(t['txid'])
+                #claims = self.rpc_conn.getclaimsfortx("c3684bd587856ba5cc38c4afdbcd2c6efc60cb2d1ed21188485ea58048b419a8")
                 if claims:
                     for claim in claims:
                         if claim not in self.seen:
-                            #self.console.sendLine(str(claim))
                             self.console.sendLine("lbry://" + str(claim['name']) + " | stream hash: " +
                                                         str(json.loads(claim['value'])['stream_hash']))
                             rtn.append(claim['name'])
                             self.seen.append(claim)
-            if not len(rtn):
-                self.console.sendLine("No claims in block " + str(block['hash']) + ", height: " + str(block['height']))
+                else:
+                    #self.console.sendLine("No new claims in block #" + str(block['height']))
+                    pass
 
         self.lastbestblock = c
+
         if len(rtn):
             return defer.succeed(rtn)
-        else:
-            return defer.failure(None)
 
     def _download_claims(self, claims):
-        for claim in claims:
-            download = defer.Deferred()
-            stream = AutoAddStreamFromLBRYcrdName(self.console, self.sd_identifier, self.session,
-                                                  self.wallet, self.lbry_file_manager)
-            download.addCallback(lambda _: stream.start(str(claim)))
-            download.callback(None)
-            self.console.sendLine("Download complete")
+        if claims:
+            for claim in claims:
+                download = defer.Deferred()
+                stream = AutoAddStreamFromLBRYcrdName(self.console, self.sd_identifier, self.session,
+                                                      self.wallet, self.lbry_file_manager)
+                download.addCallback(lambda _: stream.start(str(claim)))
+                download.callback(None)
+
         return defer.succeed(None)
 
+    def _looped_search(self):
+        d = defer.Deferred(None)
+        d.addCallback(lambda _: self._get_names())
+        d.addCallback(self._download_claims)
+        d.callback(None)
 
 class AutoFetcherFactory(CommandHandlerFactory):
     control_handler_class = AutoFetcher
     command = "start-autofetching"
-    short_help = "Download all lbry files as they are published"
\ No newline at end of file
+    short_help = "Download all lbry files as they are published"
+
+
+class BlockchainStatus(CommandHandler):
+    def __init__(self, console, wallet=None):
+        CommandHandler.__init__(self, console)
+        self.wallet = wallet
+
+    def start(self):
+        d = self.wallet.get_most_recent_blocktime()
+        d.addCallbacks(self._show_time_behind_blockchain, self._show_error)
+        d.chainDeferred(self.finished_deferred)
+        return d
+
+    def _show_time_behind_blockchain(self, best_block_time):
+        best_time = datetime.datetime.utcfromtimestamp(best_block_time)
+        diff = datetime.datetime.utcnow() - best_time
+        unit = None
+        val = None
+        if diff.days > 0:
+            if diff.days >= 7:
+                val = diff.days // 7
+                unit = "week"
+            else:
+                val = diff.days
+                unit = "day"
+        elif diff.seconds >= 60 * 90:
+            if diff.seconds >= 60 * 60:
+                val = diff.seconds // (60 * 60)
+                unit = "hour"
+        if unit is not None:
+            if val != 1:
+                unit += "s"
+            self.console.sendLine("This application is %d %s behind the LBC blockchain." % (val, unit))
+        else:
+            self.console.sendLine("This application is up to date with the LBC blockchain.")
+
+    def _show_error(self, err):
+        logging.error(err.getTraceback())
+        self.console.sendLine("Unable to determine the status of the blockchain.")
+
+
+class BlockchainStatusFactory(CommandHandlerFactory):
+    control_handler_class = BlockchainStatus
+    command = "get-blockchain-status"
+    short_help = "Show whether this application has caught up with the LBC blockchain"
+    full_help = "Show whether this applications has caught up with the LBC blockchain"
+

From 34aa51e98aa03f425fb1403e928f737a10159171 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Sat, 14 Nov 2015 21:57:58 -0500
Subject: [PATCH 05/21] remove debugging messages

---
 .idea/workspace.xml                        | 1235 ++++++++++++++++++++
 lbrynet/lbrynet_console/ControlHandlers.py |    9 -
 2 files changed, 1235 insertions(+), 9 deletions(-)
 create mode 100644 .idea/workspace.xml

diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 000000000..2b53e158a
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,1235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AnalysisUIOptions">
+    <option name="SCOPE_TYPE" value="3" />
+  </component>
+  <component name="ChangeListManager">
+    <list default="true" id="55ac8599-e726-4c97-bb6e-843a6d7c4acc" name="Default" comment="" />
+    <ignored path="lbry.iws" />
+    <ignored path=".idea/workspace.xml" />
+    <ignored path=".idea/dataSources.local.xml" />
+    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+    <option name="TRACKING_ENABLED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
+  <component name="CoverageDataManager">
+    <SUITE FILE_PATH="coverage/lbry$ControlHandlers.coverage" NAME="ControlHandlers Coverage Results" MODIFIED="1447114189280" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/lbrynet/lbrynet_console" />
+    <SUITE FILE_PATH="coverage/lbry$StreamDescriptor.coverage" NAME="StreamDescriptor Coverage Results" MODIFIED="1447028077140" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/lbrynet/core" />
+    <SUITE FILE_PATH="coverage/lbry$AutoFetcher.coverage" NAME="AutoFetcher Coverage Results" MODIFIED="1446947738130" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/lbrynet/core" />
+    <SUITE FILE_PATH="coverage/lbry$LBRYConsole.coverage" NAME="LBRYConsole Coverage Results" MODIFIED="1447555368694" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/lbrynet/lbrynet_console" />
+  </component>
+  <component name="CreatePatchCommitExecutor">
+    <option name="PATCH_PATH" value="" />
+  </component>
+  <component name="DatabaseView">
+    <option name="GROUP_SCHEMA" value="true" />
+    <option name="GROUP_CONTENTS" value="false" />
+    <option name="SORT_POSITIONED" value="false" />
+    <option name="SHOW_TABLE_DETAILS" value="true" />
+    <option name="SHOW_EMPTY_GROUPS" value="false" />
+  </component>
+  <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
+  <component name="FavoritesManager">
+    <favorites_list name="lbry" />
+  </component>
+  <component name="FileEditorManager">
+    <leaf>
+      <file leaf-file-name="ControlHandlers.py" pinned="false" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/ControlHandlers.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="-26.322075">
+              <caret line="789" column="0" selection-start-line="789" selection-start-column="0" selection-end-line="789" selection-end-column="0" />
+              <folding>
+                <element signature="e#0#11#0" expanded="true" />
+                <element signature="e#1157#1161#0" expanded="false" />
+                <element signature="e#1204#1208#0" expanded="false" />
+                <element signature="e#1731#2208#0" expanded="false" />
+                <element signature="e#2245#2500#0" expanded="false" />
+                <element signature="e#2552#3180#0" expanded="false" />
+                <element signature="e#3235#5573#0" expanded="false" />
+                <element signature="e#5622#7291#0" expanded="false" />
+                <element signature="e#7339#8236#0" expanded="false" />
+                <element signature="e#8298#8638#0" expanded="false" />
+                <element signature="e#8686#9497#0" expanded="false" />
+                <element signature="e#9559#9778#0" expanded="false" />
+                <element signature="e#9828#10422#0" expanded="false" />
+                <element signature="e#10486#10705#0" expanded="false" />
+                <element signature="e#10744#11431#0" expanded="false" />
+                <element signature="e#11484#11611#0" expanded="false" />
+                <element signature="e#11656#12731#0" expanded="false" />
+                <element signature="e#25614#25892#0" expanded="false" />
+                <element signature="e#25952#26309#0" expanded="false" />
+                <element signature="e#31776#32529#0" expanded="false" />
+                <element signature="e#32585#33388#0" expanded="false" />
+                <element signature="e#33448#33549#0" expanded="false" />
+                <element signature="e#33602#33966#0" expanded="false" />
+                <element signature="e#34032#34633#0" expanded="false" />
+                <element signature="e#34678#37825#0" expanded="false" />
+                <element signature="e#37885#37923#0" expanded="false" />
+                <element signature="e#37983#38273#0" expanded="false" />
+                <element signature="e#38346#38627#0" expanded="false" />
+                <element signature="e#38679#39520#0" expanded="false" />
+                <element signature="e#39587#39632#0" expanded="false" />
+                <element signature="e#39677#40945#0" expanded="false" />
+                <element signature="e#41004#41716#0" expanded="false" />
+                <element signature="e#41778#42195#0" expanded="false" />
+                <element signature="e#42270#42719#0" expanded="false" />
+                <element signature="e#42773#43912#0" expanded="false" />
+                <element signature="e#43981#44028#0" expanded="false" />
+                <element signature="e#44088#44406#0" expanded="false" />
+                <element signature="e#106689#108058#0" expanded="false" />
+                <element signature="e#108119#108371#0" expanded="false" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+    </leaf>
+  </component>
+  <component name="FileTemplateManagerImpl">
+    <option name="RECENT_TEMPLATES">
+      <list>
+        <option value="Python Script" />
+      </list>
+    </option>
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="IdeDocumentHistory">
+    <option name="CHANGED_PATHS">
+      <list>
+        <option value="$PROJECT_DIR$/lbrynet/node_rpc_cli.py" />
+        <option value="$PROJECT_DIR$/lbrynet/rpc_node.py" />
+        <option value="$PROJECT_DIR$/lbrynet/core/StreamDescriptor.py" />
+        <option value="$PROJECT_DIR$/lbrynet/lbryfile/client/LBRYFileDownloader.py" />
+        <option value="$APPLICATION_CONFIG_DIR$/scratches/scratch_1" />
+        <option value="$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileManager.py" />
+        <option value="$PROJECT_DIR$/lbrynet/core/LBRYcrdWallet.py" />
+        <option value="$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileDownloader.py" />
+        <option value="$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYConsole.py" />
+        <option value="$PROJECT_DIR$/lbrynet/core/AutoFetcher.py" />
+        <option value="$PROJECT_DIR$/lbrynet/core/client/StandaloneBlobDownloader.py" />
+        <option value="$PROJECT_DIR$/lbrynet/lbrynet_console/ControlHandlers.py" />
+      </list>
+    </option>
+  </component>
+  <component name="JsBuildToolGruntFileManager" detection-done="true" />
+  <component name="JsBuildToolPackageJson" detection-done="true" />
+  <component name="JsGulpfileManager">
+    <detection-done>true</detection-done>
+  </component>
+  <component name="ProjectFrameBounds">
+    <option name="width" value="1440" />
+    <option name="height" value="900" />
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectView">
+    <navigator currentView="ProjectPane" proportions="" version="1">
+      <flattenPackages />
+      <showMembers />
+      <showModules />
+      <showLibraryContents />
+      <hideEmptyPackages />
+      <abbreviatePackageNames />
+      <autoscrollToSource />
+      <autoscrollFromSource />
+      <sortByType />
+      <manualOrder />
+      <foldersAlwaysOnTop value="true" />
+    </navigator>
+    <panes>
+      <pane id="Scope" />
+      <pane id="Scratches" />
+      <pane id="ProjectPane">
+        <subPane>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbrynet" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbrynet" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbrynet_console" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbrynet" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="core" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbry" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="lbrynet" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="core" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="client" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+        </subPane>
+      </pane>
+    </panes>
+  </component>
+  <component name="PropertiesComponent">
+    <property name="settings.editor.selected.configurable" value="vcs.Git" />
+    <property name="settings.editor.splitter.proportion" value="0.2" />
+    <property name="last_opened_file_path" value="$USER_HOME$/PycharmProjects/inventory" />
+    <property name="WebServerToolWindowFactoryState" value="false" />
+    <property name="SearchEverywhereHistoryKey" value="8333&#9;null&#9;null&#10;node.&#9;FILE&#9;file:///Users/johnrobison/lbry/lbrynet/rpc_node.py&#10;rpc&#9;FILE&#9;file:///Users/johnrobison/lbry/lbrynet/rpc_node.py&#10;rpc_conn&#9;null&#9;null&#10;rpc_conn.&#9;null&#9;null&#10;claim&#9;null&#9;null&#10;dht&#9;FILE&#9;file:///Users/johnrobison/lbry/build/lib/lbrynet/core/client/DHTPeerFinder.py&#10;router&#9;null&#9;null&#10;cli&#9;FILE&#9;file:///Users/johnrobison/lbry/lbrynet/core/client/ClientProtocol.py" />
+    <property name="com.intellij.ide.scratch.LRUPopupBuilder$2/Languages" value="Python" />
+    <property name="FullScreen" value="true" />
+  </component>
+  <component name="RecentsManager">
+    <key name="CopyFile.RECENT_KEYS">
+      <recent name="$USER_HOME$/" />
+    </key>
+  </component>
+  <component name="RunManager" selected="Python.LBRYConsole">
+    <configuration default="false" name="AutoFetcher" type="PythonConfigurationType" factoryName="Python" temporary="true">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/lbrynet/core" />
+      <option name="IS_MODULE_SDK" value="true" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/lbrynet/core/AutoFetcher.py" />
+      <option name="PARAMETERS" value="" />
+      <option name="SHOW_COMMAND_LINE" value="false" />
+      <method />
+    </configuration>
+    <configuration default="false" name="LBRYConsole" type="PythonConfigurationType" factoryName="Python" temporary="true">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/lbrynet/lbrynet_console" />
+      <option name="IS_MODULE_SDK" value="true" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYConsole.py" />
+      <option name="PARAMETERS" value="" />
+      <option name="SHOW_COMMAND_LINE" value="false" />
+      <method />
+    </configuration>
+    <configuration default="false" name="StreamDescriptor" type="PythonConfigurationType" factoryName="Python" temporary="true">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/lbrynet/core" />
+      <option name="IS_MODULE_SDK" value="true" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/lbrynet/core/StreamDescriptor.py" />
+      <option name="PARAMETERS" value="" />
+      <option name="SHOW_COMMAND_LINE" value="false" />
+      <method />
+    </configuration>
+    <configuration default="false" name="ControlHandlers" type="PythonConfigurationType" factoryName="Python" temporary="true">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/lbrynet/lbrynet_console" />
+      <option name="IS_MODULE_SDK" value="true" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/lbrynet/lbrynet_console/ControlHandlers.py" />
+      <option name="PARAMETERS" value="" />
+      <option name="SHOW_COMMAND_LINE" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="DjangoTestsConfigurationType" factoryName="Django tests">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="TARGET" value="" />
+      <option name="SETTINGS_FILE" value="" />
+      <option name="CUSTOM_SETTINGS" value="false" />
+      <option name="USE_OPTIONS" value="false" />
+      <option name="OPTIONS" value="" />
+      <method />
+    </configuration>
+    <configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
+      <method />
+    </configuration>
+    <configuration default="true" type="PyBehaveRunConfigurationType" factoryName="Behave">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="ADDITIONAL_ARGS" value="" />
+      <method />
+    </configuration>
+    <configuration default="true" type="PyLettuceRunConfigurationType" factoryName="Lettuce">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="ADDITIONAL_ARGS" value="" />
+      <method />
+    </configuration>
+    <configuration default="true" type="PythonConfigurationType" factoryName="Python">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="PARAMETERS" value="" />
+      <option name="SHOW_COMMAND_LINE" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
+      <node-options />
+      <gulpfile />
+      <tasks />
+      <arguments />
+      <envs />
+      <method />
+    </configuration>
+    <configuration default="true" type="js.build_tools.npm" factoryName="npm">
+      <command value="run-script" />
+      <scripts />
+      <envs />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="Attests">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="Doctests">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="Nosetests">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <option name="PARAMS" value="" />
+      <option name="USE_PARAM" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="Unittests">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <option name="PUREUNITTEST" value="true" />
+      <option name="PARAMS" value="" />
+      <option name="USE_PARAM" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="py.test">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="lbry" />
+      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <option name="testToRun" value="" />
+      <option name="keywords" value="" />
+      <option name="params" value="" />
+      <option name="USE_PARAM" value="false" />
+      <option name="USE_KEYWORD" value="false" />
+      <method />
+    </configuration>
+    <list size="4">
+      <item index="0" class="java.lang.String" itemvalue="Python.AutoFetcher" />
+      <item index="1" class="java.lang.String" itemvalue="Python.LBRYConsole" />
+      <item index="2" class="java.lang.String" itemvalue="Python.StreamDescriptor" />
+      <item index="3" class="java.lang.String" itemvalue="Python.ControlHandlers" />
+    </list>
+    <recent_temporary>
+      <list size="4">
+        <item index="0" class="java.lang.String" itemvalue="Python.LBRYConsole" />
+        <item index="1" class="java.lang.String" itemvalue="Python.ControlHandlers" />
+        <item index="2" class="java.lang.String" itemvalue="Python.StreamDescriptor" />
+        <item index="3" class="java.lang.String" itemvalue="Python.AutoFetcher" />
+      </list>
+    </recent_temporary>
+  </component>
+  <component name="ShelveChangesManager" show_recycled="false" />
+  <component name="SvnConfiguration">
+    <configuration />
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="55ac8599-e726-4c97-bb6e-843a6d7c4acc" name="Default" comment="" />
+      <created>1446828623675</created>
+      <option name="number" value="Default" />
+      <updated>1446828623675</updated>
+    </task>
+    <servers />
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="0" y="0" width="1440" height="900" extended-state="0" />
+    <editor active="true" />
+    <layout>
+      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.22771084" sideWeight="0.50572246" order="7" side_tool="true" content_ui="tabs" />
+      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+      <window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32891566" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32891566" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25180724" sideWeight="0.49427754" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32891566" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.15450644" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
+      <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3297568" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.18313253" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.24964234" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
+      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Concurrent Activities Diagram" active="true" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32891566" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
+    </layout>
+  </component>
+  <component name="Vcs.Log.UiProperties">
+    <option name="RECENTLY_FILTERED_USER_GROUPS">
+      <collection />
+    </option>
+    <option name="RECENTLY_FILTERED_BRANCH_GROUPS">
+      <collection />
+    </option>
+  </component>
+  <component name="VcsContentAnnotationSettings">
+    <option name="myLimit" value="2678400000" />
+  </component>
+  <component name="XDebuggerManager">
+    <breakpoint-manager>
+      <option name="time" value="16" />
+    </breakpoint-manager>
+    <watches-manager />
+  </component>
+  <component name="editorHistoryManager">
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/DownloadManager.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/LiveStreamMetadataManager.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/LiveStreamCreator.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/LBRYStdoutDownloader.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.43293718">
+          <caret line="52" column="57" selection-start-line="52" selection-start-column="48" selection-end-line="52" selection-end-column="59" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/LiveBlob.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/PaymentRateManager.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbryfile/StreamDescriptor.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.13293944">
+          <caret line="6" column="71" selection-start-line="6" selection-start-column="71" selection-end-line="6" selection-end-column="71" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbrylive/LiveStreamCreator.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.44313148">
+          <caret line="20" column="8" selection-start-line="20" selection-start-column="8" selection-end-line="20" selection-end-column="8" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/StreamDescriptor.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.2658789">
+          <caret line="60" column="31" selection-start-line="60" selection-start-column="31" selection-end-line="60" selection-end-column="31" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/node_rpc_cli.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.6875754">
+          <caret line="41" column="17" selection-start-line="41" selection-start-column="17" selection-end-line="41" selection-end-column="17" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/rpc_node.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.6381182">
+          <caret line="46" column="17" selection-start-line="46" selection-start-column="17" selection-end-line="46" selection-end-column="17" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/interfaces.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/conf.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.3799759">
+          <caret line="21" column="22" selection-start-line="21" selection-start-column="22" selection-end-line="21" selection-end-column="83" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYSettings.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/dht/node.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.3325031">
+          <caret line="202" column="73" selection-start-line="202" selection-start-column="72" selection-end-line="202" selection-end-column="73" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/pointtraderclient/pointtraderclient.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="-3.2159228">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/DHTPeerFinder.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.54282266">
+          <caret line="32" column="0" selection-start-line="32" selection-start-column="0" selection-end-line="32" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/ConnectionManager.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/ClientRequest.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/ClientProtocol.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/StreamProgressManager.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="-1.6960193">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbryfile/client/LBRYFileDownloader.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="95" column="0" selection-start-line="95" selection-start-column="0" selection-end-line="134" selection-end-column="12" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileStatusReport.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$APPLICATION_CONFIG_DIR$/scratches/scratch_1">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.75121164">
+          <caret line="31" column="17" selection-start-line="31" selection-start-column="17" selection-end-line="31" selection-end-column="17" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$USER_HOME$/jake.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/StreamCreator.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/utils.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbryfile/client/LBRYFileOptions.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.088626295">
+          <caret line="5" column="24" selection-start-line="5" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/LBRYFileMetadataManager.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.872969">
+          <caret line="181" column="50" selection-start-line="181" selection-start-column="50" selection-end-line="181" selection-end-column="50" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYPlugin.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <marker date="1446821820000" expanded="true" signature="87:118" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="154:188" placeholder="..." />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbrynet_gui/LBRYGui.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.3323486">
+          <caret line="403" column="52" selection-start-line="403" selection-start-column="52" selection-end-line="403" selection-end-column="52" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/cryptstream/CryptBlob.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="-0.10869565">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/cryptstream/CryptStreamCreator.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileCreator.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.33269963">
+          <caret line="71" column="14" selection-start-line="71" selection-start-column="9" selection-end-line="71" selection-end-column="14" />
+          <folding>
+            <marker date="1446821820000" expanded="true" signature="0:58" placeholder="&quot;&quot;&quot;...&quot;&quot;&quot;" />
+            <marker date="1446821820000" expanded="true" signature="60:506" placeholder="import ..." />
+            <marker date="1446821820000" expanded="true" signature="593:3261" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="598:702" placeholder="&quot;&quot;&quot;...&quot;&quot;&quot;" />
+            <marker date="1446821820000" expanded="true" signature="842:1192" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1234:1331" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1368:1770" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1792:1903" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1938:2643" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2677:2982" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="3008:3261" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="3418:5138" placeholder="&quot;&quot;&quot;Turn a plain file into an LBRY File....&quot;&quot;&quot;" />
+            <marker date="1446821820000" expanded="true" signature="5167:5289" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="5334:5649" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="5914:6251" placeholder="..." />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/Session.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileManager.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.94015443">
+          <caret line="129" column="52" selection-start-line="129" selection-start-column="32" selection-end-line="129" selection-end-column="52" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileDownloader.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="-0.023166023">
+          <caret line="20" column="34" selection-start-line="20" selection-start-column="23" selection-end-line="20" selection-end-column="34" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/BlobManager.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="-0.05212355">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <marker date="1446821820000" expanded="true" signature="0:535" placeholder="import ..." />
+            <marker date="1446821820000" expanded="true" signature="609:1709" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="792:847" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="869:882" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="942:955" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="988:1001" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1067:1080" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1142:1155" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1203:1216" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1251:1264" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1311:1324" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1363:1376" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1419:1432" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1466:1479" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1521:1534" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1577:1590" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1634:1647" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1696:1709" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1747:15813" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1856:2252" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2274:2501" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2522:2837" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2902:3294" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="3327:3386" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="3457:4165" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="3668:4108" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="3705:3742" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="4227:4453" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="4501:4554" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="4589:4721" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="4768:5517" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="5559:5719" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="5777:5840" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="5885:6013" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="6056:6104" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="6138:6179" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="6203:6468" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="6339:6411" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="6518:7956" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="6554:6625" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="6666:6838" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="6875:7259" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="7098:7201" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="7291:7440" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="8021:8812" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="8454:8810" placeholder="create table..if..." />
+            <marker date="1446821820000" expanded="true" signature="8924:9345" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="9136:9173" placeholder="insert into blobs..." />
+            <marker date="1446821820000" expanded="true" signature="9415:10987" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="9528:9952" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="9681:9737" placeholder="select last_..blobs..." />
+            <marker date="1446821820000" expanded="true" signature="9995:10873" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="10056:10294" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="10340:10601" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="11047:11354" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="11083:11132" placeholder="select blob_..blobs..." />
+            <marker date="1446821820000" expanded="true" signature="11440:11596" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="11479:11538" placeholder="update blobs..." />
+            <marker date="1446821820000" expanded="true" signature="11676:12268" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="11718:12208" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="11792:11915" placeholder="select blob_..blobs..." />
+            <marker date="1446821820000" expanded="true" signature="12048:12116" placeholder="update blobs..." />
+            <marker date="1446821820000" expanded="true" signature="12348:12442" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="12387:12426" placeholder="update blobs..." />
+            <marker date="1446821820000" expanded="true" signature="12514:12729" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="12554:12671" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="12626:12663" placeholder="delete from ..." />
+            <marker date="1446821820000" expanded="true" signature="12785:15162" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="12934:12994" placeholder="select blob_..blobs..." />
+            <marker date="1446821820000" expanded="true" signature="13060:13804" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="13834:14395" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="14451:14633" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="14517:14576" placeholder="update blobs..." />
+            <marker date="1446821820000" expanded="true" signature="14666:15109" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="14745:14986" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="15229:15813" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="15265:15312" placeholder="select blob_..blobs..." />
+            <marker date="1446821820000" expanded="true" signature="15354:15709" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="15935:16252" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="16274:16332" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="16353:16522" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="16587:16749" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="16782:16826" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="16897:17034" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="17096:17285" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="17333:17486" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="17521:17849" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="17896:18702" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="18744:18904" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="18947:19161" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="19206:19283" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="19307:19642" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="19443:19585" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="19728:19850" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="19891:20063" placeholder="..." />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/ConsoleControl.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.625">
+          <caret line="68" column="25" selection-start-line="68" selection-start-column="25" selection-end-line="68" selection-end-column="25" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/StreamDescriptor.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.33204633">
+          <caret line="168" column="90" selection-start-line="168" selection-start-column="82" selection-end-line="168" selection-end-column="90" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/client/LBRYFileDownloader.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="6.955836">
+          <caret line="294" column="73" selection-start-line="294" selection-start-column="73" selection-end-line="294" selection-end-column="73" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/client/LBRYFileOptions.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="-0.0015772871">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$USER_HOME$/Downloads/x.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.85804415">
+          <caret line="91" column="10" selection-start-line="91" selection-start-column="10" selection-end-line="91" selection-end-column="10" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/AutoFetcher.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="-0.37223974">
+          <caret line="8" column="1" selection-start-line="8" selection-start-column="1" selection-end-line="8" selection-end-column="1" />
+          <folding>
+            <marker date="1446947371000" expanded="true" signature="0:159" placeholder="import ..." />
+            <marker date="1446947371000" expanded="true" signature="176:194" placeholder="..." />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYConsole.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="-5.104101">
+          <caret line="221" column="16" selection-start-line="221" selection-start-column="16" selection-end-line="221" selection-end-column="16" />
+          <folding>
+            <marker date="1447551514000" expanded="true" signature="0:91" placeholder="import ..." />
+            <marker date="1447551514000" expanded="true" signature="17770:22272" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="3230:5051" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="3239:3524" placeholder="&quot;&quot;&quot;@param peer_port: the network port on which to listen for peers...&quot;&quot;&quot;" />
+            <marker date="1447551514000" expanded="true" signature="5073:6006" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="6047:6187" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="6231:6371" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="6397:6674" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="6729:6836" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="6887:7402" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="6931:7146" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="7440:7972" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="8008:9125" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="8527:9027" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="9155:9363" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="9397:10152" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="9517:9840" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="9943:10092" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="10187:10300" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="10329:10433" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="10462:12365" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="10499:10710" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="10737:11389" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="11492:11649" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="11687:12143" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="12406:12823" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="12577:12747" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="12863:13330" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="17770:18098" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="18136:19294" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="18708:19053" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="19324:19741" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="19424:19674" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="19771:19938" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="19968:20249" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="20014:20128" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="20278:21014" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="21042:21264" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="21298:21765" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="21799:21859" placeholder="..." />
+            <marker date="1447551514000" expanded="false" signature="21886:22272" placeholder="..." />
+            <marker date="1447551514000" expanded="true" signature="22301:27080" placeholder="..." />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/interfaces.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/client/LBRYFileMetadataHandler.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.64935064">
+          <caret line="33" column="33" selection-start-line="33" selection-start-column="33" selection-end-line="33" selection-end-column="33" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/StreamDescriptor.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.8221344">
+          <caret line="242" column="32" selection-start-line="242" selection-start-column="32" selection-end-line="242" selection-end-column="32" />
+          <folding>
+            <marker date="1447551153000" expanded="true" signature="0:265" placeholder="import ..." />
+            <marker date="1447551153000" expanded="true" signature="341:876" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="503:516" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="546:713" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="738:876" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="937:1435" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="1068:1183" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="1213:1435" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="1238:1387" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="1495:1653" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="1581:1653" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="1701:2054" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="1726:2006" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="2094:2524" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="2236:2249" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="2292:2358" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="2409:2524" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="2585:3026" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="2623:2710" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="2761:3026" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="2788:2976" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="3086:3517" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="3124:3212" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="3263:3517" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="3549:3848" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="3642:3848" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="7207:8718" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="3897:4179" placeholder="&quot;&quot;&quot;...&quot;&quot;&quot;" />
+            <marker date="1447551153000" expanded="true" signature="4203:4460" placeholder="..." />
+            <marker date="1447551153000" expanded="false" signature="4540:5647" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="4549:5522" placeholder="&quot;&quot;&quot;This is how the StreamDescriptorIdentifier learns about new types of stream descriptors....&quot;&quot;&quot;" />
+            <marker date="1447551153000" expanded="true" signature="5715:6374" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="5724:6303" placeholder="&quot;&quot;&quot;Register a stream downloader factory with the StreamDescriptorIdentifier....&quot;&quot;&quot;" />
+            <marker date="1447551153000" expanded="true" signature="6457:6820" placeholder="..." />
+            <marker date="1447551153000" expanded="false" signature="6870:7130" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="7207:7429" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="7473:7654" placeholder="..." />
+            <marker date="1447551153000" expanded="false" signature="7698:7870" placeholder="..." />
+            <marker date="1447551153000" expanded="false" signature="7912:8080" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="8149:8718" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="8551:8653" placeholder="..." />
+            <marker date="1447551153000" expanded="true" signature="8789:8964" placeholder="&quot;&quot;&quot;Downloads a single blob from the network...&quot;&quot;&quot;" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/StandaloneBlobDownloader.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.33266532">
+          <caret line="107" column="0" selection-start-line="107" selection-start-column="0" selection-end-line="107" selection-end-column="0" />
+          <folding>
+            <marker date="1446821820000" expanded="true" signature="0:497" placeholder="import ..." />
+            <marker date="1446821820000" expanded="true" signature="576:992" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="674:758" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="833:944" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="975:992" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1031:2758" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1092:1266" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1288:1507" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1528:1714" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="1749:2102" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2134:2262" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2291:2437" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2485:2758" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2792:2887" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2816:2829" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="2874:2887" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="3036:3353" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="3378:4876" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="3538:3562" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="4897:4953" placeholder="..." />
+            <marker date="1446821820000" expanded="true" signature="4992:5108" placeholder="..." />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/core/LBRYcrdWallet.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.04809619">
+          <caret line="267" column="32" selection-start-line="267" selection-start-column="8" selection-end-line="267" selection-end-column="32" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/ControlHandlers.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="-26.322075">
+          <caret line="789" column="0" selection-start-line="789" selection-start-column="0" selection-end-line="789" selection-end-column="0" />
+          <folding>
+            <element signature="e#0#11#0" expanded="true" />
+            <element signature="e#1157#1161#0" expanded="false" />
+            <element signature="e#1204#1208#0" expanded="false" />
+            <element signature="e#1731#2208#0" expanded="false" />
+            <element signature="e#2245#2500#0" expanded="false" />
+            <element signature="e#2552#3180#0" expanded="false" />
+            <element signature="e#3235#5573#0" expanded="false" />
+            <element signature="e#5622#7291#0" expanded="false" />
+            <element signature="e#7339#8236#0" expanded="false" />
+            <element signature="e#8298#8638#0" expanded="false" />
+            <element signature="e#8686#9497#0" expanded="false" />
+            <element signature="e#9559#9778#0" expanded="false" />
+            <element signature="e#9828#10422#0" expanded="false" />
+            <element signature="e#10486#10705#0" expanded="false" />
+            <element signature="e#10744#11431#0" expanded="false" />
+            <element signature="e#11484#11611#0" expanded="false" />
+            <element signature="e#11656#12731#0" expanded="false" />
+            <element signature="e#25614#25892#0" expanded="false" />
+            <element signature="e#25952#26309#0" expanded="false" />
+            <element signature="e#31776#32529#0" expanded="false" />
+            <element signature="e#32585#33388#0" expanded="false" />
+            <element signature="e#33448#33549#0" expanded="false" />
+            <element signature="e#33602#33966#0" expanded="false" />
+            <element signature="e#34032#34633#0" expanded="false" />
+            <element signature="e#34678#37825#0" expanded="false" />
+            <element signature="e#37885#37923#0" expanded="false" />
+            <element signature="e#37983#38273#0" expanded="false" />
+            <element signature="e#38346#38627#0" expanded="false" />
+            <element signature="e#38679#39520#0" expanded="false" />
+            <element signature="e#39587#39632#0" expanded="false" />
+            <element signature="e#39677#40945#0" expanded="false" />
+            <element signature="e#41004#41716#0" expanded="false" />
+            <element signature="e#41778#42195#0" expanded="false" />
+            <element signature="e#42270#42719#0" expanded="false" />
+            <element signature="e#42773#43912#0" expanded="false" />
+            <element signature="e#43981#44028#0" expanded="false" />
+            <element signature="e#44088#44406#0" expanded="false" />
+            <element signature="e#106689#108058#0" expanded="false" />
+            <element signature="e#108119#108371#0" expanded="false" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+  </component>
+</project>
\ No newline at end of file
diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py
index b391d8818..7d2cb64db 100644
--- a/lbrynet/lbrynet_console/ControlHandlers.py
+++ b/lbrynet/lbrynet_console/ControlHandlers.py
@@ -417,7 +417,6 @@ class AddStream(CommandHandler):
         self.payment_rate_manager = PaymentRateManager(base_payment_rate_manager)
 
     def start(self):
-        self.console.sendLine("Starting addstream...")
         self.console.sendLine(self.cancel_prompt)
         self.loading_metadata_deferred.addCallback(self._handle_metadata)
         self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
@@ -652,7 +651,6 @@ class AddStream(CommandHandler):
         return choice_string
 
     def _start_download(self):
-        print 'Starting addstream._start_download'
         d = self._make_downloader()
         d.addCallback(lambda stream_downloader: stream_downloader.start())
         d.addErrback(self._handle_download_error)
@@ -666,7 +664,6 @@ class AddStream(CommandHandler):
             self.console.sendLine("An unexpected error has caused the download to stop. See console.log for details.")
 
     def _make_downloader(self):
-        print 'Making downloader'
         return self.factory.make_downloader(self.metadata, self.options_chosen,
                                             self.payment_rate_manager)
 
@@ -698,7 +695,6 @@ class AddStreamFromHash(AddStream):
         self.session = session
 
     def start(self, sd_hash):
-        print 'Starting addstreamfromhash'
         self.loading_metadata_deferred = download_sd_blob(self.session, sd_hash,
                                                           self.payment_rate_manager)
         self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
@@ -742,14 +738,12 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash):
         self.name = None
 
     def start(self, name):
-        print 'Starting addstreamfromlbrycrdname'
         self.name = name
         self.loading_metadata_deferred = self._resolve_name(name)
         self.loading_metadata_deferred.addCallback(lambda stream_hash: download_sd_blob(self.session,
                                                                                         stream_hash,
                                                                                         self.payment_rate_manager))
         self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
-        print 'Sending addstream.start from crdname'
         AddStream.start(self)
 
     def _resolve_name(self, name):
@@ -767,7 +761,6 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash):
             return stream_info['stream_hash']
         d = self.wallet.get_stream_info_for_name(name)
         d.addCallback(get_name_from_info)
-        print 'Resolved name'
         return d
 
     def _handle_load_failed(self, err):
@@ -789,13 +782,11 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash):
         return AddStreamFromHash._handle_load_failed(self, err)
 
     def _start_download(self):
-        print 'Startind download in addstreamlbrycrd'
         d = self._pay_key_fee()
         d.addCallback(lambda _: AddStream._start_download(self))
         return d
 
     def _pay_key_fee(self):
-        print 'Paying kee fee'
         if self.key_fee is not None and self.key_fee_address is not None:
             reserved_points = self.wallet.reserve_points(self.key_fee_address, self.key_fee)
             if reserved_points is None:

From 94cdd6829c8f5c504d307ec967bb6675b030f545 Mon Sep 17 00:00:00 2001
From: jackrobison <jack@robisonservice.com>
Date: Sat, 14 Nov 2015 21:59:57 -0500
Subject: [PATCH 06/21] Delete workspace.xml

---
 .idea/workspace.xml | 1235 -------------------------------------------
 1 file changed, 1235 deletions(-)
 delete mode 100644 .idea/workspace.xml

diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index 2b53e158a..000000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,1235 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="AnalysisUIOptions">
-    <option name="SCOPE_TYPE" value="3" />
-  </component>
-  <component name="ChangeListManager">
-    <list default="true" id="55ac8599-e726-4c97-bb6e-843a6d7c4acc" name="Default" comment="" />
-    <ignored path="lbry.iws" />
-    <ignored path=".idea/workspace.xml" />
-    <ignored path=".idea/dataSources.local.xml" />
-    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
-    <option name="TRACKING_ENABLED" value="true" />
-    <option name="SHOW_DIALOG" value="false" />
-    <option name="HIGHLIGHT_CONFLICTS" value="true" />
-    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
-    <option name="LAST_RESOLUTION" value="IGNORE" />
-  </component>
-  <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
-  <component name="CoverageDataManager">
-    <SUITE FILE_PATH="coverage/lbry$ControlHandlers.coverage" NAME="ControlHandlers Coverage Results" MODIFIED="1447114189280" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/lbrynet/lbrynet_console" />
-    <SUITE FILE_PATH="coverage/lbry$StreamDescriptor.coverage" NAME="StreamDescriptor Coverage Results" MODIFIED="1447028077140" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/lbrynet/core" />
-    <SUITE FILE_PATH="coverage/lbry$AutoFetcher.coverage" NAME="AutoFetcher Coverage Results" MODIFIED="1446947738130" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/lbrynet/core" />
-    <SUITE FILE_PATH="coverage/lbry$LBRYConsole.coverage" NAME="LBRYConsole Coverage Results" MODIFIED="1447555368694" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/lbrynet/lbrynet_console" />
-  </component>
-  <component name="CreatePatchCommitExecutor">
-    <option name="PATCH_PATH" value="" />
-  </component>
-  <component name="DatabaseView">
-    <option name="GROUP_SCHEMA" value="true" />
-    <option name="GROUP_CONTENTS" value="false" />
-    <option name="SORT_POSITIONED" value="false" />
-    <option name="SHOW_TABLE_DETAILS" value="true" />
-    <option name="SHOW_EMPTY_GROUPS" value="false" />
-  </component>
-  <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
-  <component name="FavoritesManager">
-    <favorites_list name="lbry" />
-  </component>
-  <component name="FileEditorManager">
-    <leaf>
-      <file leaf-file-name="ControlHandlers.py" pinned="false" current-in-tab="true">
-        <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/ControlHandlers.py">
-          <provider selected="true" editor-type-id="text-editor">
-            <state vertical-scroll-proportion="-26.322075">
-              <caret line="789" column="0" selection-start-line="789" selection-start-column="0" selection-end-line="789" selection-end-column="0" />
-              <folding>
-                <element signature="e#0#11#0" expanded="true" />
-                <element signature="e#1157#1161#0" expanded="false" />
-                <element signature="e#1204#1208#0" expanded="false" />
-                <element signature="e#1731#2208#0" expanded="false" />
-                <element signature="e#2245#2500#0" expanded="false" />
-                <element signature="e#2552#3180#0" expanded="false" />
-                <element signature="e#3235#5573#0" expanded="false" />
-                <element signature="e#5622#7291#0" expanded="false" />
-                <element signature="e#7339#8236#0" expanded="false" />
-                <element signature="e#8298#8638#0" expanded="false" />
-                <element signature="e#8686#9497#0" expanded="false" />
-                <element signature="e#9559#9778#0" expanded="false" />
-                <element signature="e#9828#10422#0" expanded="false" />
-                <element signature="e#10486#10705#0" expanded="false" />
-                <element signature="e#10744#11431#0" expanded="false" />
-                <element signature="e#11484#11611#0" expanded="false" />
-                <element signature="e#11656#12731#0" expanded="false" />
-                <element signature="e#25614#25892#0" expanded="false" />
-                <element signature="e#25952#26309#0" expanded="false" />
-                <element signature="e#31776#32529#0" expanded="false" />
-                <element signature="e#32585#33388#0" expanded="false" />
-                <element signature="e#33448#33549#0" expanded="false" />
-                <element signature="e#33602#33966#0" expanded="false" />
-                <element signature="e#34032#34633#0" expanded="false" />
-                <element signature="e#34678#37825#0" expanded="false" />
-                <element signature="e#37885#37923#0" expanded="false" />
-                <element signature="e#37983#38273#0" expanded="false" />
-                <element signature="e#38346#38627#0" expanded="false" />
-                <element signature="e#38679#39520#0" expanded="false" />
-                <element signature="e#39587#39632#0" expanded="false" />
-                <element signature="e#39677#40945#0" expanded="false" />
-                <element signature="e#41004#41716#0" expanded="false" />
-                <element signature="e#41778#42195#0" expanded="false" />
-                <element signature="e#42270#42719#0" expanded="false" />
-                <element signature="e#42773#43912#0" expanded="false" />
-                <element signature="e#43981#44028#0" expanded="false" />
-                <element signature="e#44088#44406#0" expanded="false" />
-                <element signature="e#106689#108058#0" expanded="false" />
-                <element signature="e#108119#108371#0" expanded="false" />
-              </folding>
-            </state>
-          </provider>
-        </entry>
-      </file>
-    </leaf>
-  </component>
-  <component name="FileTemplateManagerImpl">
-    <option name="RECENT_TEMPLATES">
-      <list>
-        <option value="Python Script" />
-      </list>
-    </option>
-  </component>
-  <component name="Git.Settings">
-    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
-  </component>
-  <component name="IdeDocumentHistory">
-    <option name="CHANGED_PATHS">
-      <list>
-        <option value="$PROJECT_DIR$/lbrynet/node_rpc_cli.py" />
-        <option value="$PROJECT_DIR$/lbrynet/rpc_node.py" />
-        <option value="$PROJECT_DIR$/lbrynet/core/StreamDescriptor.py" />
-        <option value="$PROJECT_DIR$/lbrynet/lbryfile/client/LBRYFileDownloader.py" />
-        <option value="$APPLICATION_CONFIG_DIR$/scratches/scratch_1" />
-        <option value="$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileManager.py" />
-        <option value="$PROJECT_DIR$/lbrynet/core/LBRYcrdWallet.py" />
-        <option value="$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileDownloader.py" />
-        <option value="$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYConsole.py" />
-        <option value="$PROJECT_DIR$/lbrynet/core/AutoFetcher.py" />
-        <option value="$PROJECT_DIR$/lbrynet/core/client/StandaloneBlobDownloader.py" />
-        <option value="$PROJECT_DIR$/lbrynet/lbrynet_console/ControlHandlers.py" />
-      </list>
-    </option>
-  </component>
-  <component name="JsBuildToolGruntFileManager" detection-done="true" />
-  <component name="JsBuildToolPackageJson" detection-done="true" />
-  <component name="JsGulpfileManager">
-    <detection-done>true</detection-done>
-  </component>
-  <component name="ProjectFrameBounds">
-    <option name="width" value="1440" />
-    <option name="height" value="900" />
-  </component>
-  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
-    <OptionsSetting value="true" id="Add" />
-    <OptionsSetting value="true" id="Remove" />
-    <OptionsSetting value="true" id="Checkout" />
-    <OptionsSetting value="true" id="Update" />
-    <OptionsSetting value="true" id="Status" />
-    <OptionsSetting value="true" id="Edit" />
-    <ConfirmationsSetting value="0" id="Add" />
-    <ConfirmationsSetting value="0" id="Remove" />
-  </component>
-  <component name="ProjectView">
-    <navigator currentView="ProjectPane" proportions="" version="1">
-      <flattenPackages />
-      <showMembers />
-      <showModules />
-      <showLibraryContents />
-      <hideEmptyPackages />
-      <abbreviatePackageNames />
-      <autoscrollToSource />
-      <autoscrollFromSource />
-      <sortByType />
-      <manualOrder />
-      <foldersAlwaysOnTop value="true" />
-    </navigator>
-    <panes>
-      <pane id="Scope" />
-      <pane id="Scratches" />
-      <pane id="ProjectPane">
-        <subPane>
-          <PATH>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
-            </PATH_ELEMENT>
-          </PATH>
-          <PATH>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-          </PATH>
-          <PATH>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbrynet" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-          </PATH>
-          <PATH>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbrynet" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbrynet_console" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-          </PATH>
-          <PATH>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbrynet" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="core" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-          </PATH>
-          <PATH>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbry" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="lbrynet" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="core" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="client" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-          </PATH>
-        </subPane>
-      </pane>
-    </panes>
-  </component>
-  <component name="PropertiesComponent">
-    <property name="settings.editor.selected.configurable" value="vcs.Git" />
-    <property name="settings.editor.splitter.proportion" value="0.2" />
-    <property name="last_opened_file_path" value="$USER_HOME$/PycharmProjects/inventory" />
-    <property name="WebServerToolWindowFactoryState" value="false" />
-    <property name="SearchEverywhereHistoryKey" value="8333&#9;null&#9;null&#10;node.&#9;FILE&#9;file:///Users/johnrobison/lbry/lbrynet/rpc_node.py&#10;rpc&#9;FILE&#9;file:///Users/johnrobison/lbry/lbrynet/rpc_node.py&#10;rpc_conn&#9;null&#9;null&#10;rpc_conn.&#9;null&#9;null&#10;claim&#9;null&#9;null&#10;dht&#9;FILE&#9;file:///Users/johnrobison/lbry/build/lib/lbrynet/core/client/DHTPeerFinder.py&#10;router&#9;null&#9;null&#10;cli&#9;FILE&#9;file:///Users/johnrobison/lbry/lbrynet/core/client/ClientProtocol.py" />
-    <property name="com.intellij.ide.scratch.LRUPopupBuilder$2/Languages" value="Python" />
-    <property name="FullScreen" value="true" />
-  </component>
-  <component name="RecentsManager">
-    <key name="CopyFile.RECENT_KEYS">
-      <recent name="$USER_HOME$/" />
-    </key>
-  </component>
-  <component name="RunManager" selected="Python.LBRYConsole">
-    <configuration default="false" name="AutoFetcher" type="PythonConfigurationType" factoryName="Python" temporary="true">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs>
-        <env name="PYTHONUNBUFFERED" value="1" />
-      </envs>
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/lbrynet/core" />
-      <option name="IS_MODULE_SDK" value="true" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/lbrynet/core/AutoFetcher.py" />
-      <option name="PARAMETERS" value="" />
-      <option name="SHOW_COMMAND_LINE" value="false" />
-      <method />
-    </configuration>
-    <configuration default="false" name="LBRYConsole" type="PythonConfigurationType" factoryName="Python" temporary="true">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs>
-        <env name="PYTHONUNBUFFERED" value="1" />
-      </envs>
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/lbrynet/lbrynet_console" />
-      <option name="IS_MODULE_SDK" value="true" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYConsole.py" />
-      <option name="PARAMETERS" value="" />
-      <option name="SHOW_COMMAND_LINE" value="false" />
-      <method />
-    </configuration>
-    <configuration default="false" name="StreamDescriptor" type="PythonConfigurationType" factoryName="Python" temporary="true">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs>
-        <env name="PYTHONUNBUFFERED" value="1" />
-      </envs>
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/lbrynet/core" />
-      <option name="IS_MODULE_SDK" value="true" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/lbrynet/core/StreamDescriptor.py" />
-      <option name="PARAMETERS" value="" />
-      <option name="SHOW_COMMAND_LINE" value="false" />
-      <method />
-    </configuration>
-    <configuration default="false" name="ControlHandlers" type="PythonConfigurationType" factoryName="Python" temporary="true">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs>
-        <env name="PYTHONUNBUFFERED" value="1" />
-      </envs>
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/lbrynet/lbrynet_console" />
-      <option name="IS_MODULE_SDK" value="true" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/lbrynet/lbrynet_console/ControlHandlers.py" />
-      <option name="PARAMETERS" value="" />
-      <option name="SHOW_COMMAND_LINE" value="false" />
-      <method />
-    </configuration>
-    <configuration default="true" type="DjangoTestsConfigurationType" factoryName="Django tests">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs>
-        <env name="PYTHONUNBUFFERED" value="1" />
-      </envs>
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="IS_MODULE_SDK" value="false" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="TARGET" value="" />
-      <option name="SETTINGS_FILE" value="" />
-      <option name="CUSTOM_SETTINGS" value="false" />
-      <option name="USE_OPTIONS" value="false" />
-      <option name="OPTIONS" value="" />
-      <method />
-    </configuration>
-    <configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
-      <method />
-    </configuration>
-    <configuration default="true" type="PyBehaveRunConfigurationType" factoryName="Behave">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs />
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="IS_MODULE_SDK" value="false" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="ADDITIONAL_ARGS" value="" />
-      <method />
-    </configuration>
-    <configuration default="true" type="PyLettuceRunConfigurationType" factoryName="Lettuce">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs />
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="IS_MODULE_SDK" value="false" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="ADDITIONAL_ARGS" value="" />
-      <method />
-    </configuration>
-    <configuration default="true" type="PythonConfigurationType" factoryName="Python">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs>
-        <env name="PYTHONUNBUFFERED" value="1" />
-      </envs>
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="IS_MODULE_SDK" value="false" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="" />
-      <option name="PARAMETERS" value="" />
-      <option name="SHOW_COMMAND_LINE" value="false" />
-      <method />
-    </configuration>
-    <configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
-      <node-options />
-      <gulpfile />
-      <tasks />
-      <arguments />
-      <envs />
-      <method />
-    </configuration>
-    <configuration default="true" type="js.build_tools.npm" factoryName="npm">
-      <command value="run-script" />
-      <scripts />
-      <envs />
-      <method />
-    </configuration>
-    <configuration default="true" type="tests" factoryName="Attests">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs />
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="IS_MODULE_SDK" value="false" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="" />
-      <option name="CLASS_NAME" value="" />
-      <option name="METHOD_NAME" value="" />
-      <option name="FOLDER_NAME" value="" />
-      <option name="TEST_TYPE" value="TEST_SCRIPT" />
-      <option name="PATTERN" value="" />
-      <option name="USE_PATTERN" value="false" />
-      <method />
-    </configuration>
-    <configuration default="true" type="tests" factoryName="Doctests">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs />
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="IS_MODULE_SDK" value="false" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="" />
-      <option name="CLASS_NAME" value="" />
-      <option name="METHOD_NAME" value="" />
-      <option name="FOLDER_NAME" value="" />
-      <option name="TEST_TYPE" value="TEST_SCRIPT" />
-      <option name="PATTERN" value="" />
-      <option name="USE_PATTERN" value="false" />
-      <method />
-    </configuration>
-    <configuration default="true" type="tests" factoryName="Nosetests">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs />
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="IS_MODULE_SDK" value="false" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="" />
-      <option name="CLASS_NAME" value="" />
-      <option name="METHOD_NAME" value="" />
-      <option name="FOLDER_NAME" value="" />
-      <option name="TEST_TYPE" value="TEST_SCRIPT" />
-      <option name="PATTERN" value="" />
-      <option name="USE_PATTERN" value="false" />
-      <option name="PARAMS" value="" />
-      <option name="USE_PARAM" value="false" />
-      <method />
-    </configuration>
-    <configuration default="true" type="tests" factoryName="Unittests">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs />
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="IS_MODULE_SDK" value="false" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="" />
-      <option name="CLASS_NAME" value="" />
-      <option name="METHOD_NAME" value="" />
-      <option name="FOLDER_NAME" value="" />
-      <option name="TEST_TYPE" value="TEST_SCRIPT" />
-      <option name="PATTERN" value="" />
-      <option name="USE_PATTERN" value="false" />
-      <option name="PUREUNITTEST" value="true" />
-      <option name="PARAMS" value="" />
-      <option name="USE_PARAM" value="false" />
-      <method />
-    </configuration>
-    <configuration default="true" type="tests" factoryName="py.test">
-      <option name="INTERPRETER_OPTIONS" value="" />
-      <option name="PARENT_ENVS" value="true" />
-      <envs />
-      <option name="SDK_HOME" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="IS_MODULE_SDK" value="false" />
-      <option name="ADD_CONTENT_ROOTS" value="true" />
-      <option name="ADD_SOURCE_ROOTS" value="true" />
-      <module name="lbry" />
-      <EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
-      <option name="SCRIPT_NAME" value="" />
-      <option name="CLASS_NAME" value="" />
-      <option name="METHOD_NAME" value="" />
-      <option name="FOLDER_NAME" value="" />
-      <option name="TEST_TYPE" value="TEST_SCRIPT" />
-      <option name="PATTERN" value="" />
-      <option name="USE_PATTERN" value="false" />
-      <option name="testToRun" value="" />
-      <option name="keywords" value="" />
-      <option name="params" value="" />
-      <option name="USE_PARAM" value="false" />
-      <option name="USE_KEYWORD" value="false" />
-      <method />
-    </configuration>
-    <list size="4">
-      <item index="0" class="java.lang.String" itemvalue="Python.AutoFetcher" />
-      <item index="1" class="java.lang.String" itemvalue="Python.LBRYConsole" />
-      <item index="2" class="java.lang.String" itemvalue="Python.StreamDescriptor" />
-      <item index="3" class="java.lang.String" itemvalue="Python.ControlHandlers" />
-    </list>
-    <recent_temporary>
-      <list size="4">
-        <item index="0" class="java.lang.String" itemvalue="Python.LBRYConsole" />
-        <item index="1" class="java.lang.String" itemvalue="Python.ControlHandlers" />
-        <item index="2" class="java.lang.String" itemvalue="Python.StreamDescriptor" />
-        <item index="3" class="java.lang.String" itemvalue="Python.AutoFetcher" />
-      </list>
-    </recent_temporary>
-  </component>
-  <component name="ShelveChangesManager" show_recycled="false" />
-  <component name="SvnConfiguration">
-    <configuration />
-  </component>
-  <component name="TaskManager">
-    <task active="true" id="Default" summary="Default task">
-      <changelist id="55ac8599-e726-4c97-bb6e-843a6d7c4acc" name="Default" comment="" />
-      <created>1446828623675</created>
-      <option name="number" value="Default" />
-      <updated>1446828623675</updated>
-    </task>
-    <servers />
-  </component>
-  <component name="ToolWindowManager">
-    <frame x="0" y="0" width="1440" height="900" extended-state="0" />
-    <editor active="true" />
-    <layout>
-      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
-      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.22771084" sideWeight="0.50572246" order="7" side_tool="true" content_ui="tabs" />
-      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
-      <window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32891566" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
-      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32891566" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
-      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25180724" sideWeight="0.49427754" order="2" side_tool="false" content_ui="tabs" />
-      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32891566" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
-      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.15450644" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
-      <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3297568" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
-      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.18313253" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
-      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.24964234" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
-      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
-      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
-      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
-      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
-      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
-      <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
-      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
-      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
-      <window_info id="Concurrent Activities Diagram" active="true" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32891566" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
-    </layout>
-  </component>
-  <component name="Vcs.Log.UiProperties">
-    <option name="RECENTLY_FILTERED_USER_GROUPS">
-      <collection />
-    </option>
-    <option name="RECENTLY_FILTERED_BRANCH_GROUPS">
-      <collection />
-    </option>
-  </component>
-  <component name="VcsContentAnnotationSettings">
-    <option name="myLimit" value="2678400000" />
-  </component>
-  <component name="XDebuggerManager">
-    <breakpoint-manager>
-      <option name="time" value="16" />
-    </breakpoint-manager>
-    <watches-manager />
-  </component>
-  <component name="editorHistoryManager">
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/DownloadManager.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/LiveStreamMetadataManager.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/LiveStreamCreator.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/LBRYStdoutDownloader.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.43293718">
-          <caret line="52" column="57" selection-start-line="52" selection-start-column="48" selection-end-line="52" selection-end-column="59" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/LiveBlob.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/PaymentRateManager.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbryfile/StreamDescriptor.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.13293944">
-          <caret line="6" column="71" selection-start-line="6" selection-start-column="71" selection-end-line="6" selection-end-column="71" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbrylive/LiveStreamCreator.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.44313148">
-          <caret line="20" column="8" selection-start-line="20" selection-start-column="8" selection-end-line="20" selection-end-column="8" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrylive/StreamDescriptor.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.2658789">
-          <caret line="60" column="31" selection-start-line="60" selection-start-column="31" selection-end-line="60" selection-end-column="31" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/node_rpc_cli.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.6875754">
-          <caret line="41" column="17" selection-start-line="41" selection-start-column="17" selection-end-line="41" selection-end-column="17" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/rpc_node.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.6381182">
-          <caret line="46" column="17" selection-start-line="46" selection-start-column="17" selection-end-line="46" selection-end-column="17" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/interfaces.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/conf.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.3799759">
-          <caret line="21" column="22" selection-start-line="21" selection-start-column="22" selection-end-line="21" selection-end-column="83" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYSettings.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/dht/node.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.3325031">
-          <caret line="202" column="73" selection-start-line="202" selection-start-column="72" selection-end-line="202" selection-end-column="73" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/pointtraderclient/pointtraderclient.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="-3.2159228">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/DHTPeerFinder.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.54282266">
-          <caret line="32" column="0" selection-start-line="32" selection-start-column="0" selection-end-line="32" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/ConnectionManager.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/ClientRequest.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/ClientProtocol.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/StreamProgressManager.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="-1.6960193">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbryfile/client/LBRYFileDownloader.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="95" column="0" selection-start-line="95" selection-start-column="0" selection-end-line="134" selection-end-column="12" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileStatusReport.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$APPLICATION_CONFIG_DIR$/scratches/scratch_1">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.75121164">
-          <caret line="31" column="17" selection-start-line="31" selection-start-column="17" selection-end-line="31" selection-end-column="17" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$USER_HOME$/jake.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/StreamCreator.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/utils.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbryfile/client/LBRYFileOptions.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.088626295">
-          <caret line="5" column="24" selection-start-line="5" selection-start-column="0" selection-end-line="6" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/LBRYFileMetadataManager.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.872969">
-          <caret line="181" column="50" selection-start-line="181" selection-start-column="50" selection-end-line="181" selection-end-column="50" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYPlugin.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-          <folding>
-            <marker date="1446821820000" expanded="true" signature="87:118" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="154:188" placeholder="..." />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/build/lib/lbrynet/lbrynet_gui/LBRYGui.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.3323486">
-          <caret line="403" column="52" selection-start-line="403" selection-start-column="52" selection-end-line="403" selection-end-column="52" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/cryptstream/CryptBlob.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="-0.10869565">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/cryptstream/CryptStreamCreator.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileCreator.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.33269963">
-          <caret line="71" column="14" selection-start-line="71" selection-start-column="9" selection-end-line="71" selection-end-column="14" />
-          <folding>
-            <marker date="1446821820000" expanded="true" signature="0:58" placeholder="&quot;&quot;&quot;...&quot;&quot;&quot;" />
-            <marker date="1446821820000" expanded="true" signature="60:506" placeholder="import ..." />
-            <marker date="1446821820000" expanded="true" signature="593:3261" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="598:702" placeholder="&quot;&quot;&quot;...&quot;&quot;&quot;" />
-            <marker date="1446821820000" expanded="true" signature="842:1192" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1234:1331" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1368:1770" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1792:1903" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1938:2643" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2677:2982" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="3008:3261" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="3418:5138" placeholder="&quot;&quot;&quot;Turn a plain file into an LBRY File....&quot;&quot;&quot;" />
-            <marker date="1446821820000" expanded="true" signature="5167:5289" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="5334:5649" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="5914:6251" placeholder="..." />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/Session.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileManager.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.94015443">
-          <caret line="129" column="52" selection-start-line="129" selection-start-column="32" selection-end-line="129" selection-end-column="52" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfilemanager/LBRYFileDownloader.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="-0.023166023">
-          <caret line="20" column="34" selection-start-line="20" selection-start-column="23" selection-end-line="20" selection-end-column="34" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/BlobManager.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="-0.05212355">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-          <folding>
-            <marker date="1446821820000" expanded="true" signature="0:535" placeholder="import ..." />
-            <marker date="1446821820000" expanded="true" signature="609:1709" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="792:847" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="869:882" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="942:955" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="988:1001" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1067:1080" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1142:1155" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1203:1216" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1251:1264" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1311:1324" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1363:1376" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1419:1432" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1466:1479" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1521:1534" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1577:1590" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1634:1647" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1696:1709" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1747:15813" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1856:2252" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2274:2501" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2522:2837" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2902:3294" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="3327:3386" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="3457:4165" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="3668:4108" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="3705:3742" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="4227:4453" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="4501:4554" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="4589:4721" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="4768:5517" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="5559:5719" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="5777:5840" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="5885:6013" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="6056:6104" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="6138:6179" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="6203:6468" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="6339:6411" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="6518:7956" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="6554:6625" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="6666:6838" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="6875:7259" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="7098:7201" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="7291:7440" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="8021:8812" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="8454:8810" placeholder="create table..if..." />
-            <marker date="1446821820000" expanded="true" signature="8924:9345" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="9136:9173" placeholder="insert into blobs..." />
-            <marker date="1446821820000" expanded="true" signature="9415:10987" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="9528:9952" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="9681:9737" placeholder="select last_..blobs..." />
-            <marker date="1446821820000" expanded="true" signature="9995:10873" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="10056:10294" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="10340:10601" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="11047:11354" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="11083:11132" placeholder="select blob_..blobs..." />
-            <marker date="1446821820000" expanded="true" signature="11440:11596" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="11479:11538" placeholder="update blobs..." />
-            <marker date="1446821820000" expanded="true" signature="11676:12268" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="11718:12208" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="11792:11915" placeholder="select blob_..blobs..." />
-            <marker date="1446821820000" expanded="true" signature="12048:12116" placeholder="update blobs..." />
-            <marker date="1446821820000" expanded="true" signature="12348:12442" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="12387:12426" placeholder="update blobs..." />
-            <marker date="1446821820000" expanded="true" signature="12514:12729" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="12554:12671" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="12626:12663" placeholder="delete from ..." />
-            <marker date="1446821820000" expanded="true" signature="12785:15162" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="12934:12994" placeholder="select blob_..blobs..." />
-            <marker date="1446821820000" expanded="true" signature="13060:13804" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="13834:14395" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="14451:14633" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="14517:14576" placeholder="update blobs..." />
-            <marker date="1446821820000" expanded="true" signature="14666:15109" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="14745:14986" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="15229:15813" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="15265:15312" placeholder="select blob_..blobs..." />
-            <marker date="1446821820000" expanded="true" signature="15354:15709" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="15935:16252" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="16274:16332" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="16353:16522" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="16587:16749" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="16782:16826" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="16897:17034" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="17096:17285" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="17333:17486" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="17521:17849" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="17896:18702" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="18744:18904" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="18947:19161" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="19206:19283" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="19307:19642" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="19443:19585" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="19728:19850" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="19891:20063" placeholder="..." />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/ConsoleControl.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.625">
-          <caret line="68" column="25" selection-start-line="68" selection-start-column="25" selection-end-line="68" selection-end-column="25" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/StreamDescriptor.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.33204633">
-          <caret line="168" column="90" selection-start-line="168" selection-start-column="82" selection-end-line="168" selection-end-column="90" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/client/LBRYFileDownloader.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="6.955836">
-          <caret line="294" column="73" selection-start-line="294" selection-start-column="73" selection-end-line="294" selection-end-column="73" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/client/LBRYFileOptions.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="-0.0015772871">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$USER_HOME$/Downloads/x.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.85804415">
-          <caret line="91" column="10" selection-start-line="91" selection-start-column="10" selection-end-line="91" selection-end-column="10" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/AutoFetcher.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="-0.37223974">
-          <caret line="8" column="1" selection-start-line="8" selection-start-column="1" selection-end-line="8" selection-end-column="1" />
-          <folding>
-            <marker date="1446947371000" expanded="true" signature="0:159" placeholder="import ..." />
-            <marker date="1446947371000" expanded="true" signature="176:194" placeholder="..." />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/LBRYConsole.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="-5.104101">
-          <caret line="221" column="16" selection-start-line="221" selection-start-column="16" selection-end-line="221" selection-end-column="16" />
-          <folding>
-            <marker date="1447551514000" expanded="true" signature="0:91" placeholder="import ..." />
-            <marker date="1447551514000" expanded="true" signature="17770:22272" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="3230:5051" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="3239:3524" placeholder="&quot;&quot;&quot;@param peer_port: the network port on which to listen for peers...&quot;&quot;&quot;" />
-            <marker date="1447551514000" expanded="true" signature="5073:6006" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="6047:6187" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="6231:6371" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="6397:6674" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="6729:6836" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="6887:7402" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="6931:7146" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="7440:7972" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="8008:9125" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="8527:9027" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="9155:9363" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="9397:10152" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="9517:9840" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="9943:10092" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="10187:10300" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="10329:10433" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="10462:12365" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="10499:10710" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="10737:11389" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="11492:11649" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="11687:12143" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="12406:12823" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="12577:12747" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="12863:13330" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="17770:18098" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="18136:19294" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="18708:19053" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="19324:19741" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="19424:19674" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="19771:19938" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="19968:20249" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="20014:20128" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="20278:21014" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="21042:21264" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="21298:21765" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="21799:21859" placeholder="..." />
-            <marker date="1447551514000" expanded="false" signature="21886:22272" placeholder="..." />
-            <marker date="1447551514000" expanded="true" signature="22301:27080" placeholder="..." />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/interfaces.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.0">
-          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbryfile/client/LBRYFileMetadataHandler.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.64935064">
-          <caret line="33" column="33" selection-start-line="33" selection-start-column="33" selection-end-line="33" selection-end-column="33" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/StreamDescriptor.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.8221344">
-          <caret line="242" column="32" selection-start-line="242" selection-start-column="32" selection-end-line="242" selection-end-column="32" />
-          <folding>
-            <marker date="1447551153000" expanded="true" signature="0:265" placeholder="import ..." />
-            <marker date="1447551153000" expanded="true" signature="341:876" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="503:516" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="546:713" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="738:876" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="937:1435" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="1068:1183" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="1213:1435" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="1238:1387" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="1495:1653" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="1581:1653" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="1701:2054" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="1726:2006" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="2094:2524" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="2236:2249" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="2292:2358" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="2409:2524" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="2585:3026" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="2623:2710" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="2761:3026" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="2788:2976" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="3086:3517" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="3124:3212" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="3263:3517" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="3549:3848" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="3642:3848" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="7207:8718" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="3897:4179" placeholder="&quot;&quot;&quot;...&quot;&quot;&quot;" />
-            <marker date="1447551153000" expanded="true" signature="4203:4460" placeholder="..." />
-            <marker date="1447551153000" expanded="false" signature="4540:5647" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="4549:5522" placeholder="&quot;&quot;&quot;This is how the StreamDescriptorIdentifier learns about new types of stream descriptors....&quot;&quot;&quot;" />
-            <marker date="1447551153000" expanded="true" signature="5715:6374" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="5724:6303" placeholder="&quot;&quot;&quot;Register a stream downloader factory with the StreamDescriptorIdentifier....&quot;&quot;&quot;" />
-            <marker date="1447551153000" expanded="true" signature="6457:6820" placeholder="..." />
-            <marker date="1447551153000" expanded="false" signature="6870:7130" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="7207:7429" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="7473:7654" placeholder="..." />
-            <marker date="1447551153000" expanded="false" signature="7698:7870" placeholder="..." />
-            <marker date="1447551153000" expanded="false" signature="7912:8080" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="8149:8718" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="8551:8653" placeholder="..." />
-            <marker date="1447551153000" expanded="true" signature="8789:8964" placeholder="&quot;&quot;&quot;Downloads a single blob from the network...&quot;&quot;&quot;" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/client/StandaloneBlobDownloader.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.33266532">
-          <caret line="107" column="0" selection-start-line="107" selection-start-column="0" selection-end-line="107" selection-end-column="0" />
-          <folding>
-            <marker date="1446821820000" expanded="true" signature="0:497" placeholder="import ..." />
-            <marker date="1446821820000" expanded="true" signature="576:992" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="674:758" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="833:944" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="975:992" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1031:2758" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1092:1266" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1288:1507" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1528:1714" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="1749:2102" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2134:2262" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2291:2437" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2485:2758" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2792:2887" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2816:2829" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="2874:2887" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="3036:3353" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="3378:4876" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="3538:3562" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="4897:4953" placeholder="..." />
-            <marker date="1446821820000" expanded="true" signature="4992:5108" placeholder="..." />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/core/LBRYcrdWallet.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="0.04809619">
-          <caret line="267" column="32" selection-start-line="267" selection-start-column="8" selection-end-line="267" selection-end-column="32" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/lbrynet/lbrynet_console/ControlHandlers.py">
-      <provider selected="true" editor-type-id="text-editor">
-        <state vertical-scroll-proportion="-26.322075">
-          <caret line="789" column="0" selection-start-line="789" selection-start-column="0" selection-end-line="789" selection-end-column="0" />
-          <folding>
-            <element signature="e#0#11#0" expanded="true" />
-            <element signature="e#1157#1161#0" expanded="false" />
-            <element signature="e#1204#1208#0" expanded="false" />
-            <element signature="e#1731#2208#0" expanded="false" />
-            <element signature="e#2245#2500#0" expanded="false" />
-            <element signature="e#2552#3180#0" expanded="false" />
-            <element signature="e#3235#5573#0" expanded="false" />
-            <element signature="e#5622#7291#0" expanded="false" />
-            <element signature="e#7339#8236#0" expanded="false" />
-            <element signature="e#8298#8638#0" expanded="false" />
-            <element signature="e#8686#9497#0" expanded="false" />
-            <element signature="e#9559#9778#0" expanded="false" />
-            <element signature="e#9828#10422#0" expanded="false" />
-            <element signature="e#10486#10705#0" expanded="false" />
-            <element signature="e#10744#11431#0" expanded="false" />
-            <element signature="e#11484#11611#0" expanded="false" />
-            <element signature="e#11656#12731#0" expanded="false" />
-            <element signature="e#25614#25892#0" expanded="false" />
-            <element signature="e#25952#26309#0" expanded="false" />
-            <element signature="e#31776#32529#0" expanded="false" />
-            <element signature="e#32585#33388#0" expanded="false" />
-            <element signature="e#33448#33549#0" expanded="false" />
-            <element signature="e#33602#33966#0" expanded="false" />
-            <element signature="e#34032#34633#0" expanded="false" />
-            <element signature="e#34678#37825#0" expanded="false" />
-            <element signature="e#37885#37923#0" expanded="false" />
-            <element signature="e#37983#38273#0" expanded="false" />
-            <element signature="e#38346#38627#0" expanded="false" />
-            <element signature="e#38679#39520#0" expanded="false" />
-            <element signature="e#39587#39632#0" expanded="false" />
-            <element signature="e#39677#40945#0" expanded="false" />
-            <element signature="e#41004#41716#0" expanded="false" />
-            <element signature="e#41778#42195#0" expanded="false" />
-            <element signature="e#42270#42719#0" expanded="false" />
-            <element signature="e#42773#43912#0" expanded="false" />
-            <element signature="e#43981#44028#0" expanded="false" />
-            <element signature="e#44088#44406#0" expanded="false" />
-            <element signature="e#106689#108058#0" expanded="false" />
-            <element signature="e#108119#108371#0" expanded="false" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-  </component>
-</project>
\ No newline at end of file

From a05f2fe3fbb0accbde7f26f27f6c99be41475abf Mon Sep 17 00:00:00 2001
From: jackrobison <jack@robisonservice.com>
Date: Mon, 16 Nov 2015 12:55:01 -0500
Subject: [PATCH 07/21] Check blocks for new claims more frequently

---
 lbrynet/lbrynet_console/ControlHandlers.py | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py
index 7d2cb64db..7146084d5 100644
--- a/lbrynet/lbrynet_console/ControlHandlers.py
+++ b/lbrynet/lbrynet_console/ControlHandlers.py
@@ -2504,6 +2504,8 @@ class AutoFetcher(CommandHandler):
         self.seen = []
         self.lastbestblock = None
         self.rpc_conn = self.wallet.get_rpc_conn_x()
+        self.search = None
+        self.first_run = True
 
     def start(self):
         #TODO add a stop function
@@ -2511,8 +2513,12 @@ class AutoFetcher(CommandHandler):
         #TODO first search through the nametrie before monitoring live updates
         #TODO load previously downloaded streams
 
-        search = LoopingCall(self._looped_search)
-        search.start(10)
+        self.search = LoopingCall(self._looped_search)
+        self.search.start(1)
+        self.finished_deferred.callback(None)
+
+    def stop(self):
+        self.search.stop()
         self.finished_deferred.callback(None)
 
     def _get_names(self):
@@ -2524,7 +2530,11 @@ class AutoFetcher(CommandHandler):
             transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
             for t in transactions:
                 claims = self.rpc_conn.getclaimsfortx(t['txid'])
-                #claims = self.rpc_conn.getclaimsfortx("c3684bd587856ba5cc38c4afdbcd2c6efc60cb2d1ed21188485ea58048b419a8")
+                # uncomment to make it download wonderfullife on startup
+                # if self.first_run:
+                #     claims = self.rpc_conn.getclaimsfortx("c3684bd587856ba5cc38c4afdbcd2c6efc60cb2d1ed21188485ea58048b419a8")
+                #     self.first_run = False
+
                 if claims:
                     for claim in claims:
                         if claim not in self.seen:
@@ -2533,8 +2543,8 @@ class AutoFetcher(CommandHandler):
                             rtn.append(claim['name'])
                             self.seen.append(claim)
                 else:
-                    #self.console.sendLine("No new claims in block #" + str(block['height']))
-                    pass
+                    self.console.sendLine("No new claims in block #" + str(block['height']))
+                    #pass
 
         self.lastbestblock = c
 

From 45eb4f7201654f87ee5c7f8a2ba0c065189f636c Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Thu, 19 Nov 2015 14:43:36 -0500
Subject: [PATCH 08/21] Improved autofetcher

Added commands:

start-autofetcher
stop-autofetcher
autofetcher-status
---
 lbrynet/core/client/AutoDownloader.py      | 196 ++++++++++++++++++
 lbrynet/lbrynet_console/ControlHandlers.py | 220 +++------------------
 lbrynet/lbrynet_console/LBRYConsole.py     |  16 +-
 3 files changed, 237 insertions(+), 195 deletions(-)
 create mode 100644 lbrynet/core/client/AutoDownloader.py

diff --git a/lbrynet/core/client/AutoDownloader.py b/lbrynet/core/client/AutoDownloader.py
new file mode 100644
index 000000000..30216719d
--- /dev/null
+++ b/lbrynet/core/client/AutoDownloader.py
@@ -0,0 +1,196 @@
+import json
+import logging
+from twisted.internet import defer
+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
+
+log = logging.getLogger(__name__)
+
+
+class AutoAddStreamFromLBRYcrdName(object):
+    def __init__(self, console, sd_identifier, session, wallet, lbry_file_manager):
+        self.finished_deferred = defer.Deferred(None)
+        self.console = console
+        self.wallet = wallet
+        self.resolved_name = None
+        self.description = None
+        self.key_fee = None
+        self.key_fee_address = None
+        self.name = None
+        self.session = session
+        self.payment_rate_manager = PaymentRateManager(self.session.base_payment_rate_manager)
+        self.loading_metadata_deferred = defer.Deferred()
+        self.lbry_file_manager = lbry_file_manager
+        self.sd_identifier = sd_identifier
+        self.metadata = None
+        self.loading_failed = False
+        self.resolved_name = None
+        self.description = None
+        self.key_fee = None
+        self.key_fee_address = None
+        self.stream_hash = None
+
+    def start(self, stream_info):
+        self.stream_info = stream_info
+        if 'stream_hash' not in json.loads(self.stream_info['value']):
+            print 'InvalidStreamInfoError'
+            raise InvalidStreamInfoError(self.stream_info)
+        self.resolved_name = self.stream_info.get('name', None)
+        self.description = json.loads(self.stream_info['value']).get('description', None)
+        try:
+            if 'key_fee' in json.loads(self.stream_info['value']):
+                self.key_fee = float(json.loads(self.stream_info['value'])['key_fee'])
+        except ValueError:
+            self.key_fee = None
+        self.key_fee_address = json.loads(self.stream_info['value']).get('key_fee_address', None)
+        self.stream_hash = json.loads(self.stream_info['value'])['stream_hash']
+
+
+        self.loading_metadata_deferred = defer.Deferred(None)
+        self.loading_metadata_deferred.addCallback(lambda _: download_sd_blob(self.session,
+                                                            self.stream_hash, self.payment_rate_manager))
+        self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
+        self.loading_metadata_deferred.addCallback(self._handle_metadata)
+        self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
+        self.loading_metadata_deferred.addErrback(self._handle_load_failed)
+
+        self.finished_deferred.addCallback(lambda _: self.loading_metadata_deferred.callback(None))
+
+        return self.finished_deferred.callback(None)
+
+    def _start_download(self):
+        d = self._pay_key_fee()
+        d.addCallback(lambda _: self._make_downloader())
+        d.addCallback(lambda stream_downloader: stream_downloader.start())
+        d.addErrback(self._handle_download_error)
+        return d
+
+    def _pay_key_fee(self):
+        if self.key_fee is not None and self.key_fee_address is not None:
+            reserved_points = self.wallet.reserve_points(self.key_fee_address, self.key_fee)
+            if reserved_points is None:
+                return defer.fail(InsufficientFundsError())
+            return self.wallet.send_points_to_address(reserved_points, self.key_fee)
+        self.console.sendLine("Sent key fee" + str(self.key_fee_address) + " | " + str(self.key_fee))
+        return defer.succeed(None)
+
+    def _handle_load_canceled(self, err):
+        err.trap(defer.CancelledError)
+        self.finished_deferred.callback(None)
+
+    def _handle_load_failed(self, err):
+        self.loading_failed = True
+        self.console.sendLine("handle load failed: " + str(err.getTraceback()))
+        log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback())
+        self.finished_deferred.callback(None)
+
+    def _handle_metadata(self, metadata):
+        self.metadata = metadata
+        self.factory = self.metadata.factories[0]
+        self.finished_deferred.addCallback(lambda _: self._start_download())
+
+    def _handle_download_error(self, err):
+        if err.check(InsufficientFundsError):
+            self.console.sendLine("Download stopped due to insufficient funds.")
+        else:
+            self.console.sendLine("Autoaddstream: An unexpected error has caused the download to stop: %s" % err.getTraceback())
+
+    def _make_downloader(self):
+        self.downloader = self.factory.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
+        return self.downloader
+
+class AutoFetcher(object):
+    def __init__(self, session, lbry_file_manager, lbry_file_metadata_manager, wallet, sd_identifier):
+        self.console = None
+        self.sd_identifier = sd_identifier
+        self.wallet = wallet
+        self.session = session
+        self.lbry_file_manager = lbry_file_manager
+        self.lbry_metadata_manager = lbry_file_metadata_manager
+        self.seen = []
+        self.lastbestblock = None
+        self.rpc_conn = self.wallet.get_rpc_conn_x()
+        self.search = None
+        self.first_run = True
+        self.is_running = False
+
+    def start(self, console):
+        #TODO first search through the nametrie before monitoring live updates
+        #TODO load previously downloaded streams
+
+        self.console = console
+
+        if not self.is_running:
+            self.is_running = True
+            self.search = LoopingCall(self._looped_search)
+            self.search.start(1)
+        else:
+            self.console.sendLine("Autofetcher is already running")
+
+    def stop(self, console):
+        self.console = console
+
+        if self.is_running:
+            self.search.stop()
+            self.is_running = False
+        else:
+            self.console.sendLine("Autofetcher isn't running, there's nothing to stop")
+
+    def check_if_running(self, console):
+        self.console = console
+
+        if self.is_running:
+            self.console.sendLine("Autofetcher is running")
+            self.console.sendLine("Last block hash: " + str(self.lastbestblock['bestblockhash']))
+        else:
+            self.console.sendLine("Autofetcher is not running")
+
+    def _get_names(self):
+        c = self.rpc_conn.getblockchaininfo()
+        rtn = []
+        if self.lastbestblock != c:
+            block = self.rpc_conn.getblock(c['bestblockhash'])
+            txids = block['tx']
+            transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
+            for t in transactions:
+                claims = self.rpc_conn.getclaimsfortx(t['txid'])
+
+                # uncomment to make it download lbry://y on startup
+                # if self.first_run:
+                #     claims = self.rpc_conn.getclaimsfortx("38da801a2c3620a79252e5b0b619d1d3f4d53aa9edd9cdc76d9ba65660fb9f06")
+                #     self.first_run = False
+
+                if claims:
+                    for claim in claims:
+                        if claim not in self.seen:
+                            self.console.sendLine("lbry://" + str(claim['name']) + " | stream hash: " +
+                                                        str(json.loads(claim['value'])['stream_hash']))
+                            rtn.append(claim)
+                            self.seen.append(claim)
+                else:
+                    #self.console.sendLine("No new claims in block #" + str(block['height']))
+                    pass
+
+        self.lastbestblock = c
+
+        if len(rtn):
+            return defer.succeed(rtn)
+
+    def _download_claims(self, claims):
+        if claims:
+            for claim in claims:
+                download = defer.Deferred()
+                stream = AutoAddStreamFromLBRYcrdName(self.console, self.sd_identifier, self.session,
+                                                      self.wallet, self.lbry_file_manager)
+                download.addCallback(lambda _: stream.start(claim))
+                download.callback(None)
+
+        return defer.succeed(None)
+
+    def _looped_search(self):
+        d = defer.Deferred(None)
+        d.addCallback(lambda _: self._get_names())
+        d.addCallback(self._download_claims)
+        d.callback(None)
\ No newline at end of file
diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py
index 7146084d5..4913414dd 100644
--- a/lbrynet/lbrynet_console/ControlHandlers.py
+++ b/lbrynet/lbrynet_console/ControlHandlers.py
@@ -2362,216 +2362,52 @@ class StatusFactory(CommandHandlerFactory):
                 "to remove the file."
 
 
-class AutoAddStream(CommandHandler):
-    def __init__(self, console):
+class AutoFetcherStart(CommandHandler):
+    def __init__(self, console, autofetcher):
         CommandHandler.__init__(self, console)
-        self.session = None
-        self.loading_metadata_deferred = None
-        self.lbry_file_manager = None
-        self.sd_identifier = None
-        self.metadata = None
-        self.downloader = None
-        self.loading_failed = False
-        self.factory = None
-        self.description = None
-        self.key_fee = None
-        self.key_fee_address = None
-        self.payment_rate_manager = None
+        self.autofetcher = autofetcher
 
     def start(self):
-        pass
-
-    def _load_metadata(self, sd_file):
-        return defer.fail(NotImplementedError())
-
-    def _start_download(self):
-        d = self._make_downloader()
-        d.addCallback(lambda stream_downloader: stream_downloader.start())
-        d.addErrback(self._handle_download_error)
-        return d
-
-    def _handle_download_error(self, err):
-        if err.check(InsufficientFundsError):
-            self.console.sendLine("Download stopped due to insufficient funds.")
-        else:
-            self.console.sendLine("Autoaddstream: An unexpected error has caused the download to stop: %s" % err.getTraceback())
-
-    def _make_downloader(self):
-        self.downloader = self.factory.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
-        return self.downloader
-
-
-class AutoAddStreamFromLBRYcrdName(AutoAddStream):
-    def __init__(self, console, sd_identifier, session, wallet, lbry_file_manager):
-        AutoAddStream.__init__(self, console)
-        self.wallet = wallet
-        self.resolved_name = None
-        self.description = None
-        self.key_fee = None
-        self.key_fee_address = None
-        self.name = None
-        self.session = session
-        self.payment_rate_manager = PaymentRateManager(self.session.base_payment_rate_manager)
-        self.loading_metadata_deferred = defer.Deferred()
-        self.lbry_file_manager = lbry_file_manager
-        self.sd_identifier = sd_identifier
-        self.metadata = None
-        self.loading_failed = False
-        self.resolved_name = None
-        self.description = None
-        self.key_fee = None
-        self.key_fee_address = None
-        self.stream_hash = None
-
-    def start(self, name):
-        self.name = name
-
-        self.loading_metadata_deferred = defer.Deferred(None)
-        self.loading_metadata_deferred.addCallback(lambda _: self._resolve_name(str(name)))
-        self.loading_metadata_deferred.addCallback(lambda stream_hash: download_sd_blob(self.session,
-                                                                            stream_hash, self.payment_rate_manager))
-        self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
-        self.loading_metadata_deferred.addCallback(self._handle_metadata)
-        #self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
-        #self.loading_metadata_deferred.addErrback(self._handle_load_failed)
-
-        self.finished_deferred.addCallback(lambda _: self.loading_metadata_deferred.callback(None))
-
-        return self.finished_deferred.callback(None)
-
-    def _resolve_name(self, name):
-        def get_name_from_info(stream_info):
-            if 'stream_hash' not in stream_info:
-                print 'InvalidStreamInfoError'
-                raise InvalidStreamInfoError(name)
-            self.resolved_name = stream_info.get('name', None)
-            self.description = stream_info.get('description', None)
-            try:
-                if 'key_fee' in stream_info:
-                    self.key_fee = float(stream_info['key_fee'])
-            except ValueError:
-                self.key_fee = None
-            self.key_fee_address = stream_info.get('key_fee_address', None)
-            self.stream_hash = stream_info['stream_hash']
-            return stream_info['stream_hash']
-        d = self.wallet.get_stream_info_for_name(name)
-        d.addCallback(get_name_from_info)
-        return d
-
-    def _start_download(self):
-        d = self._pay_key_fee()
-        d.addCallback(lambda _: AutoAddStream._start_download(self))
-        return d
-
-    def _pay_key_fee(self):
-        if self.key_fee is not None and self.key_fee_address is not None:
-            reserved_points = self.wallet.reserve_points(self.key_fee_address, self.key_fee)
-            if reserved_points is None:
-                return defer.fail(InsufficientFundsError())
-            return self.wallet.send_points_to_address(reserved_points, self.key_fee)
-        #self.console.sendLine("Sent key fee" + str(self.key_fee_address) + " | " + str(self.key_fee))
-        return defer.succeed(None)
-
-    def _handle_load_canceled(self, err):
-        err.trap(defer.CancelledError)
+        self.autofetcher.start(self.console)
         self.finished_deferred.callback(None)
 
-    def _handle_load_failed(self, err):
-        self.loading_failed = True
-        self.console.sendLine("handle load failed: " + str(err.getTraceback()))
-        log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback())
-        self.finished_deferred.callback(None)
 
-    def _handle_metadata(self, metadata):
-        self.metadata = metadata
-        self.factory = self.metadata.factories[0]
-        #self.console.sendLine("Factory: " + str(self.factory))
-
-        self.finished_deferred.addCallback(lambda _: AutoAddStream.start(self))
-        self.finished_deferred.addCallback(lambda _: self._start_download())
-
-
-class AutoFetcher(CommandHandler):
-    def __init__(self, console, session, lbry_file_manager, lbry_file_metadata_manager, wallet, sd_identifier):
+class AutoFetcherStop(CommandHandler):
+    def __init__(self, console, autofetcher):
         CommandHandler.__init__(self, console)
-        self.d = None
-        self.console = console
-        self.sd_identifier = sd_identifier
-        self.wallet = wallet
-        self.session = session
-        self.lbry_file_manager = lbry_file_manager
-        self.lbry_metadata_manager = lbry_file_metadata_manager
-        self.seen = []
-        self.lastbestblock = None
-        self.rpc_conn = self.wallet.get_rpc_conn_x()
-        self.search = None
-        self.first_run = True
+        self.autofetcher = autofetcher
 
     def start(self):
-        #TODO add a stop function
-        #TODO detect if it's already running
-        #TODO first search through the nametrie before monitoring live updates
-        #TODO load previously downloaded streams
-
-        self.search = LoopingCall(self._looped_search)
-        self.search.start(1)
+        self.autofetcher.stop(self.console)
         self.finished_deferred.callback(None)
 
-    def stop(self):
-        self.search.stop()
+
+class AutoFetcherStatus(CommandHandler):
+    def __init__(self, console, autofetcher):
+        CommandHandler.__init__(self, console)
+        self.autofetcher = autofetcher
+
+    def start(self):
+        self.autofetcher.check_if_running(self.console)
         self.finished_deferred.callback(None)
 
-    def _get_names(self):
-        c = self.rpc_conn.getblockchaininfo()
-        rtn = []
-        if self.lastbestblock != c:
-            block = self.rpc_conn.getblock(c['bestblockhash'])
-            txids = block['tx']
-            transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
-            for t in transactions:
-                claims = self.rpc_conn.getclaimsfortx(t['txid'])
-                # uncomment to make it download wonderfullife on startup
-                # if self.first_run:
-                #     claims = self.rpc_conn.getclaimsfortx("c3684bd587856ba5cc38c4afdbcd2c6efc60cb2d1ed21188485ea58048b419a8")
-                #     self.first_run = False
 
-                if claims:
-                    for claim in claims:
-                        if claim not in self.seen:
-                            self.console.sendLine("lbry://" + str(claim['name']) + " | stream hash: " +
-                                                        str(json.loads(claim['value'])['stream_hash']))
-                            rtn.append(claim['name'])
-                            self.seen.append(claim)
-                else:
-                    self.console.sendLine("No new claims in block #" + str(block['height']))
-                    #pass
+class AutoFetcherStartFactory(CommandHandlerFactory):
+    control_handler_class = AutoFetcherStart
+    command = "start-autofetcher"
+    short_help = "Start downloading all lbry files as they are published"
 
-        self.lastbestblock = c
 
-        if len(rtn):
-            return defer.succeed(rtn)
+class AutoFetcherStopFactory(CommandHandlerFactory):
+    control_handler_class = AutoFetcherStop
+    command = "stop-autofetcher"
+    short_help = "Stop downloading all lbry files as they are published"
 
-    def _download_claims(self, claims):
-        if claims:
-            for claim in claims:
-                download = defer.Deferred()
-                stream = AutoAddStreamFromLBRYcrdName(self.console, self.sd_identifier, self.session,
-                                                      self.wallet, self.lbry_file_manager)
-                download.addCallback(lambda _: stream.start(str(claim)))
-                download.callback(None)
 
-        return defer.succeed(None)
-
-    def _looped_search(self):
-        d = defer.Deferred(None)
-        d.addCallback(lambda _: self._get_names())
-        d.addCallback(self._download_claims)
-        d.callback(None)
-
-class AutoFetcherFactory(CommandHandlerFactory):
-    control_handler_class = AutoFetcher
-    command = "start-autofetching"
-    short_help = "Download all lbry files as they are published"
+class AutoFetcherStatusFactory(CommandHandlerFactory):
+    control_handler_class = AutoFetcherStatus
+    command = "autofetcher-status"
+    short_help = "Check autofetcher status"
 
 
 class BlockchainStatus(CommandHandler):
diff --git a/lbrynet/lbrynet_console/LBRYConsole.py b/lbrynet/lbrynet_console/LBRYConsole.py
index 4f0b35074..aa17d3ba9 100644
--- a/lbrynet/lbrynet_console/LBRYConsole.py
+++ b/lbrynet/lbrynet_console/LBRYConsole.py
@@ -4,6 +4,8 @@ import os.path
 import argparse
 from yapsy.PluginManager import PluginManager
 from twisted.internet import defer, threads, stdio, task, error
+
+from lbrynet.core.client.AutoDownloader import AutoFetcher
 from lbrynet.lbrynet_console.ConsoleControl import ConsoleControl
 from lbrynet.lbrynet_console.LBRYSettings import LBRYSettings
 from lbrynet.lbryfilemanager.LBRYFileManager import LBRYFileManager
@@ -21,7 +23,8 @@ from lbrynet.lbryfile.StreamDescriptor import LBRYFileStreamType
 from lbrynet.lbryfile.LBRYFileMetadataManager import DBLBRYFileMetadataManager, TempLBRYFileMetadataManager
 #from lbrynet.lbrylive.PaymentRateManager import LiveStreamPaymentRateManager
 from lbrynet.lbrynet_console.ControlHandlers import ApplicationStatusFactory, GetWalletBalancesFactory, ShutDownFactory
-from lbrynet.lbrynet_console.ControlHandlers import AutoFetcherFactory, ImmediateAnnounceAllBlobsFactory
+from lbrynet.lbrynet_console.ControlHandlers import AutoFetcherStartFactory, AutoFetcherStopFactory
+from lbrynet.lbrynet_console.ControlHandlers import ImmediateAnnounceAllBlobsFactory, AutoFetcherStatusFactory
 from lbrynet.lbrynet_console.ControlHandlers import LBRYFileStatusFactory, DeleteLBRYFileChooserFactory
 from lbrynet.lbrynet_console.ControlHandlers import ToggleLBRYFileRunningChooserFactory
 from lbrynet.lbrynet_console.ControlHandlers import ModifyApplicationDefaultsFactory
@@ -89,6 +92,7 @@ class LBRYConsole():
         self.sd_identifier = StreamDescriptorIdentifier()
         self.plugin_objects = []
         self.db_migration_revisions = None
+        self.autofetcher = None
 
     def start(self):
         """Initialize the session and restore everything to its saved state"""
@@ -100,6 +104,7 @@ class LBRYConsole():
         d.addCallback(lambda _: add_lbry_file_to_sd_identifier(self.sd_identifier))
         d.addCallback(lambda _: self._setup_lbry_file_manager())
         d.addCallback(lambda _: self._setup_lbry_file_opener())
+        d.addCallback(lambda _: self._get_autofetcher()),
         d.addCallback(lambda _: self._setup_control_handlers())
         d.addCallback(lambda _: self._setup_query_handlers())
         d.addCallback(lambda _: self._load_plugins())
@@ -108,6 +113,10 @@ class LBRYConsole():
         d.addErrback(self._show_start_error)
         return d
 
+    def _get_autofetcher(self):
+        self.autofetcher = AutoFetcher(self.session, self.lbry_file_manager, self.lbry_file_metadata_manager,
+                                       self.session.wallet, self.sd_identifier)
+
     def _show_start_error(self, error):
         print error.getErrorMessage()
         log.error("An error occurred during start up: %s", error.getTraceback())
@@ -313,8 +322,9 @@ class LBRYConsole():
             AddStreamFromHashFactory(self.sd_identifier, self.session),
             StatusFactory(self, self.session.rate_limiter, self.lbry_file_manager,
                           self.session.blob_manager, self.session.wallet if self.wallet_type == 'lbrycrd' else None),
-            AutoFetcherFactory(self.session, self.lbry_file_manager, self.lbry_file_metadata_manager,
-                               self.session.wallet, self.sd_identifier),
+            AutoFetcherStartFactory(self.autofetcher),
+            AutoFetcherStopFactory(self.autofetcher),
+            AutoFetcherStatusFactory(self.autofetcher),
             ImmediateAnnounceAllBlobsFactory(self.session.blob_manager)
         ]
         self.add_control_handlers(handlers)

From 35d5c585ecc64f820dd9aca1512bd567ec67725a Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Thu, 19 Nov 2015 16:20:12 -0500
Subject: [PATCH 09/21] Added a max key price set in autofetcher.conf

---
 lbrynet/core/client/AutoDownloader.py  | 57 +++++++++++++++++++-------
 lbrynet/lbrynet_console/LBRYConsole.py |  5 ++-
 2 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/lbrynet/core/client/AutoDownloader.py b/lbrynet/core/client/AutoDownloader.py
index 30216719d..724ad7d55 100644
--- a/lbrynet/core/client/AutoDownloader.py
+++ b/lbrynet/core/client/AutoDownloader.py
@@ -1,5 +1,7 @@
 import json
 import logging
+import os
+
 from twisted.internet import defer
 from twisted.internet.task import LoopingCall
 from lbrynet.core.Error import InvalidStreamInfoError, InsufficientFundsError
@@ -10,7 +12,7 @@ log = logging.getLogger(__name__)
 
 
 class AutoAddStreamFromLBRYcrdName(object):
-    def __init__(self, console, sd_identifier, session, wallet, lbry_file_manager):
+    def __init__(self, console, sd_identifier, session, wallet, lbry_file_manager, max_key_fee):
         self.finished_deferred = defer.Deferred(None)
         self.console = console
         self.wallet = wallet
@@ -31,6 +33,8 @@ class AutoAddStreamFromLBRYcrdName(object):
         self.key_fee = None
         self.key_fee_address = None
         self.stream_hash = None
+        self.max_key_fee = max_key_fee
+        self.stream_info = None
 
     def start(self, stream_info):
         self.stream_info = stream_info
@@ -47,10 +51,14 @@ class AutoAddStreamFromLBRYcrdName(object):
         self.key_fee_address = json.loads(self.stream_info['value']).get('key_fee_address', None)
         self.stream_hash = json.loads(self.stream_info['value'])['stream_hash']
 
+        if self.key_fee > self.max_key_fee:
+            self.console.sendLine("Key fee (" + str(self.key_fee) + ") above limit of " + str(
+                self.max_key_fee) + ", didn't download lbry://" + str(self.resolved_name))
+            return self.finished_deferred.callback(None)
 
         self.loading_metadata_deferred = defer.Deferred(None)
-        self.loading_metadata_deferred.addCallback(lambda _: download_sd_blob(self.session,
-                                                            self.stream_hash, self.payment_rate_manager))
+        self.loading_metadata_deferred.addCallback(
+            lambda _: download_sd_blob(self.session, self.stream_hash, self.payment_rate_manager))
         self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
         self.loading_metadata_deferred.addCallback(self._handle_metadata)
         self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
@@ -95,14 +103,18 @@ class AutoAddStreamFromLBRYcrdName(object):
         if err.check(InsufficientFundsError):
             self.console.sendLine("Download stopped due to insufficient funds.")
         else:
-            self.console.sendLine("Autoaddstream: An unexpected error has caused the download to stop: %s" % err.getTraceback())
+            self.console.sendLine(
+                "Autoaddstream: An unexpected error has caused the download to stop: %s" % err.getTraceback())
 
     def _make_downloader(self):
         self.downloader = self.factory.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
         return self.downloader
 
+
 class AutoFetcher(object):
-    def __init__(self, session, lbry_file_manager, lbry_file_metadata_manager, wallet, sd_identifier):
+    def __init__(self, session, lbry_file_manager, lbry_file_metadata_manager, wallet, sd_identifier, autofetcher_conf):
+        self.autofetcher_conf = autofetcher_conf
+        self.max_key_fee = 0.0
         self.console = None
         self.sd_identifier = sd_identifier
         self.wallet = wallet
@@ -115,10 +127,11 @@ class AutoFetcher(object):
         self.search = None
         self.first_run = True
         self.is_running = False
+        self._get_autofetcher_conf()
 
     def start(self, console):
-        #TODO first search through the nametrie before monitoring live updates
-        #TODO load previously downloaded streams
+        # TODO first search through the nametrie before monitoring live updates
+        # TODO load previously downloaded streams
 
         self.console = console
 
@@ -156,21 +169,19 @@ class AutoFetcher(object):
             transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
             for t in transactions:
                 claims = self.rpc_conn.getclaimsfortx(t['txid'])
-
-                # uncomment to make it download lbry://y on startup
+                # uncomment to make it download lbry://yyyy on startup
                 # if self.first_run:
-                #     claims = self.rpc_conn.getclaimsfortx("38da801a2c3620a79252e5b0b619d1d3f4d53aa9edd9cdc76d9ba65660fb9f06")
+                #     claims = self.rpc_conn.getclaimsfortx("43a784085949f7bebe5c2a2b74f4e2c6abec36219a5d04d285206b4056ea218b")
                 #     self.first_run = False
-
                 if claims:
                     for claim in claims:
                         if claim not in self.seen:
                             self.console.sendLine("lbry://" + str(claim['name']) + " | stream hash: " +
-                                                        str(json.loads(claim['value'])['stream_hash']))
+                                                  str(json.loads(claim['value'])['stream_hash']))
                             rtn.append(claim)
                             self.seen.append(claim)
                 else:
-                    #self.console.sendLine("No new claims in block #" + str(block['height']))
+                    # self.console.sendLine("No new claims in block #" + str(block['height']))
                     pass
 
         self.lastbestblock = c
@@ -183,7 +194,7 @@ class AutoFetcher(object):
             for claim in claims:
                 download = defer.Deferred()
                 stream = AutoAddStreamFromLBRYcrdName(self.console, self.sd_identifier, self.session,
-                                                      self.wallet, self.lbry_file_manager)
+                                                      self.wallet, self.lbry_file_manager, self.max_key_fee)
                 download.addCallback(lambda _: stream.start(claim))
                 download.callback(None)
 
@@ -193,4 +204,20 @@ class AutoFetcher(object):
         d = defer.Deferred(None)
         d.addCallback(lambda _: self._get_names())
         d.addCallback(self._download_claims)
-        d.callback(None)
\ No newline at end of file
+        d.callback(None)
+
+    def _get_autofetcher_conf(self):
+        settings = {"maxkey": "0.0"}
+        if os.path.exists(self.autofetcher_conf):
+            conf = open(self.autofetcher_conf)
+            for l in conf:
+                if l.startswith("maxkey="):
+                    settings["maxkey"] = float(l[7:].rstrip('\n'))
+        else:
+            self.console.sendLine("Autofetcher using default max key price of 0.0")
+            self.console.sendLine("To change this create the file:")
+            self.console.sendLine(str(self.autofetcher_conf))
+            self.console.sendLine("Example contents of conf file:")
+            self.console.sendLine("maxkey=1.0")
+
+        self.max_key_fee = settings["maxkey"]
diff --git a/lbrynet/lbrynet_console/LBRYConsole.py b/lbrynet/lbrynet_console/LBRYConsole.py
index aa17d3ba9..069948165 100644
--- a/lbrynet/lbrynet_console/LBRYConsole.py
+++ b/lbrynet/lbrynet_console/LBRYConsole.py
@@ -66,6 +66,7 @@ class LBRYConsole():
             self.lbrycrd_dir = os.path.join(os.path.expanduser("~"), ".lbrycrd")
         if not self.lbrycrd_conf:
             self.lbrycrd_conf = os.path.join(self.lbrycrd_dir, "lbrycrd.conf")
+        self.autofetcher_conf = os.path.join(self.lbrycrd_dir, "autofetcher.conf")
         self.lbrycrdd_path = lbrycrdd_path
         self.default_lbrycrdd_path = "./lbrycrdd"
         self.start_lbrycrdd = start_lbrycrdd
@@ -104,7 +105,7 @@ class LBRYConsole():
         d.addCallback(lambda _: add_lbry_file_to_sd_identifier(self.sd_identifier))
         d.addCallback(lambda _: self._setup_lbry_file_manager())
         d.addCallback(lambda _: self._setup_lbry_file_opener())
-        d.addCallback(lambda _: self._get_autofetcher()),
+        d.addCallback(lambda _: self._get_autofetcher())
         d.addCallback(lambda _: self._setup_control_handlers())
         d.addCallback(lambda _: self._setup_query_handlers())
         d.addCallback(lambda _: self._load_plugins())
@@ -115,7 +116,7 @@ class LBRYConsole():
 
     def _get_autofetcher(self):
         self.autofetcher = AutoFetcher(self.session, self.lbry_file_manager, self.lbry_file_metadata_manager,
-                                       self.session.wallet, self.sd_identifier)
+                                       self.session.wallet, self.sd_identifier, self.autofetcher_conf)
 
     def _show_start_error(self, error):
         print error.getErrorMessage()

From ebf9d11f4d0f0f31d3f2653018f65a43d8943f9b Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Fri, 20 Nov 2015 10:42:19 -0500
Subject: [PATCH 10/21] Rename a class

---
 lbrynet/core/client/AutoDownloader.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lbrynet/core/client/AutoDownloader.py b/lbrynet/core/client/AutoDownloader.py
index 724ad7d55..5ebcea353 100644
--- a/lbrynet/core/client/AutoDownloader.py
+++ b/lbrynet/core/client/AutoDownloader.py
@@ -11,7 +11,7 @@ from lbrynet.core.StreamDescriptor import download_sd_blob
 log = logging.getLogger(__name__)
 
 
-class AutoAddStreamFromLBRYcrdName(object):
+class AutoAddStream(object):
     def __init__(self, console, sd_identifier, session, wallet, lbry_file_manager, max_key_fee):
         self.finished_deferred = defer.Deferred(None)
         self.console = console
@@ -193,7 +193,7 @@ class AutoFetcher(object):
         if claims:
             for claim in claims:
                 download = defer.Deferred()
-                stream = AutoAddStreamFromLBRYcrdName(self.console, self.sd_identifier, self.session,
+                stream = AutoAddStream(self.console, self.sd_identifier, self.session,
                                                       self.wallet, self.lbry_file_manager, self.max_key_fee)
                 download.addCallback(lambda _: stream.start(claim))
                 download.callback(None)

From a9e105f9eb85e93ef57cf9d5e6c0e8b7547c1d76 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Tue, 24 Nov 2015 01:17:47 -0500
Subject: [PATCH 11/21] Make autofetcher ignore key payments

---
 lbrynet/core/client/AutoDownloader.py | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/lbrynet/core/client/AutoDownloader.py b/lbrynet/core/client/AutoDownloader.py
index 5ebcea353..70edce257 100644
--- a/lbrynet/core/client/AutoDownloader.py
+++ b/lbrynet/core/client/AutoDownloader.py
@@ -52,9 +52,10 @@ class AutoAddStream(object):
         self.stream_hash = json.loads(self.stream_info['value'])['stream_hash']
 
         if self.key_fee > self.max_key_fee:
-            self.console.sendLine("Key fee (" + str(self.key_fee) + ") above limit of " + str(
-                self.max_key_fee) + ", didn't download lbry://" + str(self.resolved_name))
-            return self.finished_deferred.callback(None)
+            pass
+            # self.console.sendLine("Key fee (" + str(self.key_fee) + ") above limit of " + str(
+            #     self.max_key_fee) + ", didn't download lbry://" + str(self.resolved_name))
+            # return self.finished_deferred.callback(None)
 
         self.loading_metadata_deferred = defer.Deferred(None)
         self.loading_metadata_deferred.addCallback(
@@ -69,7 +70,8 @@ class AutoAddStream(object):
         return self.finished_deferred.callback(None)
 
     def _start_download(self):
-        d = self._pay_key_fee()
+        #d = self._pay_key_fee()
+        d = defer.Deferred(None)
         d.addCallback(lambda _: self._make_downloader())
         d.addCallback(lambda stream_downloader: stream_downloader.start())
         d.addErrback(self._handle_download_error)

From f3141727d7293fe173f6c91c951fd2764e6e6d35 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Thu, 3 Dec 2015 20:56:56 -0500
Subject: [PATCH 12/21] Update from master and fix a path problem

Update from the master branch and a fix to a path problem in lbrynet-gui
---
 lbrynet/core/LBRYcrdWallet.py              | 27 ++++++-
 lbrynet/core/Session.py                    |  3 +-
 lbrynet/lbrynet_console/ConsoleControl.py  |  4 +
 lbrynet/lbrynet_console/ControlHandlers.py |  3 +-
 lbrynet/lbrynet_console/LBRYConsole.py     | 54 +++++++++++++-
 lbrynet/lbrynet_gui/GuiApp.py              |  2 +-
 lbrynet/lbrynet_gui/LBRYGui.py             | 86 +++++++++++-----------
 7 files changed, 129 insertions(+), 50 deletions(-)

diff --git a/lbrynet/core/LBRYcrdWallet.py b/lbrynet/core/LBRYcrdWallet.py
index 510d949f2..ef4f70d00 100644
--- a/lbrynet/core/LBRYcrdWallet.py
+++ b/lbrynet/core/LBRYcrdWallet.py
@@ -312,7 +312,7 @@ class LBRYcrdWallet(object):
 
     def get_name_and_validity_for_sd_hash(self, sd_hash):
         d = self._get_claim_metadata_for_sd_hash(sd_hash)
-        d.addCallback(lambda name_txid: self._get_status_of_claim(name_txid[1], name_txid[0], sd_hash) if name_txid is not None else None)
+        d.addCallback(lambda name_txid: threads.deferToThread(self._get_status_of_claim, name_txid[1], name_txid[0], sd_hash) if name_txid is not None else None)
         return d
 
     def get_available_balance(self):
@@ -321,6 +321,15 @@ class LBRYcrdWallet(object):
     def get_new_address(self):
         return threads.deferToThread(self._get_new_address)
 
+    def check_first_run(self):
+        d = threads.deferToThread(self._get_wallet_balance)
+        d.addCallback(lambda bal: threads.deferToThread(self._get_num_addresses) if bal == 0 else 2)
+        d.addCallback(lambda num_addresses: True if num_addresses <= 1 else False)
+        return d
+
+    def get_most_recent_blocktime(self):
+        return threads.deferToThread(self._get_best_block_time)
+
     def get_rpc_conf(self):
         settings = {"username": "rpcuser",
                     "password": "rpcpassword",
@@ -378,7 +387,7 @@ class LBRYcrdWallet(object):
             except (socket.error, JSONRPCException):
                 tries += 1
                 log.warning("Failed to connect to lbrycrdd.")
-                if tries < 5:
+                if tries < 6:
                     time.sleep(2 ** tries)
                     log.warning("Trying again in %d seconds", 2 ** tries)
                 else:
@@ -512,6 +521,20 @@ class LBRYcrdWallet(object):
                         return name, "unconfirmed"
         return None
 
+    @_catch_connection_error
+    def _get_num_addresses(self):
+        rpc_conn = self._get_rpc_conn()
+        return len(rpc_conn.getaddressesbyaccount(""))
+
+    @_catch_connection_error
+    def _get_best_block_time(self):
+        rpc_conn = self._get_rpc_conn()
+        best_block_hash = rpc_conn.getbestblockhash()
+        block = rpc_conn.getblock(best_block_hash)
+        if 'time' in block:
+            return block['time']
+        raise ValueError("Could not get a block time")
+
 
     @_catch_connection_error
     def _rpc_stop(self):
diff --git a/lbrynet/core/Session.py b/lbrynet/core/Session.py
index 21fd4c979..cc31c08ff 100644
--- a/lbrynet/core/Session.py
+++ b/lbrynet/core/Session.py
@@ -148,7 +148,8 @@ class LBRYSession(object):
             ds.append(defer.maybeDeferred(self.wallet.stop))
         if self.blob_manager is not None:
             ds.append(defer.maybeDeferred(self.blob_manager.stop))
-        ds.append(defer.maybeDeferred(self._unset_upnp))
+        if self.use_upnp is True:
+            ds.append(defer.maybeDeferred(self._unset_upnp))
         return defer.DeferredList(ds)
 
     def _try_upnp(self):
diff --git a/lbrynet/lbrynet_console/ConsoleControl.py b/lbrynet/lbrynet_console/ConsoleControl.py
index a69b73350..4d49fd6d4 100644
--- a/lbrynet/lbrynet_console/ConsoleControl.py
+++ b/lbrynet/lbrynet_console/ConsoleControl.py
@@ -12,6 +12,8 @@ class ConsoleControl(basic.LineReceiver):
     def __init__(self):
         self.connected = False
         self.buffer = []
+        self.command_handlers = {}
+        self.current_handler = None
 
     def start(self, command_handlers):
         self.command_handlers = {h.command: h for h in command_handlers}
@@ -83,6 +85,8 @@ class ConsoleControl(basic.LineReceiver):
         self.show_prompt()
 
     def lineReceived(self, line):
+        if not self.command_handlers:
+            return
         if self.current_handler is None:
             words = line.split()
             if len(words) == 0:
diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py
index 4913414dd..4a5954f9d 100644
--- a/lbrynet/lbrynet_console/ControlHandlers.py
+++ b/lbrynet/lbrynet_console/ControlHandlers.py
@@ -842,7 +842,7 @@ class LBRYFileChooser(RecursiveCommandHandler):
     def _get_control_handler_factories(self):
         control_handler_factories = []
         for lbry_file in self.lbry_file_manager.lbry_files:
-            control_handler_factories.append(self.factory_class(lbry_file, *self.args))
+            control_handler_factories.append(self.factory_class(self.console, lbry_file, *self.args))
         return control_handler_factories
 
 
@@ -2454,4 +2454,3 @@ class BlockchainStatusFactory(CommandHandlerFactory):
     command = "get-blockchain-status"
     short_help = "Show whether this application has caught up with the LBC blockchain"
     full_help = "Show whether this applications has caught up with the LBC blockchain"
-
diff --git a/lbrynet/lbrynet_console/LBRYConsole.py b/lbrynet/lbrynet_console/LBRYConsole.py
index 069948165..226716b6e 100644
--- a/lbrynet/lbrynet_console/LBRYConsole.py
+++ b/lbrynet/lbrynet_console/LBRYConsole.py
@@ -2,6 +2,8 @@ import logging
 from lbrynet.core.Session import LBRYSession
 import os.path
 import argparse
+import requests
+import locale
 from yapsy.PluginManager import PluginManager
 from twisted.internet import defer, threads, stdio, task, error
 
@@ -37,6 +39,7 @@ from lbrynet.lbrynet_console.ControlHandlers import ClaimNameFactory, GetNewWall
 from lbrynet.lbrynet_console.ControlHandlers import ShowServerStatusFactory, ModifyServerSettingsFactory
 from lbrynet.lbrynet_console.ControlHandlers import ModifyLBRYFileOptionsChooserFactory, StatusFactory
 from lbrynet.lbrynet_console.ControlHandlers import PeerStatsAndSettingsChooserFactory, PublishFactory
+from lbrynet.lbrynet_console.ControlHandlers import BlockchainStatusFactory
 from lbrynet.core.LBRYcrdWallet import LBRYcrdWallet
 
 
@@ -245,7 +248,8 @@ class LBRYConsole():
                     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))
+                                                wallet_conf=self.lbrycrd_conf,
+                                                lbrycrdd_path=lbrycrdd_path))
             else:
                 d = defer.succeed(PTCWallet(self.db_dir))
             d.addCallback(lambda wallet: {"wallet": wallet})
@@ -278,8 +282,51 @@ class LBRYConsole():
 
         dl.addCallback(lambda _: self.session.setup())
 
+        dl.addCallback(lambda _: self.check_first_run())
+
+        dl.addCallback(self._show_first_run_result)
+
         return dl
 
+    def check_first_run(self):
+        d = self.session.wallet.check_first_run()
+        d.addCallback(lambda is_first_run: self._do_first_run() if is_first_run else 0.0)
+        return d
+
+    def _do_first_run(self):
+        d = self.session.wallet.get_new_address()
+
+        def send_request(url, data):
+            r = requests.post(url, json=data)
+            if r.status_code == 200:
+                return r.json()['credits_sent']
+            return 0.0
+
+        def log_error(err):
+            log.warning("unable to request free credits. %s", err.getErrorMessage())
+            return 0.0
+
+        def request_credits(address):
+            url = "http://credreq.lbry.io/requestcredits"
+            data = {"address": address}
+            d = threads.deferToThread(send_request, url, data)
+            d.addErrback(log_error)
+            return d
+
+        d.addCallback(request_credits)
+        return d
+
+    @staticmethod
+    def _show_first_run_result(credits_received):
+        if credits_received != 0.0:
+            points_string = locale.format_string("%.2f LBC", (round(credits_received, 2),),
+                                                 grouping=True)
+            alert.info("Thank you for using 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.\nTo check whether you've caught up with the blockchain, "
+                       "use the command 'get-blockchain-status'.\nDownloading some files "
+                       "may not work until you have downloaded the LBC blockchain.", points_string)
+
     def _setup_lbry_file_manager(self):
         self.lbry_file_metadata_manager = DBLBRYFileMetadataManager(self.db_dir)
         d = self.lbry_file_metadata_manager.setup()
@@ -333,10 +380,11 @@ class LBRYConsole():
             lbrycrd_handlers = [
                 AddStreamFromLBRYcrdNameFactory(self.sd_identifier, self.session,
                                                 self.session.wallet),
-                ClaimNameFactory(self.session. wallet, self.lbry_file_manager,
+                ClaimNameFactory(self.session.wallet, self.lbry_file_manager,
                                  self.session.blob_manager),
                 GetNewWalletAddressFactory(self.session.wallet),
-                PublishFactory(self.session, self.lbry_file_manager, self.session.wallet)
+                PublishFactory(self.session, self.lbry_file_manager, self.session.wallet),
+                BlockchainStatusFactory(self.session.wallet)
             ]
             self.add_control_handlers(lbrycrd_handlers)
         if self.peer_port is not None:
diff --git a/lbrynet/lbrynet_gui/GuiApp.py b/lbrynet/lbrynet_gui/GuiApp.py
index 8f5081002..573ac1df6 100644
--- a/lbrynet/lbrynet_gui/GuiApp.py
+++ b/lbrynet/lbrynet_gui/GuiApp.py
@@ -226,7 +226,7 @@ class DownloaderApp(object):
     def _start_downloader(self):
         self.downloader = LBRYDownloader()
         d = self.downloader.start()
-        d.addCallback(lambda _: self.downloader.do_first_run())
+        d.addCallback(lambda _: self.downloader.check_first_run())
         d.addCallback(self._show_welcome_message)
         return d
 
diff --git a/lbrynet/lbrynet_gui/LBRYGui.py b/lbrynet/lbrynet_gui/LBRYGui.py
index f8cdfa8c4..fad1d0fb0 100644
--- a/lbrynet/lbrynet_gui/LBRYGui.py
+++ b/lbrynet/lbrynet_gui/LBRYGui.py
@@ -32,8 +32,6 @@ class LBRYDownloader(object):
         self.known_dht_nodes = [('104.236.42.182', 4000)]
         self.db_dir = os.path.join(os.path.expanduser("~"), ".lbrydownloader")
         self.blobfile_dir = os.path.join(self.db_dir, "blobfiles")
-        self.wallet_dir = os.path.join(os.path.expanduser("~"), ".lbrycrd")
-        self.wallet_conf = os.path.join(self.wallet_dir, "lbrycrd.conf")
         self.peer_port = 3333
         self.dht_node_port = 4444
         self.run_server = True
@@ -42,8 +40,11 @@ class LBRYDownloader(object):
         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.getcwd()
+            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()
@@ -267,26 +268,26 @@ class LBRYDownloader(object):
         if not os.path.exists(self.blobfile_dir):
             os.makedirs(self.blobfile_dir)
             log.debug("Created the data directory: %s", str(self.blobfile_dir))
-        if not os.path.exists(self.wallet_dir):
-            os.makedirs(self.wallet_dir)
-        if not os.path.exists(self.wallet_conf):
-            lbrycrd_conf = open(self.wallet_conf, mode='w')
-            self.wallet_user = "rpcuser"
-            lbrycrd_conf.write("rpcuser=%s\n" % self.wallet_user)
-            self.wallet_password = binascii.hexlify(Random.new().read(20))
-            lbrycrd_conf.write("rpcpassword=%s\n" % self.wallet_password)
-            lbrycrd_conf.write("server=1\n")
-            lbrycrd_conf.close()
-            self.first_run = True
-        else:
-            lbrycrd_conf = open(self.wallet_conf)
-            for l in lbrycrd_conf:
-                if l.startswith("rpcuser="):
-                    self.wallet_user = l[8:].rstrip('\n')
-                if l.startswith("rpcpassword="):
-                    self.wallet_password = l[12:].rstrip('\n')
-                if l.startswith("rpcport="):
-                    self.wallet_rpc_port = int(l[8:-1].rstrip('\n'))
+        if os.name == "nt":
+            if not os.path.exists(self.wallet_dir):
+                os.makedirs(self.wallet_dir)
+            if not os.path.exists(self.wallet_conf):
+                lbrycrd_conf = open(self.wallet_conf, mode='w')
+                self.wallet_user = "rpcuser"
+                lbrycrd_conf.write("rpcuser=%s\n" % self.wallet_user)
+                self.wallet_password = binascii.hexlify(Random.new().read(20))
+                lbrycrd_conf.write("rpcpassword=%s\n" % self.wallet_password)
+                lbrycrd_conf.write("server=1\n")
+                lbrycrd_conf.close()
+            else:
+                lbrycrd_conf = open(self.wallet_conf)
+                for l in lbrycrd_conf:
+                    if l.startswith("rpcuser="):
+                        self.wallet_user = l[8:].rstrip('\n')
+                    if l.startswith("rpcpassword="):
+                        self.wallet_password = l[12:].rstrip('\n')
+                    if l.startswith("rpcport="):
+                        self.wallet_rpc_port = int(l[8:-1].rstrip('\n'))
 
     def _get_session(self):
         lbrycrdd_path = None
@@ -349,30 +350,33 @@ class LBRYDownloader(object):
                                                     self.session.wallet)
         self.sd_identifier.add_stream_downloader_factory(LBRYFileStreamType, file_opener_factory)
 
-    def do_first_run(self):
-        if self.first_run is True:
-            d = self.session.wallet.get_new_address()
+    def check_first_run(self):
+        d = self.session.wallet.check_first_run()
+        d.addCallback(lambda is_first_run: self._do_first_run() if is_first_run else 0.0)
+        return d
 
-            def send_request(url, data):
-                r = requests.post(url, json=data)
-                if r.status_code == 200:
-                    return r.json()['credits_sent']
-                return 0.0
+    def _do_first_run(self):
+        d = self.session.wallet.get_new_address()
 
-            def log_error(err):
-                log.warning("unable to request free credits. %s", err.getErrorMessage())
-                return 0.0
+        def send_request(url, data):
+            r = requests.post(url, json=data)
+            if r.status_code == 200:
+                return r.json()['credits_sent']
+            return 0.0
 
-            def request_credits(address):
-                url = "http://credreq.lbry.io/requestcredits"
-                data = {"address": address}
-                d = threads.deferToThread(send_request, url, data)
-                d.addErrback(log_error)
-                return d
+        def log_error(err):
+            log.warning("unable to request free credits. %s", err.getErrorMessage())
+            return 0.0
 
-            d.addCallback(request_credits)
+        def request_credits(address):
+            url = "http://credreq.lbry.io/requestcredits"
+            data = {"address": address}
+            d = threads.deferToThread(send_request, url, data)
+            d.addErrback(log_error)
             return d
-        return defer.succeed(0.0)
+
+        d.addCallback(request_credits)
+        return d
 
     def _resolve_name(self, uri):
         return self.session.wallet.get_stream_info_for_name(uri)

From 441d3c1220b807007bea811a2198ca3fbdb43f97 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Sun, 6 Dec 2015 17:32:17 -0500
Subject: [PATCH 13/21] LBRYNet daemon

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.
---
 lbrynet/core/client/AutoDownloader.py         | 136 +++++++++
 lbrynet/lbryfilemanager/LBRYFileManager.py    |   5 +-
 lbrynet/lbrynet_daemon/LBRYDaemon.py          | 282 ++++++++++++++++++
 .../LBRYURIHandler/LBRYURIHandler.py          |  22 ++
 .../LBRYURIHandler.app/Contents/Info.plist    | 117 ++++++++
 .../lbrynet_daemon/LBRYURIHandler/setup.py    |  19 ++
 lbrynet/lbrynet_daemon/__init__.py            |   0
 lbrynet/lbrynet_gui/LBRYGui.py                |   7 +-
 8 files changed, 585 insertions(+), 3 deletions(-)
 create mode 100644 lbrynet/lbrynet_daemon/LBRYDaemon.py
 create mode 100644 lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py
 create mode 100644 lbrynet/lbrynet_daemon/LBRYURIHandler/dist/LBRYURIHandler.app/Contents/Info.plist
 create mode 100644 lbrynet/lbrynet_daemon/LBRYURIHandler/setup.py
 create mode 100644 lbrynet/lbrynet_daemon/__init__.py

diff --git a/lbrynet/core/client/AutoDownloader.py b/lbrynet/core/client/AutoDownloader.py
index 70edce257..df69f561f 100644
--- a/lbrynet/core/client/AutoDownloader.py
+++ b/lbrynet/core/client/AutoDownloader.py
@@ -113,6 +113,142 @@ class AutoAddStream(object):
         return self.downloader
 
 
+class GetStream(object):
+    def __init__(self, console, sd_identifier, session, wallet, lbry_file_manager, max_key_fee,
+                 console_on=True, pay_key=True):
+        self.finished_deferred = defer.Deferred(None)
+        self.console_on = console_on
+        self.pay_key = pay_key
+        self.console = console
+        self.wallet = wallet
+        self.resolved_name = None
+        self.description = None
+        self.key_fee = None
+        self.key_fee_address = None
+        self.name = None
+        self.session = session
+        self.payment_rate_manager = PaymentRateManager(self.session.base_payment_rate_manager)
+        self.loading_metadata_deferred = defer.Deferred()
+        self.lbry_file_manager = lbry_file_manager
+        self.sd_identifier = sd_identifier
+        self.metadata = None
+        self.loading_failed = False
+        self.resolved_name = None
+        self.description = None
+        self.key_fee = None
+        self.key_fee_address = None
+        self.stream_hash = None
+        self.max_key_fee = max_key_fee
+        self.stream_info = None
+        self.stream_info_manager = None
+        self.downloader = None
+
+    def start(self, stream_info):
+        self.stream_info = stream_info
+        try:
+            if 'stream_hash' in json.loads(self.stream_info['value']):
+                self.resolved_name = self.stream_info.get('name', None)
+                self.description = json.loads(self.stream_info['value']).get('description', None)
+                try:
+                    if 'key_fee' in json.loads(self.stream_info['value']):
+                        self.key_fee = float(json.loads(self.stream_info['value'])['key_fee'])
+                except ValueError:
+                    self.key_fee = None
+                self.key_fee_address = json.loads(self.stream_info['value']).get('key_fee_address', None)
+                self.stream_hash = json.loads(self.stream_info['value'])['stream_hash']
+            else:
+                raise InvalidStreamInfoError(self.stream_info)
+
+        except:
+            if 'stream_hash' in self.stream_info.keys():
+                self.description = self.stream_info['description']
+                if 'key_fee' in self.stream_info.keys():
+                    self.key_fee = float(self.stream_info['key_fee'])
+                    self.key_fee_address = self.stream_info['key_fee_address']
+                else:
+                    self.key_fee = None
+                self.stream_hash = self.stream_info['stream_hash']
+            else:
+                raise InvalidStreamInfoError(self.stream_info)
+
+        # if self.key_fee < self.max_key_fee:
+        #     if self.pay_key:
+        #         if self.console_on:
+        #             self.console.sendLine("Key fee (" + str(self.key_fee) + ") above limit of " + str(
+        #                 self.max_key_fee) + ", didn't download lbry://" + str(self.resolved_name))
+        #         return self.finished_deferred.callback(None)
+        #     else:
+        #         pass
+        # else:
+        #     pass
+
+        def _get_downloader_for_return():
+            return defer.succeed(self.downloader)
+
+        self.loading_metadata_deferred = defer.Deferred(None)
+        self.loading_metadata_deferred.addCallback(
+            lambda _: download_sd_blob(self.session, self.stream_hash, self.payment_rate_manager))
+        self.loading_metadata_deferred.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
+        self.loading_metadata_deferred.addCallback(self._handle_metadata)
+        self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
+        self.loading_metadata_deferred.addErrback(self._handle_load_failed)
+        self.loading_metadata_deferred.addCallback(lambda _: self._make_downloader())
+        self.loading_metadata_deferred.addCallback(lambda _: self.downloader.start())
+        self.loading_metadata_deferred.addErrback(self._handle_download_error)
+        self.loading_metadata_deferred.addCallback(lambda _: _get_downloader_for_return())
+        self.loading_metadata_deferred.callback(None)
+
+        return defer.succeed(None)
+
+    def _pay_key_fee(self):
+        if self.key_fee is not None and self.key_fee_address is not None:
+            reserved_points = self.wallet.reserve_points(self.key_fee_address, self.key_fee)
+            if reserved_points is None:
+                return defer.fail(InsufficientFundsError())
+            return self.wallet.send_points_to_address(reserved_points, self.key_fee)
+        if self.console_on:
+            self.console.sendLine("Sent key fee" + str(self.key_fee_address) + " | " + str(self.key_fee))
+        return defer.succeed(None)
+
+    def _handle_load_canceled(self, err):
+        err.trap(defer.CancelledError)
+        self.finished_deferred.callback(None)
+
+    def _handle_load_failed(self, err):
+        self.loading_failed = True
+        if self.console_on:
+            self.console.sendLine("handle load failed: " + str(err.getTraceback()))
+        log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback())
+        print 'Load Failed: ', err.getTraceback()
+        self.finished_deferred.callback(None)
+
+    def _handle_metadata(self, metadata):
+        self.metadata = metadata
+        self.factory = self.metadata.factories[0]
+        return defer.succeed(None) #self._start_download()
+
+    def _handle_download_error(self, err):
+        if self.console_on:
+            if err.check(InsufficientFundsError):
+                self.console.sendLine("Download stopped due to insufficient funds.")
+            else:
+                self.console.sendLine(
+                    "Autoaddstream: An unexpected error has caused the download to stop: %s" % err.getTraceback())
+        else:
+            print "Autoaddstream: An unexpected error has caused the download to stop: ", err.getTraceback()
+
+    def _make_downloader(self):
+
+        def _set_downloader(downloader):
+            self.downloader = downloader
+            print os.path.join(self.downloader.download_directory, self.downloader.file_name)
+            return self.downloader
+
+        self.downloader = self.factory.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
+        self.downloader.addCallback(_set_downloader)
+        return defer.succeed(self.downloader)
+
+
 class AutoFetcher(object):
     def __init__(self, session, lbry_file_manager, lbry_file_metadata_manager, wallet, sd_identifier, autofetcher_conf):
         self.autofetcher_conf = autofetcher_conf
diff --git a/lbrynet/lbryfilemanager/LBRYFileManager.py b/lbrynet/lbryfilemanager/LBRYFileManager.py
index f27f6052e..c2e426bfa 100644
--- a/lbrynet/lbryfilemanager/LBRYFileManager.py
+++ b/lbrynet/lbryfilemanager/LBRYFileManager.py
@@ -31,7 +31,10 @@ class LBRYFileManager(object):
         self.sd_identifier = sd_identifier
         self.lbry_files = []
         self.sql_db = None
-        self.download_directory = os.getcwd()
+        if os.name == 'posix':
+            self.download_directory = os.path.join(os.path.expanduser("~"), 'Downloads')
+        else:
+            self.download_directory = os.getcwd()
 
     def setup(self):
         d = self._open_db()
diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py
new file mode 100644
index 000000000..cb9e6e54c
--- /dev/null
+++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py
@@ -0,0 +1,282 @@
+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()
\ No newline at end of file
diff --git a/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py b/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py
new file mode 100644
index 000000000..2e1faa479
--- /dev/null
+++ b/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py
@@ -0,0 +1,22 @@
+import os
+import webbrowser
+import xmlrpclib, sys
+
+
+def main(args):
+    if len(args) == 0:
+        args.append('lbry://economicsman')
+
+    daemon = xmlrpclib.ServerProxy('http://localhost:7080/')
+
+    if len(args) > 1:
+        print 'Too many args', args
+    else:
+        resolved = daemon.resolve_name(str(args[0])[7:])
+        daemon.download_name(str(args[0])[7:])
+        path = [h for h in daemon.get_downloads() if h['stream_hash'] == resolved['stream_hash']][0]['path']
+        webbrowser.open('file://' + path)
+
+
+if __name__ == "__main__":
+   main(sys.argv[1:])
\ No newline at end of file
diff --git a/lbrynet/lbrynet_daemon/LBRYURIHandler/dist/LBRYURIHandler.app/Contents/Info.plist b/lbrynet/lbrynet_daemon/LBRYURIHandler/dist/LBRYURIHandler.app/Contents/Info.plist
new file mode 100644
index 000000000..4f5993ff1
--- /dev/null
+++ b/lbrynet/lbrynet_daemon/LBRYURIHandler/dist/LBRYURIHandler.app/Contents/Info.plist
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>LBRYURIHandler</string>
+	<key>CFBundleDocumentTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeOSTypes</key>
+			<array>
+				<string>****</string>
+				<string>fold</string>
+				<string>disk</string>
+			</array>
+			<key>CFBundleTypeRole</key>
+			<string>Viewer</string>
+		</dict>
+	</array>
+	<key>CFBundleExecutable</key>
+	<string>LBRYURIHandler</string>
+
+<key>CFBundleURLTypes</key>
+<array>
+    <dict>
+        <key>CFBundleURLName</key>
+        <string>LBRYURIHandler</string>
+        <key>CFBundleURLSchemes</key>
+        <array>
+            <string>lbry</string>
+        </array>
+    </dict>
+</array>
+<key>NSUIElement</key>
+<true/>
+
+	<key>CFBundleIconFile</key>
+	<string>PythonApplet.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.pythonmac.unspecified.LBRYURIHandler</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>LBRYURIHandler</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>0.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.0</string>
+	<key>LSHasLocalizedDisplayName</key>
+	<false/>
+	<key>NSAppleScriptEnabled</key>
+	<false/>
+	<key>NSHumanReadableCopyright</key>
+	<string>Copyright not specified</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+	<key>PyMainFileNames</key>
+	<array>
+		<string>__boot__</string>
+	</array>
+	<key>PyOptions</key>
+	<dict>
+		<key>alias</key>
+		<false/>
+		<key>argv_emulation</key>
+		<true/>
+		<key>emulate_shell_environment</key>
+		<false/>
+		<key>no_chdir</key>
+		<false/>
+		<key>prefer_ppc</key>
+		<false/>
+		<key>site_packages</key>
+		<false/>
+		<key>use_faulthandler</key>
+		<false/>
+		<key>use_pythonpath</key>
+		<false/>
+		<key>verbose</key>
+		<false/>
+	</dict>
+	<key>PyResourcePackages</key>
+	<array>
+	</array>
+	<key>PyRuntimeLocations</key>
+	<array>
+		<string>@executable_path/../Frameworks/Python.framework/Versions/2.7/Python</string>
+	</array>
+	<key>PythonInfoDict</key>
+	<dict>
+		<key>PythonExecutable</key>
+		<string>/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python</string>
+		<key>PythonLongVersion</key>
+		<string>2.7.10 (v2.7.10:15c95b7d81dc, May 23 2015, 09:33:12) 
+[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]</string>
+		<key>PythonShortVersion</key>
+		<string>2.7</string>
+		<key>py2app</key>
+		<dict>
+			<key>alias</key>
+			<false/>
+			<key>template</key>
+			<string>app</string>
+			<key>version</key>
+			<string>0.9</string>
+		</dict>
+	</dict>
+</dict>
+</plist>
diff --git a/lbrynet/lbrynet_daemon/LBRYURIHandler/setup.py b/lbrynet/lbrynet_daemon/LBRYURIHandler/setup.py
new file mode 100644
index 000000000..fbb83f5dc
--- /dev/null
+++ b/lbrynet/lbrynet_daemon/LBRYURIHandler/setup.py
@@ -0,0 +1,19 @@
+"""
+This is a setup.py script generated by py2applet
+
+Usage:
+    python setup.py py2app
+"""
+
+from setuptools import setup
+
+APP = ['LBRYURIHandler.py']
+DATA_FILES = []
+OPTIONS = {'argv_emulation': True}
+
+setup(
+    app=APP,
+    data_files=DATA_FILES,
+    options={'py2app': OPTIONS},
+    setup_requires=['py2app'],
+)
diff --git a/lbrynet/lbrynet_daemon/__init__.py b/lbrynet/lbrynet_daemon/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/lbrynet/lbrynet_gui/LBRYGui.py b/lbrynet/lbrynet_gui/LBRYGui.py
index fad1d0fb0..1926d80fe 100644
--- a/lbrynet/lbrynet_gui/LBRYGui.py
+++ b/lbrynet/lbrynet_gui/LBRYGui.py
@@ -57,7 +57,8 @@ class LBRYDownloader(object):
         if os.name == "nt":
             self.lbrycrdd_path = "lbrycrdd.exe"
         else:
-            self.lbrycrdd_path = "./lbrycrdd"
+            self.lbrycrdd_path = None
+            self.default_lbrycrdd_path = "./lbrycrdd"
         self.delete_blobs_on_remove = True
         self.blob_request_payment_rate_manager = None
 
@@ -123,7 +124,7 @@ class LBRYDownloader(object):
             if not os.path.exists(lbrycrdd_path_conf_path):
                 return ""
             lbrycrdd_path_conf = open(lbrycrdd_path_conf_path)
-            lines = lbrycrdd_path_conf.readline()
+            lines = lbrycrdd_path_conf.readlines()
             return lines
 
         d = threads.deferToThread(get_lbrycrdd_path_conf_file)
@@ -293,6 +294,8 @@ class LBRYDownloader(object):
         lbrycrdd_path = None
         if self.start_lbrycrdd is True:
             lbrycrdd_path = self.lbrycrdd_path
+            if not lbrycrdd_path:
+                lbrycrdd_path = self.default_lbrycrdd_path
 
         wallet = LBRYcrdWallet(self.db_dir, wallet_dir=self.wallet_dir, wallet_conf=self.wallet_conf,
                                lbrycrdd_path=lbrycrdd_path)

From 526075cd5eb4332108d557e9777aeb910672260e Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Mon, 7 Dec 2015 09:17:45 -0500
Subject: [PATCH 14/21] Fix get_downloads function

get_downloads would throw an error when it tried to open a file that
had already been downloaded, now it just ignores these duplicates
---
 lbrynet/lbrynet_daemon/LBRYDaemon.py | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py
index cb9e6e54c..887531d65 100644
--- a/lbrynet/lbrynet_daemon/LBRYDaemon.py
+++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py
@@ -242,9 +242,15 @@ class LBRYDaemon(xmlrpc.XMLRPC):
         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]
+        downloads = []
+
+        for stream in self.download_deferreds:
+            try:
+                downloads.append({'stream_hash': stream.stream_hash,
+                        'path': os.path.join(stream.downloader.download_directory, stream.downloader.file_name)})
+            except:
+                pass
+
         return downloads
 
     def xmlrpc_download_name(self, name):

From 8aee19b0ef7af5631d4e3e94843033f1879cb6c3 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Mon, 7 Dec 2015 18:02:29 -0500
Subject: [PATCH 15/21] Fix error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Fixes an error if you don’t have a conf file set up, previously it
would fail because the AutoFetcher object doesn’t have a console object
until it’s called for the first time
---
 lbrynet/core/client/AutoDownloader.py | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lbrynet/core/client/AutoDownloader.py b/lbrynet/core/client/AutoDownloader.py
index df69f561f..23460be72 100644
--- a/lbrynet/core/client/AutoDownloader.py
+++ b/lbrynet/core/client/AutoDownloader.py
@@ -352,10 +352,10 @@ class AutoFetcher(object):
                 if l.startswith("maxkey="):
                     settings["maxkey"] = float(l[7:].rstrip('\n'))
         else:
-            self.console.sendLine("Autofetcher using default max key price of 0.0")
-            self.console.sendLine("To change this create the file:")
-            self.console.sendLine(str(self.autofetcher_conf))
-            self.console.sendLine("Example contents of conf file:")
-            self.console.sendLine("maxkey=1.0")
+            print "Autofetcher using default max key price of 0.0"
+            print "To change this create the file:"
+            print str(self.autofetcher_conf)
+            print "Example contents of conf file:"
+            print "maxkey=1.0"
 
         self.max_key_fee = settings["maxkey"]

From 203f7e7ea650e6f3e957540b3d4414eb5a43fef9 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Tue, 8 Dec 2015 00:37:49 -0500
Subject: [PATCH 16/21] Update lbry daemon

---
 lbrynet/core/client/AutoDownloader.py | 71 ++++++++-------------------
 lbrynet/lbrynet_daemon/LBRYDaemon.py  | 37 +++++++++-----
 2 files changed, 46 insertions(+), 62 deletions(-)

diff --git a/lbrynet/core/client/AutoDownloader.py b/lbrynet/core/client/AutoDownloader.py
index 23460be72..10e06e6cf 100644
--- a/lbrynet/core/client/AutoDownloader.py
+++ b/lbrynet/core/client/AutoDownloader.py
@@ -114,12 +114,8 @@ class AutoAddStream(object):
 
 
 class GetStream(object):
-    def __init__(self, console, sd_identifier, session, wallet, lbry_file_manager, max_key_fee,
-                 console_on=True, pay_key=True):
+    def __init__(self, sd_identifier, session, wallet, lbry_file_manager, max_key_fee):
         self.finished_deferred = defer.Deferred(None)
-        self.console_on = console_on
-        self.pay_key = pay_key
-        self.console = console
         self.wallet = wallet
         self.resolved_name = None
         self.description = None
@@ -145,42 +141,23 @@ class GetStream(object):
 
     def start(self, stream_info):
         self.stream_info = stream_info
-        try:
-            if 'stream_hash' in json.loads(self.stream_info['value']):
-                self.resolved_name = self.stream_info.get('name', None)
-                self.description = json.loads(self.stream_info['value']).get('description', None)
-                try:
-                    if 'key_fee' in json.loads(self.stream_info['value']):
-                        self.key_fee = float(json.loads(self.stream_info['value'])['key_fee'])
-                except ValueError:
-                    self.key_fee = None
-                self.key_fee_address = json.loads(self.stream_info['value']).get('key_fee_address', None)
-                self.stream_hash = json.loads(self.stream_info['value'])['stream_hash']
+        if 'stream_hash' in self.stream_info.keys():
+            self.description = self.stream_info['description']
+            if 'key_fee' in self.stream_info.keys():
+                self.key_fee = float(self.stream_info['key_fee'])
+                self.key_fee_address = self.stream_info['key_fee_address']
             else:
-                raise InvalidStreamInfoError(self.stream_info)
+                self.key_fee = None
+            self.stream_hash = self.stream_info['stream_hash']
+        else:
+            raise InvalidStreamInfoError(self.stream_info)
 
-        except:
-            if 'stream_hash' in self.stream_info.keys():
-                self.description = self.stream_info['description']
-                if 'key_fee' in self.stream_info.keys():
-                    self.key_fee = float(self.stream_info['key_fee'])
-                    self.key_fee_address = self.stream_info['key_fee_address']
-                else:
-                    self.key_fee = None
-                self.stream_hash = self.stream_info['stream_hash']
-            else:
-                raise InvalidStreamInfoError(self.stream_info)
-
-        # if self.key_fee < self.max_key_fee:
-        #     if self.pay_key:
-        #         if self.console_on:
-        #             self.console.sendLine("Key fee (" + str(self.key_fee) + ") above limit of " + str(
-        #                 self.max_key_fee) + ", didn't download lbry://" + str(self.resolved_name))
-        #         return self.finished_deferred.callback(None)
-        #     else:
-        #         pass
-        # else:
-        #     pass
+        if self.key_fee > self.max_key_fee:
+            print "Key fee (" + str(self.key_fee) + ") above limit of " + str(
+                                    self.max_key_fee) + ", didn't download lbry://" + str(self.resolved_name)
+            return self.finished_deferred.callback(None)
+        else:
+            pass
 
         def _get_downloader_for_return():
             return defer.succeed(self.downloader)
@@ -192,6 +169,7 @@ class GetStream(object):
         self.loading_metadata_deferred.addCallback(self._handle_metadata)
         self.loading_metadata_deferred.addErrback(self._handle_load_canceled)
         self.loading_metadata_deferred.addErrback(self._handle_load_failed)
+        self.loading_metadata_deferred.addCallback(lambda _: self._pay_key_fee())
         self.loading_metadata_deferred.addCallback(lambda _: self._make_downloader())
         self.loading_metadata_deferred.addCallback(lambda _: self.downloader.start())
         self.loading_metadata_deferred.addErrback(self._handle_download_error)
@@ -205,9 +183,8 @@ class GetStream(object):
             reserved_points = self.wallet.reserve_points(self.key_fee_address, self.key_fee)
             if reserved_points is None:
                 return defer.fail(InsufficientFundsError())
+            print 'Key fee: ' + str(self.key_fee) + ' | ' + str(self.key_fee_address)
             return self.wallet.send_points_to_address(reserved_points, self.key_fee)
-        if self.console_on:
-            self.console.sendLine("Sent key fee" + str(self.key_fee_address) + " | " + str(self.key_fee))
         return defer.succeed(None)
 
     def _handle_load_canceled(self, err):
@@ -216,8 +193,6 @@ class GetStream(object):
 
     def _handle_load_failed(self, err):
         self.loading_failed = True
-        if self.console_on:
-            self.console.sendLine("handle load failed: " + str(err.getTraceback()))
         log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback())
         print 'Load Failed: ', err.getTraceback()
         self.finished_deferred.callback(None)
@@ -225,15 +200,11 @@ class GetStream(object):
     def _handle_metadata(self, metadata):
         self.metadata = metadata
         self.factory = self.metadata.factories[0]
-        return defer.succeed(None) #self._start_download()
+        return defer.succeed(None)
 
     def _handle_download_error(self, err):
-        if self.console_on:
-            if err.check(InsufficientFundsError):
-                self.console.sendLine("Download stopped due to insufficient funds.")
-            else:
-                self.console.sendLine(
-                    "Autoaddstream: An unexpected error has caused the download to stop: %s" % err.getTraceback())
+        if err.check(InsufficientFundsError):
+            print "Download stopped due to insufficient funds."
         else:
             print "Autoaddstream: An unexpected error has caused the download to stop: ", err.getTraceback()
 
diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py
index 887531d65..44c01bf9c 100644
--- a/lbrynet/lbrynet_daemon/LBRYDaemon.py
+++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py
@@ -46,7 +46,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
             self.sd_identifier = StreamDescriptorIdentifier()
             self.stream_info_manager = TempLBRYFileMetadataManager()
             self.wallet_rpc_port = 8332
-            self.download_deferreds = []
+            self.downloads = []
             self.stream_frames = []
             self.default_blob_data_payment_rate = MIN_BLOB_DATA_PAYMENT_RATE
             self.use_upnp = True
@@ -64,6 +64,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
             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
+            self.files = []
             return defer.succeed(None)
 
         d = defer.Deferred()
@@ -208,7 +209,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
         self.sd_identifier.add_stream_downloader_factory(LBRYFileStreamType, downloader_factory)
         return defer.succeed(True)
 
-    def xmlrpc_getbalance(self):
+    def xmlrpc_get_balance(self):
         """
         Get LBC balance
         """
@@ -233,6 +234,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
 
         d = defer.Deferred()
         d.addCallback(lambda _: self.session.wallet.get_stream_info_for_name(name))
+        d.addErrback(lambda _: 'UnknownNameError')
         d.addCallback(_disp)
         d.callback(None)
         return d
@@ -244,7 +246,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
 
         downloads = []
 
-        for stream in self.download_deferreds:
+        for stream in self.downloads:
             try:
                 downloads.append({'stream_hash': stream.stream_hash,
                         'path': os.path.join(stream.downloader.download_directory, stream.downloader.file_name)})
@@ -260,23 +262,34 @@ class LBRYDaemon(xmlrpc.XMLRPC):
 
         def _disp():
             try:
-                stream = self.download_deferreds[-1]
+                stream = self.downloads[-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)
+        stream = GetStream(self.sd_identifier, self.session, self.session.wallet, self.lbry_file_manager, 25.0)
+        self.downloads.append(stream)
 
-        d = defer.Deferred()
-        d.addCallback(lambda _: self.session.wallet.get_stream_info_for_name(name))
+        d = 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))
+        # d.addCallback(lambda _: self.files.append({'name': name, 'stream_hash': stream.stream_hash,
+        #                  'path': os.path.join(stream.downloader.download_directory, stream.downloader.file_name)}))
+        d.addCallback(lambda _: {'ts': datetime.now(),'name': name})
+        d.addErrback(lambda _: 'UnknownNameError')
+
+        return d
+
+    def xmlrpc_path_from_name(self, name):
+        d = self.session.wallet.get_stream_info_for_name(name)
+        d.addCallback(lambda stream_info: stream_info['stream_hash'])
+        d.addCallback(lambda stream_hash: [{'stream_hash': stream.stream_hash,
+                                            'path': os.path.join(stream.downloader.download_directory,
+                                                                 stream.downloader.file_name)}
+                                           for stream in self.downloads if stream.stream_hash == stream_hash])
+        return d
+    
 
 def main():
     daemon = LBRYDaemon()

From afac596a7b82dea3ad6363f8324268327c469961 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Wed, 9 Dec 2015 23:57:58 -0500
Subject: [PATCH 17/21] Update url handler

---
 lbrynet/lbrynet_daemon/LBRYDaemon.py                    | 3 ++-
 lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py
index 44c01bf9c..7a636963e 100644
--- a/lbrynet/lbrynet_daemon/LBRYDaemon.py
+++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py
@@ -288,8 +288,9 @@ class LBRYDaemon(xmlrpc.XMLRPC):
                                             'path': os.path.join(stream.downloader.download_directory,
                                                                  stream.downloader.file_name)}
                                            for stream in self.downloads if stream.stream_hash == stream_hash])
+        d.addErrback(lambda _: 'UnknownNameError')
         return d
-    
+
 
 def main():
     daemon = LBRYDaemon()
diff --git a/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py b/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py
index 2e1faa479..0f2623718 100644
--- a/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py
+++ b/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py
@@ -11,6 +11,7 @@ def main(args):
 
     if len(args) > 1:
         print 'Too many args', args
+
     else:
         resolved = daemon.resolve_name(str(args[0])[7:])
         daemon.download_name(str(args[0])[7:])

From 9667b81c8dd4f1baffd701246e66974681485aab Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Wed, 9 Dec 2015 23:59:19 -0500
Subject: [PATCH 18/21] Update url handler

---
 lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py b/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py
index 0f2623718..81bc0fb83 100644
--- a/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py
+++ b/lbrynet/lbrynet_daemon/LBRYURIHandler/LBRYURIHandler.py
@@ -1,11 +1,10 @@
-import os
 import webbrowser
 import xmlrpclib, sys
 
 
 def main(args):
     if len(args) == 0:
-        args.append('lbry://economicsman')
+        args.append('lbry://wonderfullife')
 
     daemon = xmlrpclib.ServerProxy('http://localhost:7080/')
 
@@ -13,11 +12,9 @@ def main(args):
         print 'Too many args', args
 
     else:
-        resolved = daemon.resolve_name(str(args[0])[7:])
         daemon.download_name(str(args[0])[7:])
-        path = [h for h in daemon.get_downloads() if h['stream_hash'] == resolved['stream_hash']][0]['path']
+        path = daemon.path_from_name(args[0][7:])[0]['path']
         webbrowser.open('file://' + path)
 
-
 if __name__ == "__main__":
    main(sys.argv[1:])
\ No newline at end of file

From 0eecfb52ed591e11ff1b0d3ddd052c2ca0ea54ad Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Mon, 14 Dec 2015 10:22:52 -0500
Subject: [PATCH 19/21] Update lbrynet-daemon
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Daemon creates data directory if it doesn’t already exist
---
 lbrynet/lbrynet_daemon/LBRYDaemon.py | 49 +++++++++++++++++++++++++++-
 setup.py                             |  1 +
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py
index 7a636963e..88291d902 100644
--- a/lbrynet/lbrynet_daemon/LBRYDaemon.py
+++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py
@@ -1,4 +1,3 @@
-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
@@ -15,6 +14,10 @@ from lbrynet.lbryfile.LBRYFileMetadataManager import DBLBRYFileMetadataManager,
 from twisted.web import xmlrpc, server
 from twisted.internet import defer, threads, reactor
 from datetime import datetime
+import logging
+import os
+
+log = logging.getLogger(__name__)
 
 
 class LBRYDaemon(xmlrpc.XMLRPC):
@@ -24,6 +27,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
 
     def setup(self):
         def _set_vars():
+            self.current_db_revision = 1
             self.run_server = True
             self.session = None
             self.known_dht_nodes = [('104.236.42.182', 4000)]
@@ -65,10 +69,16 @@ class LBRYDaemon(xmlrpc.XMLRPC):
             self.lbrycrd_conf = os.path.join(self.lbrycrd_dir, "lbrycrd.conf")
             self.rpc_conn = None
             self.files = []
+            self.created_data_dir = False
+            if not os.path.exists(self.db_dir):
+                os.mkdir(self.db_dir)
+                self.created_data_dir = True
             return defer.succeed(None)
 
         d = defer.Deferred()
         d.addCallback(lambda _: _set_vars())
+        d.addCallback(lambda _: threads.deferToThread(self._setup_data_directory))
+        d.addCallback(lambda _: self._check_db_migration())
         d.addCallback(lambda _: self._get_settings())
         d.addCallback(lambda _: self.get_lbrycrdd_path())
         d.addCallback(lambda _: self._get_session())
@@ -80,6 +90,41 @@ class LBRYDaemon(xmlrpc.XMLRPC):
 
         return defer.succeed(None)
 
+    def _setup_data_directory(self):
+        print "Loading databases..."
+        if self.created_data_dir:
+            db_revision = open(os.path.join(self.db_dir, "db_revision"), mode='w')
+            db_revision.write(str(self.current_db_revision))
+            db_revision.close()
+            log.debug("Created the db revision file: %s", str(os.path.join(self.db_dir, "db_revision")))
+        if not os.path.exists(self.blobfile_dir):
+            os.mkdir(self.blobfile_dir)
+            log.debug("Created the blobfile directory: %s", str(self.blobfile_dir))
+
+    def _check_db_migration(self):
+        old_revision = 0
+        db_revision_file = os.path.join(self.db_dir, "db_revision")
+        if os.path.exists(db_revision_file):
+            old_revision = int(open(db_revision_file).read().strip())
+        if old_revision < self.current_db_revision:
+            from lbrynet.db_migrator import dbmigrator
+            print "Upgrading your databases..."
+            d = threads.deferToThread(dbmigrator.migrate_db, self.db_dir, old_revision, self.current_db_revision)
+
+            def print_success(old_dirs):
+                success_string = "Finished upgrading the databases. It is now safe to delete the"
+                success_string += " following directories, if you feel like it. It won't make any"
+                success_string += " difference.\nAnyway here they are: "
+                for i, old_dir in enumerate(old_dirs):
+                    success_string += old_dir
+                    if i + 1 < len(old_dir):
+                        success_string += ", "
+                print success_string
+
+            d.addCallback(print_success)
+            return d
+        return defer.succeed(True)
+
     def _get_settings(self):
         d = self.settings.start()
         d.addCallback(lambda _: self.settings.get_lbryid())
@@ -229,6 +274,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
         """
 
         def _disp(info):
+            log.debug('[' + str(datetime.now()) + ']' + ' Resolved info: ' + str(info))
             print '[' + str(datetime.now()) + ']' + ' Resolved info: ' + str(info)
             return info
 
@@ -263,6 +309,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
         def _disp():
             try:
                 stream = self.downloads[-1]
+                log.debug('[' + str(datetime.now()) + ']' + ' Downloading: ' + str(stream.stream_hash))
                 print '[' + str(datetime.now()) + ']' + ' Downloading: ' + str(stream.stream_hash)
                 return defer.succeed(None)
             except:
diff --git a/setup.py b/setup.py
index 03a076268..dc7038a3c 100644
--- a/setup.py
+++ b/setup.py
@@ -21,6 +21,7 @@ setup(name='lbrynet',
               'lbrynet-gui = lbrynet.lbrynet_gui.gui:start_gui',
               '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',
           ]
       },
       data_files=[

From a1861a2f84bfcdbb8a9b70cf3e1ed1aad9d2a542 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Mon, 14 Dec 2015 12:59:44 -0500
Subject: [PATCH 20/21] Update lbrynet-daemon

Add auto fetcher to fetch new name claims
---
 lbrynet/core/client/AutoDownloader.py | 130 +++++++++++++++++++++++++-
 lbrynet/lbrynet_daemon/LBRYDaemon.py  |  42 +++++++--
 2 files changed, 161 insertions(+), 11 deletions(-)

diff --git a/lbrynet/core/client/AutoDownloader.py b/lbrynet/core/client/AutoDownloader.py
index 10e06e6cf..939e543bb 100644
--- a/lbrynet/core/client/AutoDownloader.py
+++ b/lbrynet/core/client/AutoDownloader.py
@@ -1,7 +1,7 @@
 import json
 import logging
 import os
-
+from datetime import datetime
 from twisted.internet import defer
 from twisted.internet.task import LoopingCall
 from lbrynet.core.Error import InvalidStreamInfoError, InsufficientFundsError
@@ -145,11 +145,27 @@ class GetStream(object):
             self.description = self.stream_info['description']
             if 'key_fee' in self.stream_info.keys():
                 self.key_fee = float(self.stream_info['key_fee'])
-                self.key_fee_address = self.stream_info['key_fee_address']
+                if 'key_fee_address' in self.stream_info.keys():
+                    self.key_fee_address = self.stream_info['key_fee_address']
+                else:
+                    self.key_fee_address = None
             else:
                 self.key_fee = None
+                self.key_fee_address = None
             self.stream_hash = self.stream_info['stream_hash']
+        elif 'stream_hash' in json.loads(self.stream_info['value']):
+            self.resolved_name = self.stream_info.get('name', None)
+            self.description = json.loads(self.stream_info['value']).get('description', None)
+
+            try:
+                if 'key_fee' in json.loads(self.stream_info['value']):
+                    self.key_fee = float(json.loads(self.stream_info['value'])['key_fee'])
+            except ValueError:
+                self.key_fee = None
+            self.key_fee_address = json.loads(self.stream_info['value']).get('key_fee_address', None)
+            self.stream_hash = json.loads(self.stream_info['value'])['stream_hash']
         else:
+            print 'InvalidStreamInfoError'
             raise InvalidStreamInfoError(self.stream_info)
 
         if self.key_fee > self.max_key_fee:
@@ -212,7 +228,7 @@ class GetStream(object):
 
         def _set_downloader(downloader):
             self.downloader = downloader
-            print os.path.join(self.downloader.download_directory, self.downloader.file_name)
+            print "Downloading", self.stream_hash, " -->", os.path.join(self.downloader.download_directory, self.downloader.file_name)
             return self.downloader
 
         self.downloader = self.factory.make_downloader(self.metadata, [0.5, True], self.payment_rate_manager)
@@ -278,9 +294,9 @@ class AutoFetcher(object):
             transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
             for t in transactions:
                 claims = self.rpc_conn.getclaimsfortx(t['txid'])
-                # uncomment to make it download lbry://yyyy on startup
                 # if self.first_run:
-                #     claims = self.rpc_conn.getclaimsfortx("43a784085949f7bebe5c2a2b74f4e2c6abec36219a5d04d285206b4056ea218b")
+                #     #claims = self.rpc_conn.getclaimsfortx("96aca2c60efded5806b7336430c5987b9092ffbea9c6ed444e3bf8e008993e11")
+                #     claims = self.rpc_conn.getclaimsfortx("cc9c7f5225ecb38877e6ca7574d110b23214ac3556b9d65784065ad3a85b4f74")
                 #     self.first_run = False
                 if claims:
                     for claim in claims:
@@ -330,3 +346,107 @@ class AutoFetcher(object):
             print "maxkey=1.0"
 
         self.max_key_fee = settings["maxkey"]
+
+
+class FetcherDaemon(object):
+    def __init__(self, session, lbry_file_manager, lbry_file_metadata_manager, wallet, sd_identifier, autofetcher_conf):
+        self.autofetcher_conf = autofetcher_conf
+        self.max_key_fee = 0.0
+        self.sd_identifier = sd_identifier
+        self.wallet = wallet
+        self.session = session
+        self.lbry_file_manager = lbry_file_manager
+        self.lbry_metadata_manager = lbry_file_metadata_manager
+        self.seen = []
+        self.lastbestblock = None
+        self.rpc_conn = self.wallet.get_rpc_conn_x()
+        self.search = None
+        self.first_run = True
+        self.is_running = False
+        self._get_autofetcher_conf()
+
+    def start(self):
+        if not self.is_running:
+            self.is_running = True
+            self.search = LoopingCall(self._looped_search)
+            self.search.start(1)
+        else:
+            print "Autofetcher is already running"
+
+    def stop(self):
+        if self.is_running:
+            self.search.stop()
+            self.is_running = False
+        else:
+            print "Autofetcher isn't running, there's nothing to stop"
+
+    def check_if_running(self):
+        if self.is_running:
+            msg = "Autofetcher is running\n"
+            msg += "Last block hash: " + str(self.lastbestblock['bestblockhash'])
+        else:
+            msg = "Autofetcher is not running"
+        return msg
+
+    def _get_names(self):
+        c = self.rpc_conn.getblockchaininfo()
+        rtn = []
+        if self.lastbestblock != c:
+            block = self.rpc_conn.getblock(c['bestblockhash'])
+            txids = block['tx']
+            transactions = [self.rpc_conn.decoderawtransaction(self.rpc_conn.getrawtransaction(t)) for t in txids]
+            for t in transactions:
+                claims = self.rpc_conn.getclaimsfortx(t['txid'])
+                # if self.first_run:
+                #     # claims = self.rpc_conn.getclaimsfortx("96aca2c60efded5806b7336430c5987b9092ffbea9c6ed444e3bf8e008993e11")
+                #     # claims = self.rpc_conn.getclaimsfortx("cc9c7f5225ecb38877e6ca7574d110b23214ac3556b9d65784065ad3a85b4f74")
+                #     self.first_run = False
+                if claims:
+                    for claim in claims:
+                        if claim not in self.seen:
+                            msg = "[" + str(datetime.now()) + "] New claim | lbry://" + str(claim['name']) + \
+                                                    " | stream hash: " + str(json.loads(claim['value'])['stream_hash'])
+                            print msg
+                            log.debug(msg)
+                            rtn.append(claim)
+                            self.seen.append(claim)
+                else:
+                    # self.console.sendLine("No new claims in block #" + str(block['height']))
+                    pass
+
+        self.lastbestblock = c
+
+        if len(rtn):
+            return defer.succeed(rtn)
+
+    def _download_claims(self, claims):
+        if claims:
+            for claim in claims:
+                download = defer.Deferred()
+                stream = GetStream(self.sd_identifier, self.session, self.wallet, self.lbry_file_manager, self.max_key_fee)
+                download.addCallback(lambda _: stream.start(claim))
+                download.callback(None)
+
+        return defer.succeed(None)
+
+    def _looped_search(self):
+        d = defer.Deferred(None)
+        d.addCallback(lambda _: self._get_names())
+        d.addCallback(self._download_claims)
+        d.callback(None)
+
+    def _get_autofetcher_conf(self):
+        settings = {"maxkey": "0.0"}
+        if os.path.exists(self.autofetcher_conf):
+            conf = open(self.autofetcher_conf)
+            for l in conf:
+                if l.startswith("maxkey="):
+                    settings["maxkey"] = float(l[7:].rstrip('\n'))
+        else:
+            print "Autofetcher using default max key price of 0.0"
+            print "To change this create the file:"
+            print str(self.autofetcher_conf)
+            print "Example contents of conf file:"
+            print "maxkey=1.0"
+
+        self.max_key_fee = settings["maxkey"]
\ No newline at end of file
diff --git a/lbrynet/lbrynet_daemon/LBRYDaemon.py b/lbrynet/lbrynet_daemon/LBRYDaemon.py
index 88291d902..543aac02b 100644
--- a/lbrynet/lbrynet_daemon/LBRYDaemon.py
+++ b/lbrynet/lbrynet_daemon/LBRYDaemon.py
@@ -1,7 +1,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.core.client.AutoDownloader import GetStream
+from lbrynet.core.client.AutoDownloader import GetStream, FetcherDaemon
 from lbrynet.core.utils import generate_id
 from lbrynet.lbrynet_console.LBRYSettings import LBRYSettings
 from lbrynet.conf import MIN_BLOB_DATA_PAYMENT_RATE
@@ -27,6 +27,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
 
     def setup(self):
         def _set_vars():
+            self.fetcher = None
             self.current_db_revision = 1
             self.run_server = True
             self.session = None
@@ -67,6 +68,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
             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.autofetcher_conf = os.path.join(self.lbrycrd_dir, "autofetcher.conf")
             self.rpc_conn = None
             self.files = []
             self.created_data_dir = False
@@ -86,10 +88,16 @@ class LBRYDaemon(xmlrpc.XMLRPC):
         d.addCallback(lambda _: self._setup_stream_identifier())
         d.addCallback(lambda _: self._setup_lbry_file_manager())
         d.addCallback(lambda _: self._setup_lbry_file_opener())
+        d.addCallback(lambda _: self._setup_fetcher())
         d.callback(None)
 
         return defer.succeed(None)
 
+    def _setup_fetcher(self):
+        self.fetcher = FetcherDaemon(self.session, self.lbry_file_manager, self.lbry_file_metadata_manager,
+                                     self.session.wallet, self.sd_identifier, self.autofetcher_conf)
+        return defer.succeed(None)
+
     def _setup_data_directory(self):
         print "Loading databases..."
         if self.created_data_dir:
@@ -194,13 +202,9 @@ class LBRYDaemon(xmlrpc.XMLRPC):
             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):
@@ -254,10 +258,36 @@ class LBRYDaemon(xmlrpc.XMLRPC):
         self.sd_identifier.add_stream_downloader_factory(LBRYFileStreamType, downloader_factory)
         return defer.succeed(True)
 
+    def xmlrpc_start_fetcher(self):
+        """
+        Start autofetcher
+        """
+
+        self.fetcher.start()
+
+        return str('Started autofetching')
+
+    def xmlrpc_stop_fetcher(self):
+        """
+        Start autofetcher
+        """
+
+        self.fetcher.stop()
+
+        return str('Started autofetching')
+
+    def xmlrpc_fetcher_status(self):
+        """
+        Start autofetcher
+        """
+
+        return str(self.fetcher.check_if_running())
+
     def xmlrpc_get_balance(self):
         """
         Get LBC balance
         """
+
         return str(self.session.wallet.wallet_balance)
 
     def xmlrpc_stop(self):
@@ -324,7 +354,7 @@ class LBRYDaemon(xmlrpc.XMLRPC):
         # d.addCallback(lambda _: self.files.append({'name': name, 'stream_hash': stream.stream_hash,
         #                  'path': os.path.join(stream.downloader.download_directory, stream.downloader.file_name)}))
         d.addCallback(lambda _: {'ts': datetime.now(),'name': name})
-        d.addErrback(lambda _: 'UnknownNameError')
+        d.addErrback(lambda err: str(err.getTraceback()))
 
         return d
 

From 1abe890067a7cad0b02fb657f56244f71d727083 Mon Sep 17 00:00:00 2001
From: Jack <jack@robisonservice.com>
Date: Mon, 14 Dec 2015 13:14:04 -0500
Subject: [PATCH 21/21] Disable console autofetcher

---
 lbrynet/lbrynet_console/ControlHandlers.py | 88 +++++++++++-----------
 lbrynet/lbrynet_console/LBRYConsole.py     |  6 +-
 2 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py
index 4a5954f9d..77a9562c6 100644
--- a/lbrynet/lbrynet_console/ControlHandlers.py
+++ b/lbrynet/lbrynet_console/ControlHandlers.py
@@ -2362,52 +2362,52 @@ class StatusFactory(CommandHandlerFactory):
                 "to remove the file."
 
 
-class AutoFetcherStart(CommandHandler):
-    def __init__(self, console, autofetcher):
-        CommandHandler.__init__(self, console)
-        self.autofetcher = autofetcher
-
-    def start(self):
-        self.autofetcher.start(self.console)
-        self.finished_deferred.callback(None)
+# class AutoFetcherStart(CommandHandler):
+#     def __init__(self, console, autofetcher):
+#         CommandHandler.__init__(self, console)
+#         self.autofetcher = autofetcher
+#
+#     def start(self):
+#         self.autofetcher.start(self.console)
+#         self.finished_deferred.callback(None)
+#
+#
+# class AutoFetcherStop(CommandHandler):
+#     def __init__(self, console, autofetcher):
+#         CommandHandler.__init__(self, console)
+#         self.autofetcher = autofetcher
+#
+#     def start(self):
+#         self.autofetcher.stop(self.console)
+#         self.finished_deferred.callback(None)
+#
+#
+# class AutoFetcherStatus(CommandHandler):
+#     def __init__(self, console, autofetcher):
+#         CommandHandler.__init__(self, console)
+#         self.autofetcher = autofetcher
+#
+#     def start(self):
+#         self.autofetcher.check_if_running(self.console)
+#         self.finished_deferred.callback(None)
 
 
-class AutoFetcherStop(CommandHandler):
-    def __init__(self, console, autofetcher):
-        CommandHandler.__init__(self, console)
-        self.autofetcher = autofetcher
-
-    def start(self):
-        self.autofetcher.stop(self.console)
-        self.finished_deferred.callback(None)
-
-
-class AutoFetcherStatus(CommandHandler):
-    def __init__(self, console, autofetcher):
-        CommandHandler.__init__(self, console)
-        self.autofetcher = autofetcher
-
-    def start(self):
-        self.autofetcher.check_if_running(self.console)
-        self.finished_deferred.callback(None)
-
-
-class AutoFetcherStartFactory(CommandHandlerFactory):
-    control_handler_class = AutoFetcherStart
-    command = "start-autofetcher"
-    short_help = "Start downloading all lbry files as they are published"
-
-
-class AutoFetcherStopFactory(CommandHandlerFactory):
-    control_handler_class = AutoFetcherStop
-    command = "stop-autofetcher"
-    short_help = "Stop downloading all lbry files as they are published"
-
-
-class AutoFetcherStatusFactory(CommandHandlerFactory):
-    control_handler_class = AutoFetcherStatus
-    command = "autofetcher-status"
-    short_help = "Check autofetcher status"
+# class AutoFetcherStartFactory(CommandHandlerFactory):
+#     control_handler_class = AutoFetcherStart
+#     command = "start-autofetcher"
+#     short_help = "Start downloading all lbry files as they are published"
+#
+#
+# class AutoFetcherStopFactory(CommandHandlerFactory):
+#     control_handler_class = AutoFetcherStop
+#     command = "stop-autofetcher"
+#     short_help = "Stop downloading all lbry files as they are published"
+#
+#
+# class AutoFetcherStatusFactory(CommandHandlerFactory):
+#     control_handler_class = AutoFetcherStatus
+#     command = "autofetcher-status"
+#     short_help = "Check autofetcher status"
 
 
 class BlockchainStatus(CommandHandler):
diff --git a/lbrynet/lbrynet_console/LBRYConsole.py b/lbrynet/lbrynet_console/LBRYConsole.py
index 226716b6e..2d473bcb7 100644
--- a/lbrynet/lbrynet_console/LBRYConsole.py
+++ b/lbrynet/lbrynet_console/LBRYConsole.py
@@ -370,9 +370,9 @@ class LBRYConsole():
             AddStreamFromHashFactory(self.sd_identifier, self.session),
             StatusFactory(self, self.session.rate_limiter, self.lbry_file_manager,
                           self.session.blob_manager, self.session.wallet if self.wallet_type == 'lbrycrd' else None),
-            AutoFetcherStartFactory(self.autofetcher),
-            AutoFetcherStopFactory(self.autofetcher),
-            AutoFetcherStatusFactory(self.autofetcher),
+            # AutoFetcherStartFactory(self.autofetcher),
+            # AutoFetcherStopFactory(self.autofetcher),
+            # AutoFetcherStatusFactory(self.autofetcher),
             ImmediateAnnounceAllBlobsFactory(self.session.blob_manager)
         ]
         self.add_control_handlers(handlers)