def init_core(mainloop): core_doneflag = DeferredEvent() class UILogger(logging.Handler): def emit(self, record): msg = "[%s] %s" % (record.name, self.format(record)) gui_wrap(mainloop.do_log, record.levelno, msg) logging.getLogger('').addHandler(UILogger()) try: multitorrent = MultiTorrent(config, rawserver, config['data_dir'], listen_fail_ok=True, init_torrents=False) # Butlers multitorrent.add_policy(DownloadTorrentButler(multitorrent)) multitorrent.add_policy(SeedTorrentButler(multitorrent)) auto_update_butler = AutoUpdateButler(multitorrent, rawserver, test_new_version=config['new_version'], test_current_version=config['current_version']) multitorrent.add_auto_update_policy(auto_update_butler) # attach to the UI tpm = ThreadProxy(multitorrent, gui_wrap, wrap_task(rawserver.external_add_task)) mainloop.attach_multitorrent(tpm, core_doneflag) ipc.start(mainloop.external_command) #rawserver.associate_thread() # register shutdown action def shutdown(): df = multitorrent.shutdown() stop_rawserver = lambda r : rawserver.stop() df.addCallbacks(stop_rawserver, stop_rawserver) rawserver.add_task(0, core_doneflag.addCallback, lambda r: rawserver.external_add_task(0, shutdown)) rawserver.listen_forever() except: # oops, we failed. # one message for the log w/ exception info global_logger.exception("BitTorrent core initialization failed!") # one message for the user w/o info global_logger.critical("BitTorrent core initialization failed!") core_doneflag.set() rawserver.stop() try: gui_wrap(mainloop.ExitMainLoop) except: pass try: gui_wrap(mainloop.doneflag.set) except: pass raise
def shutdown(self): self.logger.debug("multitorrent shutting down") print "shutting down" df = launch_coroutine(wrap_task(self.rawserver.add_task), self._shutdown) df.addErrback(lambda f : self.logger.error('shutdown failed!', exc_info=f.exc_info())) return df
def _check_version(self): """Actually check for an auto-update: 1. Check the version number from the file on the version site. 2. Check the stable version number from the file on the version site. 3. Notify the user and stop if they are on an OS with no installer. 4. Get the torrent file from the version site. 5. Get the signature from the version site. 6. Check the signature against the torrent file using the public key. 7a. Start the torrent if it's not in the client. 7b. Restart the torrent if it's in the client but not running. 8. Put the infohash of the torrent into estate so the butler knows to butle it. 9. AutoUpdateButler.started() ensures that only the most recent auto-update torrent is running. 10. AutoUpdateButler.finished() indicates the new version is available, the UI polls for that value later. Whether an auto-update was found and started or not, requeue the call to check_version() to run a day later. This means that the version check runs at startup, and once a day. """ debug_prefix = '_check_version() run#%d: '%self.runs self.debug(debug_prefix + 'starting') url = self.version_site + self.current_version.name() df = ThreadedDeferred(wrap_task(self.rawserver.external_add_task), self._get_available, url, daemon=True) yield df try: available_version = df.getResult() except BTFailure, e: self.debug(debug_prefix + 'failed to load %s' % url) self._restart() return
def coro(f, *args, **kwargs): global warned if not warned: warnings.warn("This module should not depend on the reactor.\n" "Put this convenience function somewhere else.") warned = True return launch_coroutine(wrap_task(reactor.callLater), f, *args, **kwargs)
def check_version(self): """Launch the actual version check code in a coroutine since it needs to make three (or four, in beta) http requests, one disk read, and one decryption.""" df = launch_coroutine(wrap_task(self.rawserver.external_add_task), self._check_version) def errback(e): self.logger.error('check_version() run #%d: ' % self.runs, exc_info=e.exc_info()) df.addErrback(errback)
def run_gen(): def gen(): global a for i in xrange(m): df = Deferred() #rawserver.add_task(0, df.callback, lambda r: r) df.callback(1) yield df df.getResult() a[i] = time.clock() mdf = launch_coroutine(wrap_task(rawserver.add_task), gen) def done(r=None): print 'yielddefer\t', len(a), a[-1] - a[0], '\t', avg_dist(a) i = 0 if stackless: print 'stackless' run_gen2() else: run_gen3() mdf.addCallback(done)
def initialize(self, save_path, files): # a list of bytes ranges and filenames for window-based IO self.ranges = [] # a dict of filename-to-ranges for piece priorities and filename lookup self.range_by_name = {} # a sparse set for smart allocation detection self.allocated_regions = SparseSet() # dict of filename-to-length on disk (for % complete in the file view) self.undownloaded = {} self.save_path = save_path # Rather implement this as an ugly hack here than change all the # individual calls. Affects all torrent instances using this module. if self.config['bad_libc_workaround']: bad_libc_workaround() self.initialized = False self.startup_df = ThreadedDeferred(wrap_task(self.external_add_task), self._build_file_structs, self.filepool, files) return self.startup_df
def _check_version(self): """Actually check for an auto-update: 1. Check the version number from the file on the version site. 2. Check the stable version number from the file on the version site. 3. Notify the user and stop if they are on an OS with no installer. 4. Get the torrent file from the version site. 5. Get the signature from the version site. 6. Check the signature against the torrent file using the public key. 7a. Start the torrent if it's not in the client. 7b. Restart the torrent if it's in the client but not running. 8. Put the infohash of the torrent into estate so the butler knows to butle it. 9. AutoUpdateButler.started() ensures that only the most recent auto-update torrent is running. 10. AutoUpdateButler.finished() indicates the new version is available, the UI polls for that value later. Whether an auto-update was found and started or not, requeue the call to check_version() to run a day later. This means that the version check runs at startup, and once a day. """ debug_prefix = '_check_version() run#%d: ' % self.runs self.debug(debug_prefix + 'starting') url = self.version_site + self.current_version.name() df = ThreadedDeferred(wrap_task(self.rawserver.external_add_task), self._get_available, url, daemon=True) yield df try: available_version = df.getResult() except BTFailure, e: self.debug(debug_prefix + 'failed to load %s' % url) self._restart() return
def initialize_torrents(self): df = launch_coroutine(wrap_task(self.rawserver.add_task), self._initialize_torrents) df.addErrback(lambda f: self.logger.error( 'initialize_torrents failed!', exc_info=f.exc_info())) return df
def shutdown(self): df = launch_coroutine(wrap_task(self.rawserver.add_task), self._shutdown) df.addErrback(lambda f: self.logger.error('shutdown failed!', exc_info=f.exc_info())) return df
def _thread_proxy(self, obj): return ThreadProxy(obj, self.gui_wrap, wrap_task(self.rawserver.external_add_task))
def initialize_torrents(self): df = launch_coroutine(wrap_task(self.rawserver.add_task), self._initialize_torrents) df.addErrback(lambda f : self.logger.error('initialize_torrents failed!', exc_info=f.exc_info())) return df
def shutdown(self): df = launch_coroutine(wrap_task(self.rawserver.add_task), self._shutdown) df.addErrback(lambda f : self.logger.error('shutdown failed!', exc_info=f.exc_info())) return df
def read(self, pos, amount): df = launch_coroutine(wrap_task(self.add_task), self._batch_read, pos, amount) return df
def periodic_stats(self): df = ThreadedDeferred(wrap_task(self.rawserver.external_add_task), self.stats, daemon = True) df.addCallback(lambda r : self.rawserver.add_task(self.config['display_interval'], self.periodic_stats))
def coro(f, *args, **kwargs): return launch_coroutine(wrap_task(reactor.callLater), f, *args, **kwargs)
def periodic_stats(self): df = ThreadedDeferred(wrap_task(self.rawserver.external_add_task), self.stats, daemon=True) df.addCallback(self.rawserver.add_task, self.periodic_stats, self.config['display_interval'], self.periodic_stats)
url, daemon=True) yield df try: available_version = df.getResult() except BTFailure, e: self.debug(debug_prefix + 'failed to load %s' % url) self._restart() return if available_version.is_beta(): if available_version[1] != self.current_version[1]: available_version = self.current_version if self.current_version.is_beta(): stable_url = self.version_site + 'stable' df = ThreadedDeferred(wrap_task(self.rawserver.external_add_task), self._get_available, stable_url) yield df try: available_stable_version = df.getResult() except BTFailure, e: self.debug(debug_prefix + 'failed to load %s' % url) self._restart() return if available_stable_version > available_version: available_version = available_stable_version self.debug(debug_prefix + 'got %s' % str(available_version)) if available_version <= self.current_version: self.debug(debug_prefix +
def write(self, pos, s): df = launch_coroutine(wrap_task(self.add_task), self._batch_write, pos, s) return df
df = ThreadedDeferred(wrap_task(self.rawserver.external_add_task), self._get_available, url, daemon=True) yield df try: available_version = df.getResult() except BTFailure, e: self.debug(debug_prefix + 'failed to load %s' % url) self._restart() return if available_version.is_beta(): if available_version[1] != self.current_version[1]: available_version = self.current_version if self.current_version.is_beta(): stable_url = self.version_site + 'stable' df = ThreadedDeferred(wrap_task(self.rawserver.external_add_task), self._get_available, stable_url) yield df try: available_stable_version = df.getResult() except BTFailure, e: self.debug(debug_prefix + 'failed to load %s' % url) self._restart() return if available_stable_version > available_version: available_version = available_stable_version self.debug(debug_prefix + 'got %s' % str(available_version)) if available_version <= self.current_version:
def replacement(*a, **kw): return launch_coroutine(wrap_task(reactor.callLater), _f, *a, **kw)