URI: 
       tGenericize plugin handling of thread jobs - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 1171a25815448093d9ea81c9788337b11d7a113a
   DIR parent 24cd18e193c9f5198643363193dd1a635e1185ad
  HTML Author: Neil Booth <kyuupichan@gmail.com>
       Date:   Sat,  5 Sep 2015 17:18:09 +0900
       
       Genericize plugin handling of thread jobs
       
       Move it to the Plugins class so all plugins get it for
       free.
       
       Diffstat:
         M lib/plugins.py                      |      29 ++++++++++++++++++++++-------
         M lib/util.py                         |       9 +++++----
         M lib/wallet.py                       |       6 ++----
         M plugins/exchange_rate.py            |      14 +++-----------
       
       4 files changed, 32 insertions(+), 26 deletions(-)
       ---
   DIR diff --git a/lib/plugins.py b/lib/plugins.py
       t@@ -26,6 +26,13 @@ from util import *
        from i18n import _
        from util import print_error, profiler
        
       +hook_names = set()
       +hooks = {}
       +
       +def hook(func):
       +    hook_names.add(func.func_name)
       +    return func
       +
        class Plugins:
        
            @profiler
       t@@ -40,6 +47,7 @@ class Plugins:
        
                self.plugins = {}
                self.windows = []
       +        self.network = None
                self.descriptions = plugins.descriptions
                for item in self.descriptions:
                    name = item['name']
       t@@ -118,6 +126,17 @@ class Plugins:
                x += (lambda: self.wallet_plugin_loader(config, name),)
                wallet.wallet_types.append(x)
        
       +    @hook
       +    def set_network(self, network):
       +        if network != self.network:
       +            jobs = [job in plugin.thread_jobs()
       +                    for plugin in self.plugins.values()]
       +            if self.network:
       +                self.network.remove_jobs(jobs)
       +            self.network = network
       +            if network:
       +                network.add_jobs(jobs)
       +
            def trigger(self, event, *args, **kwargs):
                for plugin in self.plugins.values():
                    getattr(plugin, event)(*args, **kwargs)
       t@@ -130,13 +149,6 @@ class Plugins:
                self.windows.remove(window)
                self.trigger('on_close_window', window)
        
       -hook_names = set()
       -hooks = {}
       -
       -def hook(func):
       -    hook_names.add(func.func_name)
       -    return func
       -
        def run_hook(name, *args):
            return _run_hook(name, False, *args)
        
       t@@ -194,6 +206,9 @@ class BasePlugin:
            def requires_settings(self):
                return False
        
       +    def thread_jobs(self):
       +        return []
       +
            @hook
            def load_wallet(self, wallet, window): pass
        
   DIR diff --git a/lib/util.py b/lib/util.py
       t@@ -51,9 +51,9 @@ class DaemonThread(threading.Thread):
                self.job_lock = threading.Lock()
                self.jobs = []
        
       -    def add_job(self, job):
       +    def add_jobs(self, jobs):
                with self.job_lock:
       -            self.jobs.append(job)
       +            self.jobs.extend(jobs)
        
            def run_jobs(self):
                # Don't let a throwing job disrupt the thread, future runs of
       t@@ -66,9 +66,10 @@ class DaemonThread(threading.Thread):
                        except:
                            traceback.print_exc(file=sys.stderr)
        
       -    def remove_job(self, job):
       +    def remove_jobs(self, jobs):
                with self.job_lock:
       -            self.jobs.remove(job)
       +            for job in jobs:
       +                self.jobs.remove(job)
        
            def start(self):
                with self.running_lock:
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -1109,17 +1109,15 @@ class Abstract_Wallet(object):
                if self.network is not None:
                    self.prepare_for_verifier()
                    self.verifier = SPV(self.network, self)
       -            network.add_job(self.verifier)
                    self.synchronizer = Synchronizer(self, network)
       -            network.add_job(self.synchronizer)
       +            network.add_jobs([self.verifier, self.synchronizer])
                else:
                    self.verifier = None
                    self.synchronizer = None
        
            def stop_threads(self):
                if self.network:
       -            self.network.remove_job(self.synchronizer)
       -            self.network.remove_job(self.verifier)
       +            self.network.remove_jobs([self.synchronizer, self.verifier])
                    self.synchronizer = None
                    self.verifier = None
                    self.storage.put('stored_height', self.get_local_height(), True)
   DIR diff --git a/plugins/exchange_rate.py b/plugins/exchange_rate.py
       t@@ -193,13 +193,15 @@ class Plugin(BasePlugin, ThreadJob):
                                           and issubclass(obj, ExchangeBase))
                self.exchanges = dict(inspect.getmembers(sys.modules[__name__],
                                                         is_exchange))
       -        self.network = None
                self.set_exchange(self.config_exchange())
                self.currencies = [self.fiat_unit()]
                self.btc_rate = Decimal("0.0")
                self.get_historical_rates()
                self.timeout = 0
        
       +    def thread_jobs(self):
       +        return [self]
       +
            def run(self):
                # This runs from the network thread which catches exceptions
                if self.parent.windows and self.timeout <= time.time():
       t@@ -222,15 +224,6 @@ class Plugin(BasePlugin, ThreadJob):
                    self.config.set_key('use_exchange', name, True)
                self.exchange = class_()
        
       -    @hook
       -    def set_network(self, network):
       -        if network != self.network:
       -            if self.network:
       -                self.network.remove_job(self)
       -            self.network = network
       -            if network:
       -                network.add_job(self)
       -
            def on_new_window(self, window):
                window.connect(window, SIGNAL("refresh_currencies()"),
                               window.update_status)
       t@@ -241,7 +234,6 @@ class Plugin(BasePlugin, ThreadJob):
        
            def close(self):
                BasePlugin.close(self)
       -        self.set_network(None)
                for window in self.parent.windows:
                    window.send_fiat_e.hide()
                    window.receive_fiat_e.hide()