📄 download_bt1.py
字号:
errorfunc('problem getting response info - ' + str(e))
return None
try:
h.close()
except:
pass
try:
try:
response = bdecode(response)
except:
errorfunc("warning: bad data in responsefile")
response = bdecode(response, sloppy=1)
check_message(response)
except ValueError, e:
errorfunc("got bad file info - " + str(e))
return None
return response
class BT1Download:
def __init__(self, statusfunc, finfunc, errorfunc, excfunc, doneflag,
config, response, infohash, id, rawserver, port,
appdataobj = None):
self.statusfunc = statusfunc
self.finfunc = finfunc
self.errorfunc = errorfunc
self.excfunc = excfunc
self.doneflag = doneflag
self.config = config
self.response = response
self.infohash = infohash
self.myid = id
self.rawserver = rawserver
self.port = port
self.info = self.response['info']
self.pieces = [self.info['pieces'][x:x+20]
for x in xrange(0, len(self.info['pieces']), 20)]
self.len_pieces = len(self.pieces)
self.argslistheader = argslistheader
self.unpauseflag = Event()
self.unpauseflag.set()
self.downloader = None
self.storagewrapper = None
self.fileselector = None
self.super_seeding_active = False
self.filedatflag = Event()
self.spewflag = Event()
self.superseedflag = Event()
self.whenpaused = None
self.finflag = Event()
self.rerequest = None
self.tcp_ack_fudge = config['tcp_ack_fudge']
self.selector_enabled = config['selector_enabled']
if appdataobj:
self.appdataobj = appdataobj
elif self.selector_enabled:
self.appdataobj = ConfigDir()
self.appdataobj.deleteOldCacheData( config['expire_cache_data'],
[self.infohash] )
self.excflag = self.rawserver.get_exception_flag()
self.failed = False
self.checking = False
self.started = False
self.picker = PiecePicker(self.len_pieces, config['rarest_first_cutoff'],
config['rarest_first_priority_cutoff'])
self.choker = Choker(config, rawserver.add_task,
self.picker, self.finflag.isSet)
def checkSaveLocation(self, loc):
if self.info.has_key('length'):
return path.exists(loc)
for x in self.info['files']:
if path.exists(path.join(loc, x['path'][0])):
return True
return False
def saveAs(self, filefunc, pathfunc = None):
try:
def make(f, forcedir = False):
if not forcedir:
f = path.split(f)[0]
if f != '' and not path.exists(f):
makedirs(f)
if self.info.has_key('length'):
file_length = self.info['length']
file = filefunc(self.info['name'], file_length,
self.config['saveas'], False)
if file is None:
return None
make(file)
files = [(file, file_length)]
else:
file_length = 0L
for x in self.info['files']:
file_length += x['length']
file = filefunc(self.info['name'], file_length,
self.config['saveas'], True)
if file is None:
return None
# if this path exists, and no files from the info dict exist, we assume it's a new download and
# the user wants to create a new directory with the default name
existing = 0
if path.exists(file):
if not path.isdir(file):
self.errorfunc(file + 'is not a dir')
return None
if listdir(file): # if it's not empty
for x in self.info['files']:
if path.exists(path.join(file, x['path'][0])):
existing = 1
if not existing:
file = path.join(file, self.info['name'])
if path.exists(file) and not path.isdir(file):
if file[-8:] == '.torrent':
file = file[:-8]
if path.exists(file) and not path.isdir(file):
self.errorfunc("Can't create dir - " + self.info['name'])
return None
make(file, True)
# alert the UI to any possible change in path
if pathfunc != None:
pathfunc(file)
files = []
for x in self.info['files']:
n = file
for i in x['path']:
n = path.join(n, i)
files.append((n, x['length']))
make(n)
except OSError, e:
self.errorfunc("Couldn't allocate dir - " + str(e))
return None
self.filename = file
self.files = files
self.datalength = file_length
return file
def getFilename(self):
return self.filename
def _finished(self):
self.finflag.set()
try:
self.storage.set_readonly()
except (IOError, OSError), e:
self.errorfunc('trouble setting readonly at end - ' + str(e))
if self.superseedflag.isSet():
self._set_super_seed()
self.choker.set_round_robin_period(
max( self.config['round_robin_period'],
self.config['round_robin_period'] *
self.info['piece length'] / 200000 ) )
self.rerequest_complete()
self.finfunc()
def _data_flunked(self, amount, index):
self.ratemeasure_datarejected(amount)
if not self.doneflag.isSet():
self.errorfunc('piece %d failed hash check, re-downloading it' % index)
def _failed(self, reason):
self.failed = True
self.doneflag.set()
if reason is not None:
self.errorfunc(reason)
def initFiles(self, old_style = False, statusfunc = None):
if self.doneflag.isSet():
return None
if not statusfunc:
statusfunc = self.statusfunc
disabled_files = None
if self.selector_enabled:
self.priority = self.config['priority']
if self.priority:
try:
self.priority = self.priority.split(',')
assert len(self.priority) == len(self.files)
self.priority = [int(p) for p in self.priority]
for p in self.priority:
assert p >= -1
assert p <= 2
except:
self.errorfunc('bad priority list given, ignored')
self.priority = None
data = self.appdataobj.getTorrentData(self.infohash)
try:
d = data['resume data']['priority']
assert len(d) == len(self.files)
disabled_files = [x == -1 for x in d]
except:
try:
disabled_files = [x == -1 for x in self.priority]
except:
pass
try:
try:
self.storage = Storage(self.files, self.info['piece length'],
self.doneflag, self.config, disabled_files)
except IOError, e:
self.errorfunc('trouble accessing files - ' + str(e))
return None
if self.doneflag.isSet():
return None
self.storagewrapper = StorageWrapper(self.storage, self.config['download_slice_size'],
self.pieces, self.info['piece length'], self._finished, self._failed,
statusfunc, self.doneflag, self.config['check_hashes'],
self._data_flunked, self.rawserver.add_task,
self.config, self.unpauseflag)
except ValueError, e:
self._failed('bad data - ' + str(e))
except IOError, e:
self._failed('IOError - ' + str(e))
if self.doneflag.isSet():
return None
if self.selector_enabled:
self.fileselector = FileSelector(self.files, self.info['piece length'],
self.appdataobj.getPieceDir(self.infohash),
self.storage, self.storagewrapper,
self.rawserver.add_task,
self._failed)
if data:
data = data.get('resume data')
if data:
self.fileselector.unpickle(data)
self.checking = True
if old_style:
return self.storagewrapper.old_style_init()
return self.storagewrapper.initialize
def getCachedTorrentData(self):
return self.appdataobj.getTorrentData(self.infohash)
def _make_upload(self, connection, ratelimiter, totalup):
return Upload(connection, ratelimiter, totalup,
self.choker, self.storagewrapper, self.picker,
self.config)
def _kick_peer(self, connection):
def k(connection = connection):
connection.close()
self.rawserver.add_task(k, 0)
def _ban_peer(self, ip):
self.encoder_ban(ip)
def _received_raw_data(self, x):
if self.tcp_ack_fudge:
x = int(x*self.tcp_ack_fudge)
self.ratelimiter.adjust_sent(x)
# self.upmeasure.update_rate(x)
def _received_data(self, x):
self.downmeasure.update_rate(x)
self.ratemeasure.data_came_in(x)
def _received_http_data(self, x):
self.downmeasure.update_rate(x)
self.ratemeasure.data_came_in(x)
self.downloader.external_data_received(x)
def _cancelfunc(self, pieces):
self.downloader.cancel_piece_download(pieces)
self.httpdownloader.cancel_piece_download(pieces)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -