📄 oldtorrentqueue.py
字号:
t.dlpath = None return infohash, t try: if version < 2: t.dlpath = line[41:-1].decode('string_escape') elif version == 3: up, down, dlpath = line[41:-1].split(' ', 2) t.uptotal = t.uptotal_old = int(up) t.downtotal = t.downtotal_old = int(down) t.dlpath = dlpath.decode('string_escape') 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)")) # save_as workaround self.config['save_as'] = '' config = configfile.read_torrent_config(self.config, self.config['data_dir'], infohash, self.global_error) t.config.update(config) # save_as workaround del self.config['save_as'] return infohash, t filename = os.path.join(self.config['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(str(e)) 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 > 4: 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': raise BTFailure(_("Invalid state file contents")) while True: line = i.next() if line == 'Queued torrents\n': break t = decode_line(line) if t is None: continue infohash, t = t if t.dlpath is None: raise BTFailure(_("Invalid state file contents (dlpath is None)")) t.state = RUN_QUEUED self.running_torrents.append(infohash) while True: line = i.next() if line == 'Known torrents\n': break t = decode_line(line) if t is None: continue infohash, t = t if t.dlpath is None: raise BTFailure(_("Invalid state file contents")) t.state = QUEUED self.queue.append(infohash) while True: line = i.next() if line == 'End\n': break t = decode_line(line) if t is None: continue infohash, t = t if t.dlpath is None: t.state = ASKING_LOCATION else: t.state = KNOWN self.other_torrents.append(infohash) except StopIteration: raise BTFailure(_("Invalid state file contents")) def _queue_loop(self): if self.doneflag.isSet(): return self.rawserver.add_task(20, self._queue_loop) now = bttime() self._check_version() if self.queue and self.starting_torrent is None: mintime = now - self.config['next_torrent_time'] * 60 minratio = self.config['next_torrent_ratio'] / 100 if self.config['seed_forever']: minratio = 1e99 else: mintime = 0 minratio = self.config['last_torrent_ratio'] / 100 if self.config['seed_last_forever']: minratio = 1e99 if minratio >= 1e99: return for infohash in self.running_torrents: t = self.torrents[infohash] myminratio = minratio if t.dl: if self.queue and t.dl.config['seed_last_forever']: myminratio = 1e99 elif t.dl.config['seed_forever']: myminratio = 1e99 if t.state == RUN_QUEUED: continue totals = t.dl.get_total_transfer() # not updated for remaining torrents if one is stopped, who cares t.uptotal = t.uptotal_old + totals[0] t.downtotal = t.downtotal_old + totals[1] if t.finishtime is None or t.finishtime > now - 120: continue if t.finishtime > mintime: if t.uptotal < t.metainfo.total_bytes * myminratio: continue self.change_torrent_state(infohash, RUNNING, KNOWN) break if self.running_torrents and self.last_save_time < now - 300: self._dump_state() def _check_queue(self): if self.starting_torrent is not None or self.config['pause']: return for infohash in self.running_torrents: if self.torrents[infohash].state == RUN_QUEUED: self.starting_torrent = infohash t = self.torrents[infohash] t.state = RUNNING t.finishtime = None t.dl = self.multitorrent.start_torrent(t.metainfo, t.config, self, t.dlpath) return if not self.queue or len(self.running_torrents) >= \ self.config['def_running_torrents']: return infohash = self.queue.pop(0) self.starting_torrent = infohash t = self.torrents[infohash] assert t.state == QUEUED t.state = RUNNING t.finishtime = None self.running_torrents.append(infohash) t.dl = self.multitorrent.start_torrent(t.metainfo, t.config, self, t.dlpath) self._send_state(infohash) def _send_state(self, infohash): t = self.torrents[infohash] state = t.state if state == RUN_QUEUED: state = RUNNING pos = None if state in (KNOWN, RUNNING, QUEUED): l = self._get_list(state) if l[-1] != infohash: pos = l.index(infohash) self.run_ui_task(self.ui.torrent_state_changed, infohash, t.dlpath, state, t.completion, t.uptotal_old, t.downtotal_old, pos) def _stop_running(self, infohash): t = self.torrents[infohash] if t.state == RUN_QUEUED: self.running_torrents.remove(infohash) t.state = KNOWN return True assert t.state == RUNNING shutdown_succeded = t.dl.shutdown() if not shutdown_succeded: self.run_ui_task(self.ui.open_log) self.error(t.metainfo, ERROR, "Unable to stop torrent. Please send this application log to bugs@bittorrent.com .") return False if infohash == self.starting_torrent: self.starting_torrent = None try: self.running_torrents.remove(infohash) except ValueError: self.other_torrents.remove(infohash) return False else: t.state = KNOWN totals = t.dl.get_total_transfer() t.uptotal_old += totals[0] t.uptotal = t.uptotal_old t.downtotal_old += totals[1] t.downtotal = t.downtotal_old t.dl = None t.completion = self.multitorrent.get_completion(self.config, t.metainfo, t.dlpath) return True def external_command(self, action, *datas): if action == 'start_torrent': assert len(datas) == 2 # BUG: passing raw data over controlsocket instead of # metainfo because we can't pass metainfo over control # socket, bummer self.start_new_torrent_raw(datas[0], save_as=datas[1]) elif action == 'show_error': assert len(datas) == 1 self.global_error(ERROR, datas[0]) elif action == 'no-op': pass def remove_torrent(self, infohash): if infohash not in self.torrents: return state = self.torrents[infohash].state if state == QUEUED: self.queue.remove(infohash) elif state in (RUNNING, RUN_QUEUED): self._stop_running(infohash) self._check_queue() else: self.other_torrents.remove(infohash) self.run_ui_task(self.ui.removed_torrent, infohash) del self.torrents[infohash] for d in ['metainfo', 'resume']: filename = os.path.join(self.config['data_dir'], d, infohash.encode('hex')) try: os.remove(filename) except Exception, e: self.global_error(WARNING, (_("Could not delete cached %s file:")%d) + str(e)) ec = lambda level, message: self.global_error(level, message) configfile.remove_torrent_config(self.config['data_dir'], infohash, ec) self._dump_state() def set_save_location(self, infohash, dlpath): torrent = self.torrents.get(infohash) if torrent is None or torrent.state == RUNNING: return torrent.dlpath = dlpath self._dump_config() torrent.completion = self.multitorrent.get_completion(self.config, torrent.metainfo, dlpath) if torrent.state == ASKING_LOCATION: torrent.state = KNOWN self.change_torrent_state(infohash, KNOWN, QUEUED) else: self._send_state(infohash) self._dump_state() def start_new_torrent_raw(self, data, save_as=None): try: metainfo = ConvertedMetainfo(bdecode(data)) self.start_new_torrent(metainfo, save_as=save_as) except Exception, e: self.global_error(ERROR, _("This is not a valid torrent file. (%s)") % str(e)) def start_new_torrent(self, metainfo, save_as=None): t = TorrentInfo(Preferences(self.config)) t.metainfo = metainfo infohash = t.metainfo.infohash if infohash in self.torrents: real_state = self.torrents[infohash].state if real_state in (RUNNING, RUN_QUEUED): self.error(t.metainfo, ERROR, _("This torrent (or one with the same contents) is " "already running.")) elif real_state == QUEUED: self.error(t.metainfo, ERROR, _("This torrent (or one with the same contents) is " "already waiting to run.")) elif real_state == ASKING_LOCATION: pass elif real_state == KNOWN: self.change_torrent_state(infohash, KNOWN, newstate=QUEUED) else: raise BTFailure(_("Torrent in unknown state %d") % real_state) return path = os.path.join(self.config['data_dir'], 'metainfo', infohash.encode('hex')) try: f = file(path+'.new', 'wb') f.write(metainfo.to_data()) f.close() shutil.move(path+'.new', path) except Exception, e: try: f.close() except:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -