Example #1
0
    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
Example #2
0
    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
Example #3
0
    def listen_forever(self, doneflag=None):
        """Main event processing loop for RawServer.
           RawServer listens until the doneFlag is set by some other
           thread.  The doneFlag tells all threads to clean-up and then
           exit."""

        if not doneflag:
            doneflag = DeferredEvent()
        assert isinstance(doneflag, DeferredEvent)
        self.doneflag = doneflag

        if not self.associated:
            self.associate_thread()

        if self.listened:
            Exception(
                _("listen_forever() should only be called once per reactor."))

        if main_thread == thread.get_ident() and not self.sigint_installed:
            self.install_sigint_handler()

        if is_iocpreactor and main_thread == thread.get_ident():

            def pulse():
                self.add_task(1, pulse)

            pulse()

        reactor.callLater(0, self.doneflag.addCallback, self._safestop)
        self.listened = True

        reactor.suggestThreadPoolSize(3)

        if profile:
            self.prof.enable()

        if noSignals:
            reactor.run(installSignalHandlers=False)
        else:
            reactor.run()

        if profile:
            self.prof.disable()
            st = Stats(self.prof.getstats())
            st.sort()
            f = open(prof_file_name, 'wb')
            st.dump(file=f)
Example #4
0
    def __init__(self,
                 config,
                 rawserver,
                 data_dir,
                 listen_fail_ok=False,
                 init_torrents=True,
                 is_single_torrent=False,
                 resume_from_torrent_config=True,
                 bitstring=None):
        """
         @param config: program-wide configuration object.
         @param rawserver: object that manages main event loop and event
           scheduling.
         @param data_dir: where variable data such as fastresume information
           and GUI state is saved.
         @param listen_fail_ok: if false, a BTFailure is raised if
           a server socket cannot be opened to accept incoming peer
           connections.
         @param init_torrents: restore fast resume state from prior
           instantiations of MultiTorrent.
         @param is_single_torrent: if true then allow only one torrent
           at a time in this MultiTorrent.
         @param resume_from_torrent_config: resume from ui_state files.
        """
        # is_single_torrent will go away when we move MultiTorrent into
        # a separate process, in which case, single torrent applications like
        # curses and console will act as a client to the MultiTorrent daemon.
        #   --Dave

        # init_torrents refers to fast resume rather than torrent config.
        # If init_torrents is set to False, the UI state file is still
        # read and the paths to existing downloads still used. This is
        # not what we want for launchmany.
        #
        # resume_from_torrent_config is separate from
        # is_single_torrent because launchmany must be able to have
        # multiple torrents while not resuming from torrent config
        # state.  If launchmany resumes from torrent config then it
        # saves or seeds from the path in the torrent config even if
        # the file has moved in the directory tree.  Because
        # launchmany has no mechanism for removing torrents other than
        # to change the directory tree, the only way for the user to
        # eliminate the old state is to wipe out the files in the
        # .bittorrent/launchmany-*/ui_state directory.  This is highly
        # counterintuitive.  Best to simply ignore the ui_state
        # directory altogether.  --Dave

        assert isinstance(config, Preferences)
        #assert isinstance(data_dir, unicode)  # temporarily commented -Dave
        assert isinstance(listen_fail_ok, bool)
        assert not (is_single_torrent and resume_from_torrent_config)

        self.config = config
        self.data_dir = data_dir
        self.last_save_time = 0
        self.policies = []
        self.torrents = {}
        self.running = {}
        self.log_root = "core.MultiTorrent"
        self.logger = logging.getLogger(self.log_root)
        self.is_single_torrent = is_single_torrent
        self.resume_from_torrent_config = resume_from_torrent_config
        self.auto_update_policy_index = None
        self.dht = None
        self.rawserver = rawserver
        nattraverser = NatTraverser(self.rawserver)
        self.internet_watcher = get_internet_watcher(self.rawserver)
        self.singleport_listener = SingleportListener(
            self.rawserver,
            nattraverser,
            self.log_root,
            # config['use_local_discovery']
            False)
        self.choker = Choker(self.config, self.rawserver.add_task)
        self.up_ratelimiter = RateLimiter(self.rawserver.add_task)
        self.up_ratelimiter.set_parameters(config['max_upload_rate'],
                                           config['upload_unit_size'])
        self.down_ratelimiter = DownloadRateLimiter(
            config['download_rate_limiter_interval'],
            self.config['max_download_rate'])
        self.total_downmeasure = Measure(config['max_rate_period'])

        self._find_port(listen_fail_ok)

        self.filepool_doneflag = DeferredEvent()
        self.filepool = FilePool(self.filepool_doneflag,
                                 self.rawserver.add_task,
                                 self.rawserver.external_add_task,
                                 config['max_files_open'],
                                 config['num_disk_threads'])
        self.bitstring = bitstring

        if self.resume_from_torrent_config:
            try:
                self._restore_state(init_torrents)
            except BTFailure:
                # don't be retarted.
                self.logger.exception("_restore_state failed")

        def no_dump_set_option(option, value):
            self.set_option(option, value, dump=False)

        self.bandwidth_manager = BandwidthManager(
            self.rawserver.external_add_task,
            config,
            no_dump_set_option,
            self.rawserver.get_remote_endpoints,
            get_rates=self.get_total_rates)

        self.rawserver.add_task(0, self.butle)
