📄 bittorrent-console.py
字号:
#!/usr/bin/env python# The contents of this file are subject to the BitTorrent Open Source License# Version 1.1 (the License). You may not copy or use this file, in either# source code or executable form, except in compliance with the License. You# may obtain a copy of the License at http://www.bittorrent.com/license/.## Software distributed under the License is distributed on an AS IS basis,# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License# for the specific language governing rights and limitations under the# License.# Written by Bram Cohen, Uoti Urpala, John Hoffman, and David Harrisonfrom __future__ import divisionfrom BitTorrent.translation import _import sysimport osfrom cStringIO import StringIOimport loggingfrom logging import ERROR, WARNINGfrom time import strftime, sleepimport tracebackfrom BitTorrent import platformfrom BitTorrent.platform import decode_from_filesystem, encode_for_filesystemimport BitTorrent.stackthreading as threadingfrom BitTorrent.defer import DeferredEventfrom BitTorrent import inject_main_logfilefrom BitTorrent.MultiTorrent import Feedback, MultiTorrentfrom BitTorrent.defaultargs import get_defaultsfrom BitTorrent.parseargs import printHelpfrom BitTorrent.zurllib import urlopenfrom BitTorrent.prefs import Preferencesfrom BitTorrent import configfilefrom BitTorrent import BTFailure, UserFailurefrom BitTorrent import versionfrom BitTorrent import GetTorrentfrom BitTorrent.UI import Size, Durationfrom BitTorrent.RawServer_twisted import RawServer, taskfrom BitTorrent.ConvertedMetainfo import ConvertedMetainfofrom BitTorrent.MultiTorrent import TorrentNotInitializedinject_main_logfile()from BitTorrent import consolefrom BitTorrent import stderr_console # must import after inject_main_logfile # because import is really a copy. # If imported earlier, stderr_console # doesn't reflect the changes made in # inject_main_logfile!! BAAAHHHH!!def wrap_log(context_string, logger): """Useful when passing a logger to a deferred's errback. The context specifies what was being done when the exception was raised.""" return lambda e, *args, **kwargs : logger.error(context_string, exc_info=e)def fmttime(n): if n == 0: return _("download complete!") return _("finishing in %s") % (str(Duration(n)))def fmtsize(n): s = str(n) size = s[-3:] while len(s) > 3: s = s[:-3] size = '%s,%s' % (s[-3:], size) size = '%s (%s)' % (size, str(Size(n))) return sizeclass HeadlessDisplayer(object): def __init__(self): self.done = False self.percentDone = '' self.timeEst = '' self.downRate = '---' self.upRate = '---' self.shareRating = '' self.seedStatus = '' self.peerStatus = '' self.errors = [] self.file = '' self.downloadTo = '' self.fileSize = '' self.numpieces = 0 def set_torrent_values(self, name, path, size, numpieces): self.file = name self.downloadTo = path self.fileSize = fmtsize(size) self.numpieces = numpieces def finished(self): self.done = True self.downRate = '---' self.display({'activity':_("download succeeded"), 'fractionDone':1}) def error(self, errormsg): newerrmsg = strftime('[%H:%M:%S] ') + errormsg self.errors.append(newerrmsg) print errormsg #self.display({}) # display is only called periodically. def display(self, statistics): fractionDone = statistics.get('fractionDone') activity = statistics.get('activity') timeEst = statistics.get('timeEst') downRate = statistics.get('downRate') upRate = statistics.get('upRate') spew = statistics.get('spew') print '\n\n\n\n' if spew is not None: self.print_spew(spew) if timeEst is not None: self.timeEst = fmttime(timeEst) elif activity is not None: self.timeEst = activity if fractionDone is not None: self.percentDone = str(int(fractionDone * 1000) / 10) if downRate is not None: self.downRate = '%.1f KB/s' % (downRate / (1 << 10)) if upRate is not None: self.upRate = '%.1f KB/s' % (upRate / (1 << 10)) downTotal = statistics.get('downTotal') if downTotal is not None: upTotal = statistics['upTotal'] if downTotal <= upTotal / 100: self.shareRating = _("oo (%.1f MB up / %.1f MB down)") % ( upTotal / (1<<20), downTotal / (1<<20)) else: self.shareRating = _("%.3f (%.1f MB up / %.1f MB down)") % ( upTotal / downTotal, upTotal / (1<<20), downTotal / (1<<20)) #numCopies = statistics['numCopies'] #nextCopies = ', '.join(["%d:%.1f%%" % (a,int(b*1000)/10) for a,b in # zip(xrange(numCopies+1, 1000), statistics['numCopyList'])]) if not self.done: self.seedStatus = _("%d seen now") % statistics['numSeeds'] # self.seedStatus = _("%d seen now, plus %d distributed copies" # "(%s)") % (statistics['numSeeds' ], # statistics['numCopies'], # nextCopies) else: self.seedStatus = "" # self.seedStatus = _("%d distributed copies (next: %s)") % ( # statistics['numCopies'], nextCopies) self.peerStatus = _("%d seen now") % statistics['numPeers'] if not self.errors: print _("Log: none") else: print _("Log:") for err in self.errors[-4:]: print err print print _("saving: "), self.file print _("file size: "), self.fileSize print _("percent done: "), self.percentDone print _("time left: "), self.timeEst print _("download to: "), self.downloadTo print _("download rate: "), self.downRate print _("upload rate: "), self.upRate print _("share rating: "), self.shareRating print _("seed status: "), self.seedStatus print _("peer status: "), self.peerStatus def print_spew(self, spew): s = StringIO() s.write('\n\n\n') for c in spew: s.write('%20s ' % c['ip']) if c['initiation'] == 'L': s.write('l') else: s.write('r') total, rate, interested, choked = c['upload'] s.write(' %10s %10s ' % (str(int(total/10485.76)/100), str(int(rate)))) if c['is_optimistic_unchoke']: s.write('*') else: s.write(' ') if interested: s.write('i') else: s.write(' ') if choked: s.write('c') else: s.write(' ') total, rate, interested, choked, snubbed = c['download'] s.write(' %10s %10s ' % (str(int(total/10485.76)/100), str(int(rate)))) if interested: s.write('i') else: s.write(' ') if choked: s.write('c') else: s.write(' ') if snubbed: s.write('s') else: s.write(' ') s.write('\n') print s.getvalue()#class TorrentApp(Feedback):class TorrentApp(object): class LogHandler(logging.Handler): def __init__(self, app, level=logging.NOTSET): logging.Handler.__init__(self,level) self.app = app def emit(self, record):
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -