⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multitorrent.py

📁 bittorrent source by python. please enjoy
💻 PY
📖 第 1 页 / 共 3 页
字号:
        for policy in self.policies:            policy.error(torrent, level, text)    ### persistence    ## These should be the .torrent file!    #################    def _dump_metainfo(self, metainfo):        infohash = metainfo.infohash        path = os.path.join(self.data_dir, 'metainfo',                            infohash.encode('hex'))        f = file(path+'.new', 'wb')        f.write(metainfo.to_data())        f.close()        shutil.move(path+'.new', path)    def _read_metainfo(self, infohash):        path = os.path.join(self.data_dir, 'metainfo',                            infohash.encode('hex'))        f = file(path, 'rb')        data = f.read()        f.close()        return ConvertedMetainfo(bdecode(data))    #################    def _read_torrent_config(self, infohash):        path = os.path.join(self.data_dir, 'torrents', infohash.encode('hex'))        if not os.path.exists(path):            raise BTFailure,_("Coult not open the torrent config: " + infohash.encode('hex'))        f = file(path, 'rb')        data = f.read()        f.close()        try:            torrent_config = cPickle.loads(data)        except:            # backward compatibility with <= 4.9.3            torrent_config = bdecode(data)            for k, v in torrent_config.iteritems():                try:                    torrent_config[k] = v.decode('utf8')                    if k in ('destination_path', 'working_path'):                        torrent_config[k] = encode_for_filesystem(torrent_config[k])[0]                except:                    pass        if not torrent_config.get('destination_path'):            raise BTFailure( _("Invalid torrent config file"))        if not torrent_config.get('working_path'):            raise BTFailure( _("Invalid torrent config file"))        if get_filesystem_encoding() == None:            # These paths should both be unicode.  If they aren't, they are the            # broken product of some old version, and probably are in the            # encoding we used to use in config files.  Attempt to recover.            dp = torrent_config['destination_path']            if isinstance(dp, str):                try:                    dp = dp.decode(old_broken_config_subencoding)                    torrent_config['destination_path'] = dp                except:                    raise BTFailure( _("Invalid torrent config file"))            wp = torrent_config['working_path']            if isinstance(wp, str):                try:                    wp = wp.decode(old_broken_config_subencoding)                    torrent_config['working_path'] = wp                except:                    raise BTFailure( _("Invalid torrent config file"))        return torrent_config    def _dump_global_config(self):        # BUG: we can save to different sections later        section = 'bittorrent'        configfile.save_global_config(self.config, section,                                      lambda *e : self.logger.error(*e))    def _dump_torrents(self):        assert self.resume_from_torrent_config         self.last_save_time = bttime()        r = []        def write_entry(infohash, t):            r.append(' '.join((infohash.encode('hex'),                               str(t.uptotal), str(t.downtotal))))        r.append('BitTorrent UI state file, version 5')        r.append('Queued torrents')        for t in self.torrents.values():            write_entry(t.metainfo.infohash, self.torrents[t.metainfo.infohash])        r.append('End')        f = None        try:            path = os.path.join(self.data_dir, 'ui_state')            f = file(path+'.new', 'wb')            f.write('\n'.join(r) + '\n')            f.close()            shutil.move(path+'.new', path)        except Exception, e:            self.logger.error(_("Could not save UI state: ") + unicode(e.args[0]))            if f is not None:                f.close()    def _init_torrent(self, t, initialize=True, use_policy=True):        self.torrents[t.infohash] = t        if not initialize:            t.logger.debug("created torrent")            return        t.logger.debug("created torrent, initializing")        df = t.initialize()        if use_policy and t.policy == "start":            df.addCallback(lambda r, t: self.start_torrent(t.infohash), t)        return df    def initialize_torrents(self):        df = launch_coroutine(_wrap_task(self.rawserver.add_task), self._initialize_torrents)        df.addErrback(lambda e : self.logger.error('initialize_torrents failed!',                                                   exc_info=e))        return df    def _initialize_torrents(self):        self.logger.debug("initializing torrents")        for t in copy(self.torrents).itervalues():            if t in self.torrents.values() and t.state == "created":                df = self._init_torrent(t)                # HACK                #yield df                #df.getResult()    # this function is so nasty!    def _restore_state(self, init_torrents):        def decode_line(line):            hashtext = line[:40]            try:                infohash = InfoHashType(hashtext.decode('hex'))            except:                raise BTFailure(_("Invalid state file contents"))            if len(infohash) != 20:                raise BTFailure(_("Invalid state file contents"))            if infohash in self.torrents:                raise BTFailure(_("Invalid state file (duplicate entry)"))            try:                metainfo = self._read_metainfo(infohash)            except OSError, e:                try:                    f.close()                except:                    pass                self.logger.error((_("Error reading metainfo file \"%s\".") %                                  hashtext) + " (" + unicode(e.args[0])+ "), " +                                  _("cannot restore state completely"))                return None            except Exception, e:                self.logger.error((_("Corrupt data in metainfo \"%s\", cannot restore torrent.") % hashtext) +                                  '('+unicode(e.args[0])+')')                return None            t = Torrent(metainfo, "",  "", self.config, self.data_dir,                        self.rawserver, self.choker,                        self.singleport_listener, self.ratelimiter,                        self.total_downmeasure, self.filepool, self.dht, self,                        self.log_root)            t.metainfo.reported_errors = True # suppress redisplay on restart            if infohash != t.metainfo.infohash:                self.logger.error((_("Corrupt data in \"%s\", cannot restore torrent.") % hashtext) +                                  _("(infohash mismatch)"))                return None            if len(line) == 41:                t.working_path = None                t.destination_path = None                return infohash, t            try:                if version < 2:                    t.working_path = line[41:-1].decode('string_escape')                    t.working_path = t.working_path.decode('utf-8')                    t.working_path = encode_for_filesystem(t.working_path)[0]                    t.destination_path = t.working_path                elif version == 3:                    up, down, working_path = line[41:-1].split(' ', 2)                    t.uptotal = t.uptotal_old = int(up)                    t.downtotal = t.downtotal_old = int(down)                    t.working_path = working_path.decode('string_escape')                    t.working_path = t.working_path.decode('utf-8')                    t.working_path = encode_for_filesystem(t.working_path)[0]                    t.destination_path = t.working_path                elif version >= 4:                    up, down = line[41:-1].split(' ', 1)                    t.uptotal = t.uptotal_old = int(up)                    t.downtotal = t.downtotal_old = int(down)            except ValueError:  # unpack, int(), decode()                raise BTFailure(_("Invalid state file (bad entry)"))            torrent_config = self.config            try:                if version < 5:                    torrent_config = configfile.read_torrent_config(                                                           self.config,                                                           self.data_dir,                                                           infohash,                                                           lambda s : self.global_error(logging.ERROR, s))                else:                    torrent_config = self._read_torrent_config(infohash)                t.update_config(torrent_config)            except BTFailure, e:                self.logger.error("Read torrent config failed",                                  exc_info=sys.exc_info())                # if read_torrent_config fails then ignore the torrent...                return None            return infohash, t        # BEGIN _restore_state        assert self.resume_from_torrent_config        filename = os.path.join(self.data_dir, 'ui_state')        if not os.path.exists(filename):            return        f = None        try:            f = file(filename, 'rb')            lines = f.readlines()            f.close()        except Exception, e:            if f is not None:                f.close()            raise BTFailure(unicode(e.args[0]))        i = iter(lines)        try:            txt = 'BitTorrent UI state file, version '            version = i.next()            if not version.startswith(txt):                raise BTFailure(_("Bad UI state file"))            try:                version = int(version[len(txt):-1])            except:                raise BTFailure(_("Bad UI state file version"))            if version > 5:                raise BTFailure(_("Unsupported UI state file version (from "                                  "newer client version?)"))            if version < 3:                if i.next() != 'Running/queued torrents\n':                    raise BTFailure(_("Invalid state file contents"))            else:                if i.next() != 'Running torrents\n' and version != 5:                    raise BTFailure(_("Invalid state file contents"))                while version < 5:                    line = i.next()                    if line == 'Queued torrents\n':                        break                    t = decode_line(line)                    if t is None:                        continue                    infohash, t = t                    df = self._init_torrent(t, initialize=init_torrents)            while True:                line = i.next()                if (version < 5 and line == 'Known torrents\n') or (version == 5 and line == 'End\n'):                    break                t = decode_line(line)                if t is None:                    continue                infohash, t = t                if t.destination_path is None:                    raise BTFailure(_("Invalid state file contents"))                df = self._init_torrent(t, initialize=init_torrents)            while version < 5:                line = i.next()                if line == 'End\n':                    break                t = decode_line(line)                if t is None:                    continue                infohash, t = t                df = self._init_torrent(t, initialize=init_torrents)        except StopIteration:            raise BTFailure(_("Invalid state file contents"))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -