Beispiel #1
0
    def run(self, scrwin):
        def reread():
            self.multitorrent.rawserver.external_add_task(
                self.reread_config, 0)

        self.d = CursesDisplayer(scrwin, self.errlist, self.doneflag, reread)
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if config['save_as']:
                if config['save_in']:
                    raise BTFailure('You cannot specify both --save_as and '
                                    '--save_in')
                saveas = config['save_as']
            elif config['save_in']:
                saveas = os.path.join(config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                      metainfo.total_bytes,
                                      len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(
                metainfo, self.config, self, saveas)
        except BTFailure, e:
            errlist.append(str(e))
            return
Beispiel #2
0
    def run(self):
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if self.config['save_as']:
                if self.config['save_in']:
                    raise BTFailure(
                        _("You cannot specify both --save_as and "
                          "--save_in"))
                saveas = self.config['save_as']
            elif self.config['save_in']:
                saveas = os.path.join(self.config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                      metainfo.total_bytes,
                                      len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(
                metainfo, Preferences(self.config), self, saveas)
        except BTFailure, e:
            print str(e)
            return
Beispiel #3
0
        def run(self):
            import os

            try:
                config = self.config
                self.d = HeadlessDisplayer(self.doneflag)
                self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error)
                # raises BTFailure if bad
                metainfo = ConvertedMetainfo(bdecode(self.metainfo))
                torrent_name = metainfo.name_fs

                if config["save_as"]:
                    if config["save_in"]:
                        raise BTFailure("You cannot specify both --save_as and " "--save_in")
                    saveas = config["save_as"]
                elif config["save_in"]:
                    saveas = os.path.join(config["save_in"], torrent_name)
                else:
                    saveas = torrent_namef

                self.d.set_torrent_values(
                    metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes)
                )
                self.torrent = self.multitorrent.start_torrent(metainfo, self.config, self, saveas)
            except BTFailure, e:
                globals()["torrentStatus"] = 0
                logIt(str(e))
                return
    def run(self, scrwin):
        def reread():
            self.multitorrent.rawserver.external_add_task(self.reread_config,0)
        def ulrate(value):
            self.multitorrent.set_option('max_upload_rate', value)
            self.torrent.set_option('max_upload_rate', value)

        self.d = CursesDisplayer(scrwin, self.errlist, self.doneflag, reread, ulrate)
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if config['save_as']:
                if config['save_in']:
                    raise BTFailure(_("You cannot specify both --save_as and "
                                      "--save_in"))
                saveas = config['save_as']
            elif config['save_in']:
                saveas = os.path.join(config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                metainfo.total_bytes, len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(metainfo,
                                Preferences(self.config), self, saveas)
        except BTFailure, e:
            errlist.append(str(e))
            return
Beispiel #5
0
    def run(self):
        self.d = HeadlessDisplayer(self.doneflag)
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if config['save_as']:
                if config['save_in']:
                    raise BTFailure('You cannot specify both --save_as and '
                                    '--save_in')
                saveas = config['save_as']
            elif config['save_in']:
                saveas = os.path.join(config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                metainfo.total_bytes, len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(metainfo,
                                self.config, self, saveas)
        except BTFailure, e:
            print str(e)
            return
	def __init__(self, config, display):
		super(BTControl, self).__init__()
		self.config = config
		self.display = display
		self.doneFlag = threading.Event()
		self.multitorrent = Multitorrent(self.config, self.doneFlag, self.error)
		self.rawServer = self.multitorrent.rawserver
		self.torrentInfo = {}
		self.sharingTorrents = {}
		# Add initial tasks to rawServer:
		self.updateDisplay()
Beispiel #7
0
 def run(self, ui, ui_wrap, startflag):
     self.ui = ui
     self.run_ui_task = ui_wrap
     self.multitorrent = Multitorrent(self.config, self.doneflag,
                                     self.global_error, listen_fail_ok=True)
     self.rawserver = self.multitorrent.rawserver
     self.controlsocket.set_rawserver(self.rawserver)
     self.controlsocket.start_listening(self.external_command)
     try:
         self._restore_state()
     except BTFailure, e:
         self.queue = []
         self.other_torrents = []
         self.torrents = {}
         self.global_error(ERROR, "Could not load saved state: "+str(e))
Beispiel #8
0
class DL(Feedback):
    def __init__(self, metainfo, config, errlist):
        self.doneflag = threading.Event()
        self.metainfo = metainfo
        self.config = Preferences().initWithDict(config)
        self.errlist = errlist

    def run(self, scrwin):
        def reread():
            self.multitorrent.rawserver.external_add_task(
                self.reread_config, 0)

        def ulrate(value):
            self.multitorrent.set_option('max_upload_rate', value)
            self.torrent.set_option('max_upload_rate', value)

        self.d = CursesDisplayer(scrwin, self.errlist, self.doneflag, reread,
                                 ulrate)
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if config['save_as']:
                if config['save_in']:
                    raise BTFailure(
                        _("You cannot specify both --save_as and "
                          "--save_in"))
                saveas = config['save_as']
            elif config['save_in']:
                saveas = os.path.join(config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                      metainfo.total_bytes,
                                      len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(
                metainfo, Preferences(self.config), self, saveas)
        except BTFailure, e:
            errlist.append(str(e))
            return
        self.get_status()
        self.multitorrent.rawserver.install_sigint_handler()
        self.multitorrent.rawserver.listen_forever()
        self.d.display({'activity': _("shutting down"), 'fractionDone': 0})
        self.torrent.shutdown()
Beispiel #9
0
        def run(self):
            self.d = HeadlessDisplayer(self.doneflag)
            try:
                self.multitorrent = Multitorrent(self.config, self.doneflag,
                                                 self.global_error)
                # raises BTFailure if bad
                metainfo = ConvertedMetainfo(bdecode(self.metainfo))
                torrent_name = metainfo.name_fs
                saveas = os.path.join(self.config['save_in'], torrent_name)

                self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                    metainfo.total_bytes, len(metainfo.hashes))
                self.torrent = self.multitorrent.start_torrent(metainfo,
                                    Preferences(self.config), self, saveas)
            except BTFailure, e:
                self.log.exception("Problem running torrent")
                return
Beispiel #10
0
    def __init__(self, config, output, configfile_key):
        try:
            self.config = config
            self.output = output
            self.configfile_key = configfile_key

            self.torrent_dir = config['torrent_dir']
            self.torrent_cache = {}
            self.file_cache = {}
            self.blocked_files = {}

            self.torrent_list = []
            self.downloads = {}
            self.doneflag = Event()

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

            self.multitorrent = Multitorrent(config, self.doneflag,
                                             self.global_error)
            self.rawserver = self.multitorrent.rawserver

            self.rawserver.add_task(self.scan, 0)
            self.rawserver.add_task(self.stats, 0)

            try:
                import signal

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

                signal.signal(signal.SIGHUP, handler)
            except Exception, e:
                self.output.message('Could not set signal handler: ' + str(e))

            self.rawserver.listen_forever()

            self.output.message('shutting down')
            for infohash in self.torrent_list:
                self.output.message('dropped "' +
                                    self.torrent_cache[infohash]['path'] + '"')
                torrent = self.downloads[infohash]
                if torrent is not None:
                    torrent.shutdown()
Beispiel #11
0
    class DL(Feedback):
        def __init__(self, metainfo, config):

            self.doneflag = threading.Event()
            self.metainfo = metainfo
            self.config = config

            logIt("BT url: %s" % self.config["url"])
            logIt("BT save_as: %s" % self.config["save_as"])
            if self.config["max_upload_rate"] > 0:
                logIt("BT max_upload_rate: %s" % str(self.config["max_upload_rate"]))

        def run(self):
            import os

            try:
                config = self.config
                self.d = HeadlessDisplayer(self.doneflag)
                self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error)
                # raises BTFailure if bad
                metainfo = ConvertedMetainfo(bdecode(self.metainfo))
                torrent_name = metainfo.name_fs

                if config["save_as"]:
                    if config["save_in"]:
                        raise BTFailure("You cannot specify both --save_as and " "--save_in")
                    saveas = config["save_as"]
                elif config["save_in"]:
                    saveas = os.path.join(config["save_in"], torrent_name)
                else:
                    saveas = torrent_namef

                self.d.set_torrent_values(
                    metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes)
                )
                self.torrent = self.multitorrent.start_torrent(metainfo, self.config, self, saveas)
            except BTFailure, e:
                globals()["torrentStatus"] = 0
                logIt(str(e))
                return
            self.get_status()
            self.multitorrent.rawserver.listen_forever()
            self.d.display({"activity": "shutting down", "fractionDone": 0})
            self.torrent.shutdown()
class DL(Feedback):

    def __init__(self, metainfo, config, errlist):
        self.doneflag = threading.Event()
        self.metainfo = metainfo
        self.config = Preferences().initWithDict(config)
        self.errlist = errlist

    def run(self, scrwin):
        def reread():
            self.multitorrent.rawserver.external_add_task(self.reread_config,0)
        def ulrate(value):
            self.multitorrent.set_option('max_upload_rate', value)
            self.torrent.set_option('max_upload_rate', value)

        self.d = CursesDisplayer(scrwin, self.errlist, self.doneflag, reread, ulrate)
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if config['save_as']:
                if config['save_in']:
                    raise BTFailure(_("You cannot specify both --save_as and "
                                      "--save_in"))
                saveas = config['save_as']
            elif config['save_in']:
                saveas = os.path.join(config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                metainfo.total_bytes, len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(metainfo,
                                Preferences(self.config), self, saveas)
        except BTFailure, e:
            errlist.append(str(e))
            return
        self.get_status()
        self.multitorrent.rawserver.install_sigint_handler()
        self.multitorrent.rawserver.listen_forever()
        self.d.display({'activity':_("shutting down"), 'fractionDone':0})
        self.torrent.shutdown()
Beispiel #13
0
    class DL(Feedback):

        def __init__(self, metainfo, config):
            self.log      = logging.getLogger("%s"%self.__class__.__name__)
            self.doneflag = threading.Event()
            self.metainfo = metainfo
            self.config   = Preferences().initWithDict(config)
            self.started_downloading = False

        def run(self):
            self.d = HeadlessDisplayer(self.doneflag)
            try:
                self.multitorrent = Multitorrent(self.config, self.doneflag,
                                                 self.global_error)
                # raises BTFailure if bad
                metainfo = ConvertedMetainfo(bdecode(self.metainfo))
                torrent_name = metainfo.name_fs
                saveas = os.path.join(self.config['save_in'], torrent_name)

                self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                    metainfo.total_bytes, len(metainfo.hashes))
                self.torrent = self.multitorrent.start_torrent(metainfo,
                                    Preferences(self.config), self, saveas)
            except BTFailure, e:
                self.log.exception("Problem running torrent")
                return

            self.get_status()
            #self.multitorrent.rawserver.install_sigint_handler()
            #self.multitorrent.rawserver.listen_forever()
            start_time = time()
            ret = 0
            rsvr = self.multitorrent.rawserver
            while not rsvr.doneflag.isSet() and not ret:
                ret = rsvr.listen_once()
                if not self.started_downloading and \
                        (time()-start_time) > self.config['max_startup_wait']:
                    self.log.info("Torrent took too long to start downloading")
                    break

            self.d.display({'activity':_("shutting down"), 'fractionDone':0})
            self.torrent.shutdown()
Beispiel #14
0
class DLKamaelia(Feedback):
    """This class accepts feedback from the multitorrent downloader class
    which it can then pass back to the inboxes of TorrentClient"""
    def __init__(self, metainfo, config, interface):
        self.doneflag = threading.Event()
        self.metainfo = metainfo
        self.config = Preferences().initWithDict(config)
        self.d = interface

    def run(self):
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if self.config['save_as']:
                if self.config['save_in']:
                    raise BTFailure(
                        _("You cannot specify both --save_as and "
                          "--save_in"))
                saveas = self.config['save_as']
            elif self.config['save_in']:
                saveas = os.path.join(self.config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                      metainfo.total_bytes,
                                      len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(
                metainfo, Preferences(self.config), self, saveas)
        except BTFailure, e:
            print str(e)
            return
        self.get_status()
        #self.multitorrent.rawserver.install_sigint_handler() - can only be done on the main thread so does not work with Kamaelia
        self.multitorrent.rawserver.listen_forever(self.d)
        self.d.display({'activity': _("shutting down"), 'fractionDone': 0})
        self.torrent.shutdown()
        print "BitTorrent Debug: shutting down"
class DLKamaelia(Feedback):
    """This class accepts feedback from the multitorrent downloader class
    which it can then pass back to the inboxes of TorrentClient"""
    def __init__(self, metainfo, config, interface):
        self.doneflag = threading.Event()
        self.metainfo = metainfo
        self.config = Preferences().initWithDict(config)
        self.d = interface
        
    def run(self):
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if self.config['save_as']:
                if self.config['save_in']:
                    raise BTFailure(_("You cannot specify both --save_as and "
                                      "--save_in"))
                saveas = self.config['save_as']
            elif self.config['save_in']:
                saveas = os.path.join(self.config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                metainfo.total_bytes, len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(metainfo,
                                Preferences(self.config), self, saveas)
        except BTFailure, e:
            print str(e)
            return
        self.get_status()
        #self.multitorrent.rawserver.install_sigint_handler()
        self.multitorrent.rawserver.listen_forever( self.d )
        self.d.display({'activity':_("shutting down"), 'fractionDone':0})
        self.torrent.shutdown()
        print "BitTorrent Debug: shutting down"
    def run(self):
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if self.config["save_as"]:
                if self.config["save_in"]:
                    raise BTFailure(_("You cannot specify both --save_as and " "--save_in"))
                saveas = self.config["save_as"]
            elif self.config["save_in"]:
                saveas = os.path.join(self.config["save_in"], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(
                metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes)
            )
            self.torrent = self.multitorrent.start_torrent(metainfo, Preferences(self.config), self, saveas)
        except BTFailure, e:
            print str(e)
            return
    def run(self):
        self.d = HeadlessDisplayer(self.taskid, self.doneflag)
        self.status_reporter = StatusReporter(self.taskid, report_peer_status_url)

        try:
            self._logger.info('DL.run.Multitorrent')
            if self.multitorrent is None:
                self.doneflag = threading.Event()
                self.multitorrent = Multitorrent(self.config, self.doneflag,
                                                 self.global_error)

            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            self.hash_info = binascii.b2a_hex(metainfo.infohash)

            torrent_name = metainfo.name_fs
            if self.torrentfile is None:
                self.torrentfile = '.'.join([torrent_name, 'torrent'])

            if self.config['save_as']:
                if self.config['save_in']:
                    raise BTFailure(_("You cannot specify both --save_as and "
                                      "--save_in"))
                saveas = self.config['save_as']
            elif self.config['save_in']:
                saveas = os.path.join(self.config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                metainfo.total_bytes, len(metainfo.hashes))

            self._logger.info("start_torrent: %s", saveas)
            self.torrent = self.multitorrent.start_torrent(metainfo,
                                Preferences(self.config), self, saveas)
        except BTFailure, e:
            self._logger.exception("start_torrent raise Exception BTFailure: %s", str(e))
            raise e
class DL(Feedback):
    def __init__(self, metainfo, config):
        self.doneflag = threading.Event()
        self.metainfo = metainfo
        self.config = Preferences().initWithDict(config)

    def run(self):
        self.d = HeadlessDisplayer(self.doneflag)
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if config['save_as']:
                if config['save_in']:
                    raise BTFailure(
                        _("You cannot specify both --save_as and "
                          "--save_in"))
                saveas = config['save_as']
            elif config['save_in']:
                saveas = os.path.join(config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                      metainfo.total_bytes,
                                      len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(
                metainfo, Preferences(self.config), self, saveas)
        except BTFailure, e:
            print str(e)
            return
        self.get_status()
        self.multitorrent.rawserver.install_sigint_handler()
        self.multitorrent.rawserver.listen_forever()
        self.d.display({'activity': _("shutting down"), 'fractionDone': 0})
        self.torrent.shutdown()
class DL(Feedback):

    def __init__(self, metainfo, config):
        self.doneflag = threading.Event()
        self.metainfo = metainfo
        self.config = Preferences().initWithDict(config)

    def run(self):
        self.d = HeadlessDisplayer(self.doneflag)
        try:
            self.multitorrent = Multitorrent(self.config, self.doneflag,
                                             self.global_error)
            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            torrent_name = metainfo.name_fs
            if config['save_as']:
                if config['save_in']:
                    raise BTFailure(_("You cannot specify both --save_as and "
                                      "--save_in"))
                saveas = config['save_as']
            elif config['save_in']:
                saveas = os.path.join(config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                metainfo.total_bytes, len(metainfo.hashes))
            self.torrent = self.multitorrent.start_torrent(metainfo,
                                Preferences(self.config), self, saveas)
        except BTFailure, e:
            print str(e)
            return
        self.get_status()
        self.multitorrent.rawserver.install_sigint_handler()
        self.multitorrent.rawserver.listen_forever()
        self.d.display({'activity':_("shutting down"), 'fractionDone':0})
        self.torrent.shutdown()
class BTControl(object):
	def __init__(self, config, display):
		super(BTControl, self).__init__()
		self.config = config
		self.display = display
		self.doneFlag = threading.Event()
		self.multitorrent = Multitorrent(self.config, self.doneFlag, self.error)
		self.rawServer = self.multitorrent.rawserver
		self.torrentInfo = {}
		self.sharingTorrents = {}
		# Add initial tasks to rawServer:
		self.updateDisplay()

	def start(self):
		self.rawServer.listen_forever()

	def stop(self):
		self.doneFlag.set()

	def getTorrent(self, data, url, handler=None, pieces=[], keepAlive=None, finishTimeout=0):
		metainfo = ConvertedMetainfo(bdecode(data))
		config = self.getConfig(pieces, keepAlive)
		info = TorrentInfo(metainfo, config, handler, keepAlive, url, finishTimeout)
		torrent = self.multitorrent.start_torrent(metainfo, config, self, info.pathName)
		config['#torrent'] = torrent
		self.torrentInfo[torrent] = info
		return (info.pathName, torrent)

	def shutdownTorrent(self, torrent):
		self.display.shutdownTorrent(torrent)
		torrent.shutdown()

	def stopTorrent(self, torrent):
		self.torrentInfo.pop(torrent, None)
		self.sharingTorrents.pop(torrent, None)
		# TODO: implement a stoppedTorrent method in display
		self.shutdownTorrent(torrent)

	def startKeepAlive(self, torrentInfo, torrent):
		if not torrentInfo.keepAlive:
			return
		def serverCallback():
			# Check if the torrent has stopped
			if torrent not in self.torrentInfo:
				return
			self.rawServer.add_task(serverCallback, 1)
			torrentInfo.keepAlive.keepAlive(torrent)
		serverCallback()

	# TODO: rename this to something more appropriate, since it now does more than simply update display
	def updateDisplay(self):
		self.rawServer.add_task(self.updateDisplay, self.config['display_interval'])
		self.display.status()
		self.checkTimeout()
		self.checkShareRatios()

	def checkTimeout(self):
		# self.torrentInfo only contains torrents that haven't yet finished.
		for torrent, info in self.torrentInfo.items():
			if not info.started or not info.finishTimeout:
				continue
			if info.started + info.finishTimeout > time.time():
				continue
			self.display.error('Torrent did not finish in time', torrent)
			self.shutdownTorrent(torrent)
			self.failed(torrent, True)
		# end for

	def checkShareRatios(self):
		for torrent, info in self.sharingTorrents.items():
			stats = torrent.get_status()
			# TODO: allow share ratio to be overridden
			# TODO: save upTotal in feedStore so that we don't get dinged for restarting.
			if stats['upTotal'] >= stats['downTotal']:
				# TODO: rename finishedTorrent to shutdownTorrent:
				self.shutdownTorrent(torrent)
				if info.handler:
					info.handler.shutdownTorrent(torrent)
				del self.sharingTorrents[torrent]
			# end if
		# end for

	def getConfig(self, pieces, keepAlive):
		config = Preferences(self.config)
		if pieces:
			config['#only-pieces'] = pieces
		if keepAlive is not None:
			config['#piece-picker-next'] = keepAlive.pickPiece
		return config

	def started(self, torrent):
		info = self.torrentInfo.get(torrent)
		# If we already had the file, we will finish before we ever start
		if not info:
			return
		info.started = time.time()
		self.startKeepAlive(info, torrent)
		self.display.startedTorrent(torrent, info)

	def finished(self, torrent):
		info = self.torrentInfo.pop(torrent)
		# If we already had the file, we will finish before we ever start
		if not info.started:
			self.display.startedTorrent(torrent, info)
		def afterFlushed():
			if info.handler and info.handler.finishedTorrent(torrent):
				# We cannot shutdown the torrent immediately, so we schedule it.
				self.rawServer.add_task(self.shutdownTorrent, 0, (torrent,))
				return
			self.sharingTorrents[torrent] = info
		if info.keepAlive:
			info.keepAlive.finish(torrent, afterFlushed)
		else:
			afterFlushed()
		# end if

	def failed(self, torrent, unused_is_external):
		info = self.torrentInfo.pop(torrent)
		if info.handler:
			info.handler.failedTorrent(torrent)
		self.display.failedTorrent(torrent)

	def error(self, *args):
		if len(args) == 2:
			level, text = args
			torrent = None
		else:
			torrent, level, text = args
		getattr(self.display, LEVEL_FUNC[level])(text, torrent)

	def exception(self, torrent, text):
		self.error(torrent, CRITICAL, text)
class DL(Feedback):

    def __init__(self, taskid, metainfo, config, singledl_config = {}, multitorrent=None, doneflag=None):
        self._logger = logging.getLogger(self.__class__.__name__)

        self.taskid = taskid
        self.doneflag = doneflag
        self.metainfo = metainfo

        try:
            for k, v in singledl_config.items():
                config[k] = v
        except Exception as e:
            self._logger.error("parse DL config Exception: %s", str(e))

        self.config = config        
        self.multitorrent = multitorrent
        self.shutdownflag = False
        self.torrentfile = None
        self.torrent_name = None
        self.hash_info = None
        self.activity = None
        self.interval = self.config['display_interval']
        self.time_after_seeding = 0

    def run(self):
        self.d = HeadlessDisplayer(self.taskid, self.doneflag)
        self.status_reporter = StatusReporter(self.taskid, report_peer_status_url)

        try:
            self._logger.info('DL.run.Multitorrent')
            if self.multitorrent is None:
                self.doneflag = threading.Event()
                self.multitorrent = Multitorrent(self.config, self.doneflag,
                                                 self.global_error)

            # raises BTFailure if bad
            metainfo = ConvertedMetainfo(bdecode(self.metainfo))
            self.hash_info = binascii.b2a_hex(metainfo.infohash)

            torrent_name = metainfo.name_fs
            if self.torrentfile is None:
                self.torrentfile = '.'.join([torrent_name, 'torrent'])

            if self.config['save_as']:
                if self.config['save_in']:
                    raise BTFailure(_("You cannot specify both --save_as and "
                                      "--save_in"))
                saveas = self.config['save_as']
            elif self.config['save_in']:
                saveas = os.path.join(self.config['save_in'], torrent_name)
            else:
                saveas = torrent_name

            self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas),
                                metainfo.total_bytes, len(metainfo.hashes))

            self._logger.info("start_torrent: %s", saveas)
            self.torrent = self.multitorrent.start_torrent(metainfo,
                                Preferences(self.config), self, saveas)
        except BTFailure, e:
            self._logger.exception("start_torrent raise Exception BTFailure: %s", str(e))
            raise e

        self.get_status()