Example #5
0
    def __init__(self, config, display, configfile_key):
        """Starts torrents for all .torrent files in a directory tree.

         All errors are logged using Python logging to 'configfile_key' logger.

         @param config: Preferences object storing config.
         @param display: output function for stats.
      """

        # 4.4.x version of LaunchMany output exceptions to a displayer.
        # This version only outputs stats to the displayer.  We do not use
        # the logger to output stats so that a caller-provided object
        # can provide stats formatting as opposed to using the
        # logger Formatter, which is specific to exceptions, warnings, and
        # info messages.
        self.logger = logging.getLogger(configfile_key)
        try:
            self.multitorrent = None
            self.rawserver = None
            self.config = config
            self.configfile_key = configfile_key
            self.display = display

            self.torrent_dir = config['torrent_dir']

            # Ex: torrent_cache = infohash -> (path,metainfo)
            self.torrent_cache = {}

            # maps path -> [(modification time, size), infohash]
            self.file_cache = {}

            # used as set containing paths of files that do not have separate
            # entries in torrent_cache either because torrent_cache already
            # contains the torrent or because the torrent file is corrupt.
            self.blocked_files = {}

            #self.torrent_list = []
            #self.downloads = {}

            self.hashcheck_queue = []
            #self.hashcheck_store = {}
            self.hashcheck_current = None

            self.core_doneflag = DeferredEvent()
            self.rawserver = RawServer(self.config)
            try:

                # set up shut-down procedure before we begin doing things that
                # can throw exceptions.
                def shutdown():
                    self.logger.critical(_("shutting down"))
                    if self.multitorrent:
                        if len(self.multitorrent.get_torrents()) > 0:
                            for t in self.multitorrent.get_torrents():
                                self.logger.info(
                                    _('dropped "%s"') %
                                    self.torrent_cache[t.infohash][0])

                        def after_mt(r):
                            self.logger.critical(
                                "multitorrent shutdown completed. Calling rawserver.stop"
                            )
                            self.rawserver.stop()

                        self.logger.critical("calling multitorrent shutdown")
                        df = self.multitorrent.shutdown()
                        #set_flag = lambda *a : self.rawserver.stop()
                        df.addCallbacks(after_mt, after_mt)
                    else:
                        self.rawserver.stop()

                    ### PROFILER POSTPROCESSING.
                    #self.logger.critical( "Disabling profiles" )
                    #prof.disable()
                    #self.logger.critical( "Running profiler post-processing" )
                    #stats = Stats(prof.getstats())
                    #stats.sort("inlinetime")
                    #self.logger.info( "Calling stats.pprint")
                    #stats.pprint()
                    #self.logger.info( "After stats.pprint")
                    ### PROFILER POSTPROCESSING

                # It is safe to addCallback here, because there is only one thread,
                # but even if the code were multi-threaded, core_doneflag has not
                # been passed to anyone.  There is no chance of a race condition
                # between the DeferredEvent's callback and addCallback.
                self.core_doneflag.addCallback(
                    lambda r: self.rawserver.external_add_task(0, shutdown))

                self.rawserver.install_sigint_handler(self.core_doneflag)

                data_dir = config['data_dir']
                self.multitorrent = MultiTorrent(
                    config,
                    self.rawserver,
                    data_dir,
                    resume_from_torrent_config=False)

                # first time sleep_time is 0 so that it will startup fast.  On
                # subsequent scans, the scan is slowed down to not affect performance.
                self.rawserver.add_task(0, self.scan, sleep_time=0)
                self.rawserver.add_task(0.5,
                                        self.periodic_check_hashcheck_queue)
                self.rawserver.add_task(self.config['display_interval'],
                                        self.periodic_stats)

                try:
                    import signal

                    def handler(signum, frame):
                        self.rawserver.external_add_task(0, self.read_config)

                    if hasattr(signal, 'SIGHUP'):
                        signal.signal(signal.SIGHUP, handler)
                except Exception, e:
                    self.logger.error(
                        _("Could not set signal handler: ") + str_exc(e))
                    self.rawserver.add_task(0, self.core_doneflag.set)

            except UserFailure, e:
                self.logger.error(str_exc(e))
                self.rawserver.add_task(0, self.core_doneflag.set)
            except:
                #data = StringIO()
                #print_exc(file = data)
                #self.logger.error(data.getvalue())
                self.logger.exception(
                    "Exception raised while initializing LaunchMany")
                self.rawserver.add_task(0, self.core_doneflag.set)

            # always make sure events get processed even if only for
            # shutting down.
            self.rawserver.listen_forever()
            self.logger.info("After rawserver.listen_forever")
    def __init__(self, config, display, configfile_key):
      """Starts torrents for all .torrent files in a directory tree.

         All errors are logged using Python logging to 'configfile_key' logger.

         @param config: Preferences object storing config.
         @param display: output function for stats.
      """

      # 4.4.x version of LaunchMany output exceptions to a displayer.
      # This version only outputs stats to the displayer.  We do not use
      # the logger to output stats so that a caller-provided object
      # can provide stats formatting as opposed to using the
      # logger Formatter, which is specific to exceptions, warnings, and
      # info messages.
      self.logger = logging.getLogger(configfile_key)
      try:
        self.multitorrent = None
        self.rawserver = None
        self.config = config
        self.configfile_key = configfile_key
        self.display = display

        self.torrent_dir = config['torrent_dir']

        # Ex: torrent_cache = infohash -> (path,metainfo)
        self.torrent_cache = {}

        # maps path -> [(modification time, size), infohash]
        self.file_cache = {}

        # used as set containing paths of files that do not have separate
        # entries in torrent_cache either because torrent_cache already
        # contains the torrent or because the torrent file is corrupt.
        self.blocked_files = {}

        #self.torrent_list = [] 
        #self.downloads = {}

        self.hashcheck_queue = []
        #self.hashcheck_store = {}
        self.hashcheck_current = None
                         
        self.core_doneflag = DeferredEvent()
        self.rawserver = RawServer(self.config)
        try:
   
            # set up shut-down procedure before we begin doing things that
            # can throw exceptions.
            def shutdown():
                self.logger.critical(_("shutting down"))
                for t in self.multitorrent.get_torrents():
                    self.logger.info(_('dropped "%s"') %
                                    self.torrent_cache[t.infohash][0])
                if self.multitorrent:
                    df = self.multitorrent.shutdown()
                    set_flag = lambda *a : self.rawserver.stop()
                    df.addCallbacks(set_flag, set_flag)
                else:
                    self.rawserver.stop()
                
            # It is safe to addCallback here, because there is only one thread,
            # but even if the code were multi-threaded, core_doneflag has not
            # been passed to anyone.  There is no chance of a race condition
            # between the DeferredEvent's callback and addCallback.
            self.core_doneflag.addCallback(
                lambda r: self.rawserver.external_add_task(0, shutdown))

            self.rawserver.install_sigint_handler(self.core_doneflag)
    
            data_dir = config['data_dir']
            self.multitorrent = MultiTorrent(config, self.rawserver, data_dir,
                                             resume_from_torrent_config=False)
    
            self.rawserver.add_task(0, self.scan)
            self.rawserver.add_task(0.5, self.periodic_check_hashcheck_queue)
            self.rawserver.add_task(self.config['display_interval'],
                                    self.periodic_stats)
            
            try:
                import signal
                def handler(signum, frame):
                    self.rawserver.external_add_task(0, self.read_config)
                signal.signal(signal.SIGHUP, handler)
            except Exception, e:
                self.logger.error(_("Could not set signal handler: ") +
                                    str_exc(e))
                self.rawserver.add_task(0,self.core_doneflag.set())
  
        except UserFailure, e:
            self.logger.error(str_exc(e))
            self.rawserver.add_task(0,self.core_doneflag.set())
        except:
            data = StringIO()
            print_exc(file = data)
            self.logger.error(data.getvalue())
            self.rawserver.add_task(0,self.core_doneflag.set())
           
        # always make sure events get processed even if only for
        # shutting down.
        self.rawserver.listen_forever()
def message_dump(data):
    print "Received: ", data.encode("hex")


def shutdown():
    print "shutdown."
    rawserver.stop()


if __name__ == "__main__":
    print "test2"
    sys.stdout.flush()
    uiname = "bittorrent-console"
    defaults = get_defaults(uiname)
    config, args = configfile.parse_configuration_and_args(
        defaults, uiname, sys.argv[1:], 0, 1)

    core_doneflag = DeferredEvent()
    rawserver = RawServer(config)
    core_doneflag.addCallback(
        lambda r: rawserver.external_add_task(0, shutdown))
    rawserver.install_sigint_handler(core_doneflag)

    print "Creating IcmpIPC"
    icmp = IcmpIPC(rawserver)
    icmp.create()
    print "Starting IcmpIPC"
    icmp.start(message_dump)
    rawserver.listen_forever()
Example #8
0

def message_dump(data):
    print "Received: ", data.encode("hex")

def shutdown():
    print "shutdown."
    rawserver.stop()

if __name__ == "__main__":
    print "test2"
    sys.stdout.flush()
    uiname = "bittorrent-console"
    defaults = get_defaults(uiname)
    config, args = configfile.parse_configuration_and_args(defaults,
                                       uiname, sys.argv[1:], 0, 1)
    
    core_doneflag = DeferredEvent()
    rawserver = RawServer(config)
    core_doneflag.addCallback(
            lambda r: rawserver.external_add_task(0, shutdown))
    rawserver.install_sigint_handler(core_doneflag)

    print "Creating IcmpIPC"
    icmp = IcmpIPC(rawserver)
    icmp.create()
    print "Starting IcmpIPC"
    icmp.start(message_dump)
    rawserver.listen_forever()
    
Example #9
0
        psyco.bind(PiecePicker.PieceBuckets)
        psyco.bind(PiecePicker.PiecePicker)
        from BitTorrent import PieceSetBuckets
        psyco.bind(PieceSetBuckets.PieceSetBuckets)
        psyco.bind(PieceSetBuckets.SortedPieceBuckets)
        from BTL import bitfield
        psyco.bind(bitfield.Bitfield)
    except ImportError:
        pass

    #import memleak_detection
    #memleak_detection.begin_sampling('memleak_sample.log')

    config['start_time'] = time.time()

    core_doneflag = DeferredEvent()

    ms = []
    try:
        print args
        for i in xrange(NUM_PEERS):
            multitorrent = create_multitorrent(config, rawserver, i)
            multitorrent._id = i
            ms.append(multitorrent)
            for t in args:
                p = multitorrent.config['data_dir']
                p = os.path.join(p, '%s.dat' % i)
                multitorrent.create_torrent_non_suck(efs2(t), efs2(p))

        task.LoopingCall(print_status, ms).start(5)
Example #10
0
        psyco.bind(PiecePicker.PieceBuckets)
        psyco.bind(PiecePicker.PiecePicker)
        from BitTorrent import PieceSetBuckets
        psyco.bind(PieceSetBuckets.PieceSetBuckets)
        psyco.bind(PieceSetBuckets.SortedPieceBuckets)
        from BTL import bitfield
        psyco.bind(bitfield.Bitfield)
    except ImportError:
        pass

    #import memleak_detection
    #memleak_detection.begin_sampling('memleak_sample.log')

    config['start_time'] = time.time()

    core_doneflag = DeferredEvent()

    ms = []
    try:
        print args
        for i in xrange(NUM_PEERS):
            multitorrent = create_multitorrent(config, rawserver, i)
            multitorrent._id = i
            ms.append(multitorrent)
            for t in args:
                p = multitorrent.config['data_dir']
                p = os.path.join(p, '%s.dat' % i)
                multitorrent.create_torrent_non_suck(efs2(t), efs2(p))

        task.LoopingCall(print_status, ms).start(5)