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

📄 autoupdatebutler.py

📁 bittorrent source by python. please enjoy
💻 PY
📖 第 1 页 / 共 2 页
字号:
        parts = [app_name, str(available_version)]        if available_version.is_beta():            parts.append('Beta')        name = '-'.join(parts)        name += '.' + ext        return name    def _calc_installer_dir(self):        """Find a place to store the installer while it's being downloaded."""        temp_dir = get_temp_dir()        return temp_dir    def _get_available(self, url):        """Get the available version from the version site.  The        command line option --new_version X.Y.Z overrides this method        and returns 'X.Y.Z' instead."""        self.debug('_get_available() run#%d: hitting url %s' % (self.runs, url))        try:            u = zurllib.urlopen(url)            s = u.read()            s = s.strip()        except:            raise BTFailure(_("Could not get latest version from %s")%url)        try:            # we're luck asserts are turned off in production.            # this assert is false for 4.20.X            #assert len(s) == 5            available_version = Version.from_str(s)        except:            raise BTFailure(_("Could not parse new version string from %s")%url)        return available_version    def _get_torrent(self, installer_url):        """Get the .torrent file from the version site."""        torrentfile = None        try:            torrentfile = GetTorrent.get_url(installer_url)        except GetTorrent.GetTorrentException, e:            self.debug('_get_torrent() run#%d: failed to download torrent file %s: %s' %                       (self.runs, installer_url, unicode(e.args[0])))            pass        return torrentfile    def _get_signature(self, installer_url):        """Get the signature (.sign) file from the version site, and        unpickle the signature.  The sign file is a signature of the        .torrent file created with the auto-update tool in        auto-update/sign_file.py."""        signature = None        try:            signfile = zurllib.urlopen(installer_url + '.sign')        except:            self.debug('_get_signature() run#%d: failed to download signfile %s.sign' %                       (self.runs, installer_url))            pass        else:            try:                signature = pickle.load(signfile)            except:                self.debug('_get_signature() run#%d: failed to unpickle signfile %s' %                           (self.runs, signfile))                pass        return signature    def _check_signature(self, torrentfile, signature):        """Check the torrent file's signature using the public key."""        public_key_file = open(os.path.join(doc_root, 'public.key'), 'rb')        public_key = pickle.load(public_key_file)        public_key_file.close()        h = sha(torrentfile).digest()        return public_key.verify(h, signature)    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):            from traceback import format_exc            self.debug('check_version() run #%d: '%self.runs + format_exc(e))        df.addErrback(errback)    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        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 + 'not updating old version %s' %                       str(available_version))            self._restart()            return        if not self._can_install():            self.debug(debug_prefix + 'cannot install on this os')            self.available_version = available_version            self._restart()            return        installer_name = self._calc_installer_name(available_version)        installer_url  = self.version_site + installer_name + '.torrent'        fs_name = encode_for_filesystem(installer_name.decode('ascii'))[0]        installer_path = os.path.join(self.installer_dir, fs_name)        df = ThreadedDeferred(_wrap_task(self.rawserver.external_add_task),                              self._get_torrent, installer_url)        yield df        torrentfile = df.getResult()        df = ThreadedDeferred(_wrap_task(self.rawserver.external_add_task),                              self._get_signature, installer_url)        yield df        signature = df.getResult()        if torrentfile and signature:            df = ThreadedDeferred(_wrap_task(self.rawserver.external_add_task),                                  self._check_signature, torrentfile, signature)            yield df            checked = df.getResult()            if checked:                self.debug(debug_prefix + 'signature verified successfully.')                b = bdecode(torrentfile)                metainfo = ConvertedMetainfo(b)                infohash = metainfo.infohash                self.available_version = available_version                self.multitorrent.remove_auto_updates_except(infohash)                try:                    df = self.multitorrent.create_torrent(metainfo, installer_path,                                                          installer_path, hidden=True,                                                          is_auto_update=True)                    yield df                    df.getResult()                except TorrentAlreadyRunning:                    self.debug(debug_prefix + 'found auto-update torrent already running')                except TorrentAlreadyInQueue:                    self.debug(debug_prefix + 'found auto-update torrent queued')                else:                    self.debug(debug_prefix + 'starting auto-update download')                self.debug(debug_prefix + 'adding to estate '+infohash.short())                self.estate.add(infohash)            else:                self.debug(debug_prefix + 'torrent file signature failed to verify.')                pass        else:            self.debug(debug_prefix +                       'couldn\'t get both torrentfile %s and signature %s' %                       (str(type(torrentfile)), str(type(signature))))        self._restart()    def _restart(self):        """Run the auto-update check once a day, or every ten seconds        in debug mode."""        self.runs += 1        self.rawserver.external_add_task(self.delay, self.check_version)

⌨️ 快捷键说明

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