def add(request): if request.POST: errors = {} paused = request.POST.has_key('paused') url = request.POST['url'] if url: try: f = urllib.urlopen(url) content = f.read() f.close() metainfo = ConvertedMetainfo(bdecode(content)) name = metainfo.name_fs[:50] except Exception, e: err = traceback.format_exception_only(e.__class__, e) errors.setdefault('url', []).append(''.join(err)) else: try: torrent = request.FILES['torrent'] content = torrent['content'] metainfo = ConvertedMetainfo(bdecode(content)) name = metainfo.name_fs[:50] except Exception, e: err = traceback.format_exception_only(e.__class__, e) errors.setdefault('torrent', []).append(''.join(err))
def _getTorrentMeta(self, dest_path, url): """ Given the download destination path and URL to the torrent, extract the metadata to return the torrent file/dir name, files to be downloaded, and total length of download. """ # Grab the torrent metadata metainfo_file = urllib2.urlopen(url) metainfo = bdecode(metainfo_file.read()) metainfo_file.close() # Gather the list of files in the torrent and total size. files = [] info = metainfo['info'] if not info.has_key('files'): # Get the length and path of the single file to download. total_length = info['length'] files.append(os.path.join(dest_path, info['name'])) else: # Calculate the total length and find paths of all files # to be downloaded. total_length = 0 files_root = os.path.join(dest_path, info['name']) for file in info['files']: total_length += file['length'] file_path = os.path.join(*(file['path'])) files.append(os.path.join(files_root, file_path)) return info['name'], files, total_length
def run(self): self.d = HeadlessDisplayer(self.doneflag) try: self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error) # raises BTFailure if bad metainfo = ConvertedMetainfo(bdecode(self.metainfo)) torrent_name = metainfo.name_fs if config['save_as']: if config['save_in']: raise BTFailure('You cannot specify both --save_as and ' '--save_in') saveas = config['save_as'] elif config['save_in']: saveas = os.path.join(config['save_in'], torrent_name) else: saveas = torrent_name self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes)) self.torrent = self.multitorrent.start_torrent(metainfo, self.config, self, saveas) except BTFailure, e: print str(e) return
def datagramReceived(self, str, addr): # bdecode try: msg = bdecode(str) except Exception, e: if self.noisy: print "response decode error: " + `e`, `str`
def datagramReceived(self, str, addr): # bdecode try: msg = bdecode(str) except Exception, e: if self.noisy: print "response decode error: " + ` e `, ` str `
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 _restore_state(self): def decode_line(line): hashtext = line[:40] try: infohash = hashtext.decode('hex') except: raise BTFailure("Invalid state file contents") if len(infohash) != 20: raise BTFailure("Invalid state file contents") try: path = os.path.join(self.config['data_dir'], 'metainfo', hashtext) f = file(path, 'rb') data = f.read() f.close() except Exception, e: try: f.close() except: pass self.global_error(ERROR,"Error reading file "+path+" ("+str(e)+ "), cannot restore state completely") return None if infohash in self.torrents: raise BTFailure("Invalid state file (duplicate entry)") t = TorrentInfo() self.torrents[infohash] = t try: t.metainfo = ConvertedMetainfo(bdecode(data)) except Exception, e: self.global_error(ERROR, "Corrupt data in "+path+ " , cannot restore torrent ("+str(e)+")") return None
def init(self): self = super(Generate, self).init() appDefaults = {ANNOUNCEKEY:bencode([]), COMPLETEDIRKEY:0, GWINKEY:"", SWITCHKEY:1} defaults.registerDefaults_(appDefaults) x=defaults.objectForKey_(ANNOUNCEKEY) try: self.trackers = bdecode(x) except ValueError: if x[:7] == "http://": self.trackers = [str(x.encode("utf-8"))] else: self.trackers = [] defaults.setObject_forKey_(bencode(self.trackers), ANNOUNCEKEY) NSBundle.loadNibNamed_owner_("Metainfo", self) self.fname = None self.done = 0 self.gWindow.registerForDraggedTypes_([NSFilenamesPboardType]) self.gWindow.setFrameAutosaveName_(GWINKEY) self.gWindow.setFrameUsingName_(GWINKEY) try: self.announce.setStringValue_(self.trackers[0]) except IndexError: pass self.subCheck.setState_(defaults.objectForKey_(COMPLETEDIRKEY)) self.trackerPop.selectItemAtIndex_(defaults.objectForKey_(SWITCHKEY)) self.popped_(self.trackerPop) return self
def run(self): import os try: config = self.config self.d = HeadlessDisplayer(self.doneflag) self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error) # raises BTFailure if bad metainfo = ConvertedMetainfo(bdecode(self.metainfo)) torrent_name = metainfo.name_fs if config["save_as"]: if config["save_in"]: raise BTFailure("You cannot specify both --save_as and " "--save_in") saveas = config["save_as"] elif config["save_in"]: saveas = os.path.join(config["save_in"], torrent_name) else: saveas = torrent_namef self.d.set_torrent_values( metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes) ) self.torrent = self.multitorrent.start_torrent(metainfo, self.config, self, saveas) except BTFailure, e: globals()["torrentStatus"] = 0 logIt(str(e)) return
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 run(self, scrwin): def reread(): self.multitorrent.rawserver.external_add_task(self.reread_config,0) def ulrate(value): self.multitorrent.set_option('max_upload_rate', value) self.torrent.set_option('max_upload_rate', value) self.d = CursesDisplayer(scrwin, self.errlist, self.doneflag, reread, ulrate) try: self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error) # raises BTFailure if bad metainfo = ConvertedMetainfo(bdecode(self.metainfo)) torrent_name = metainfo.name_fs if config['save_as']: if config['save_in']: raise BTFailure(_("You cannot specify both --save_as and " "--save_in")) saveas = config['save_as'] elif config['save_in']: saveas = os.path.join(config['save_in'], torrent_name) else: saveas = torrent_name self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes)) self.torrent = self.multitorrent.start_torrent(metainfo, Preferences(self.config), self, saveas) except BTFailure, e: errlist.append(str(e)) return
def run(self, scrwin): def reread(): self.multitorrent.rawserver.external_add_task(self.reread_config,0) self.d = CursesDisplayer(scrwin, self.errlist, self.doneflag, reread) try: self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error) # raises BTFailure if bad metainfo = ConvertedMetainfo(bdecode(self.metainfo)) torrent_name = metainfo.name_fs if config['save_as']: if config['save_in']: raise BTFailure('You cannot specify both --save_as and ' '--save_in') saveas = config['save_as'] elif config['save_in']: saveas = os.path.join(config['save_in'], torrent_name) else: saveas = torrent_name self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes)) self.torrent = self.multitorrent.start_torrent(metainfo, self.config, self, saveas) except BTFailure, e: errlist.append(str(e)) return
def run(self): self.d = HeadlessDisplayer(self.doneflag) try: self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error) # raises BTFailure if bad metainfo = ConvertedMetainfo(bdecode(self.metainfo)) torrent_name = metainfo.name_fs if config['save_as']: if config['save_in']: raise BTFailure( _("You cannot specify both --save_as and " "--save_in")) saveas = config['save_as'] elif config['save_in']: saveas = os.path.join(config['save_in'], torrent_name) else: saveas = torrent_name self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes)) self.torrent = self.multitorrent.start_torrent( metainfo, Preferences(self.config), self, saveas) except BTFailure, e: print str(e) return
def torrent_hash(fname): f = open(fname, 'rb') d = bdecode(f.read()) f.close() check_message(d) hash = hashlib.sha1(bencode(d['info'])).hexdigest().upper() fn = os.path.basename(fname) return '%s - %s' % (hash,fn)
def postrequest(self, data): try: r = bdecode(data) check_peers(r) except BTFailure, e: if data != '': self.errorfunc(ERROR, 'bad data from tracker - ' + str(e)) return
def start_new_torrent(self, data, save_as=None): t = TorrentInfo(Preferences(self.config)) try: t.metainfo = ConvertedMetainfo(bdecode(data)) except Exception, e: self.global_error(ERROR, _("This is not a valid torrent file. (%s)") % str(e)) return
def start_new_torrent(self, data): t = TorrentInfo() try: t.metainfo = ConvertedMetainfo(bdecode(data)) except Exception, e: self.global_error(ERROR, "This is not a valid torrent file. (%s)" % str(e)) return
def torrent_hash(fname): f = open(fname, 'rb') d = bdecode(f.read()) f.close() check_message(d) hash = hashlib.sha1(bencode(d['info'])).hexdigest().upper() fn = os.path.basename(fname) return '%s - %s' % (hash, fn)
def getTorrent(self, data, url, handler=None, pieces=[], keepAlive=None, finishTimeout=0): metainfo = ConvertedMetainfo(bdecode(data)) config = self.getConfig(pieces, keepAlive) info = TorrentInfo(metainfo, config, handler, keepAlive, url, finishTimeout) torrent = self.multitorrent.start_torrent(metainfo, config, self, info.pathName) config['#torrent'] = torrent self.torrentInfo[torrent] = info return (info.pathName, torrent)
def saferetrieve(url, fname, min_megabytes, max_megabytes, ref = None, headers = {}): badurls = [] for b in badurls: if url.find(b)!=-1: print "bad url", url, b return False global bdecode try: if not url.startswith("http"): url = "http:" + url print "Trying", url, headers tmpname = join("/tmp",basename(fname)) cache.urlretrieve(url, tmpname, ref = ref, headers = headers) if exists(tmpname) and getsize(tmpname)>1000: print "Retrieved!",url if bdecode: try: torr = bdecode(open(tmpname).read()) except ValueError, e: print "can't decode", e, tmpname return False bd = torr['info'] try: ret = checkLength(bd, min_megabytes, max_megabytes) if not ret: return False except KeyError: assert "files" in bd,bd.keys() if 'files' in bd: # folder torrent print bd['files'] for info in bd['files']: path = info['path'][-1] if path.find(".wmv")!=-1: print "Found %s, bad torrent!"%path return False if path.find("mp4") !=-1 or path.find("avi")!=-1 or path.find("mkv")!=-1: ret = checkLength(info, min_megabytes, max_megabytes) if not ret: return False trackers = [] if "announce-list" in torr: for x in torr['announce-list']: trackers.extend(x) if "announce" in torr: trackers.append(torr["announce"]) badtrackers = ["http://tracker.hexagon.cc:2710/announce", "http://tracker.thepiratebay.org/announce"] good = [x for x in trackers if x not in badtrackers] if len(good) == 0: print "no good trackers", trackers, torr return False move(tmpname, fname) return True else:
def start_new_torrent(self, data, save_as=None): t = TorrentInfo(Preferences(self.config)) try: t.metainfo = ConvertedMetainfo(bdecode(data)) except Exception, e: self.global_error( ERROR, _("This is not a valid torrent file. (%s)") % str(e)) return
def prefetch(self, url, callback, *args, **kwargs): record = self.feedStore[url] torrentFile = file(record.torrentFile, 'rb') data = torrentFile.read() torrentFile.close() largestInfo = LargestFileInfo(ConvertedMetainfo(bdecode(data))) pathName, torrent = self.btControl.getTorrent(data, url, self, [largestInfo.begin[0]], finishTimeout=300) self.activeTorrents[torrent] = (url, None, pathName, callback, args, kwargs) self.urlMap[url] = torrent
def transformEnclosure(self, url, enclosure, data): # TODO: Remove this call from here: from BitTorrent.ConvertedMetainfo import set_filesystem_encoding set_filesystem_encoding('', None) try: metainfo = ConvertedMetainfo(bdecode(data)) except BTFailure, e: message = 'Error reading .torrent file %s: %s' % (url, e) self.failTorrent(url, enclosure, message) return
def __init__(self, feedFetcher, url): super(TorrentPrefetcher, self).__init__() self.rawServer = feedFetcher.rawServer self.torrentFetcher = feedFetcher.torrentFetcher self.display = feedFetcher.display self.config = feedFetcher.config self.url = url self.record = feedFetcher.feedStore[url] torrentFile = file(self.record.torrentFile, 'rb') self.metainfo = ConvertedMetainfo(bdecode(torrentFile.read())) torrentFile.close()
def make_meta_file_dht(path, nodes, piece_len_exp, flag=Event(), progress=dummy, comment=None, target=None, encoding='ascii', data_dir=None): # if nodes is empty, then get them out of the routing table in data_dir # else, expect nodes to be a string of comma seperated <ip>:<port> pairs # this has a lot of duplicated code from make_meta_file piece_length = 2**piece_len_exp a, b = os.path.split(path) if not target: if b == '': f = a + '.torrent' else: f = os.path.join(a, b + '.torrent') else: f = target info = makeinfo(path, piece_length, flag, progress, encoding) if flag.isSet(): return check_info(info) info_hash = sha(bencode(info)).digest() if not nodes: x = open(os.path.join(data_dir, 'routing_table'), 'rb') d = bdecode(x.read()) x.close() t = KTable(Node().initWithDict({ 'id': d['id'], 'host': '127.0.0.1', 'port': 0 })) for n in d['rt']: t.insertNode(Node().initWithDict(n)) nodes = [(node.host, node.port) for node in t.findNodes(info_hash) if node.host != '127.0.0.1'] else: nodes = [ (a[0], int(a[1])) for a in [node.strip().split(":") for node in nodes.split(",")] ] data = {'nodes': nodes, 'creation date': int(time())} h = file(f, 'wb') data['info'] = info if comment: data['comment'] = comment h.write(bencode(data)) h.close()
def fetch(self, url, writer): # TODO: check for new version of torrent file if expired. record = self.feedStore[url] # TODO: download torrent file if not exists torrentFile = file(record.torrentFile, 'rb') data = torrentFile.read() torrentFile.close() largestInfo = LargestFileInfo(ConvertedMetainfo(bdecode(data))) keepAlive = KeepAlive(writer, largestInfo, self.btControl.display) pathName, torrent = self.btControl.getTorrent(data, url, self, keepAlive=keepAlive) self.activeTorrents[torrent] = (url, writer, pathName, None, None, None) self.urlMap[url] = torrent
def decodeTorrent(self, data): """\ Converts bencoded raw metadata (as one would find in a .torrent file) into a metainfo object (which one can then get the torrent's properties from). """ from BitTorrent.bencode import bdecode, bencode metainfo = None try: b = bdecode(data) metainfo = ConvertedMetainfo(b) except Exception, e: pass
def _load(self): do_load = False try: s = open(os.path.join(self.ddir, "routing_table"), 'r').read() dict = bdecode(s) except: id = newID() else: id = dict['id'] do_load = True self.node = self._Node(self.udp.connectionForAddr).init(id, self.host, self.port) self.table = KTable(self.node) if do_load: self._loadRoutingTable(dict['rt'])
def _postrequest(self, data=None, errormsg=None, peerid=None): self.current_started = None self.last_time = bttime() if errormsg is not None: self.errorfunc(WARNING, errormsg) self._fail() return try: r = bdecode(data) check_peers(r) except BTFailure, e: if data != '': self.errorfunc(ERROR, _("bad data from tracker - ") + str(e)) self._fail() return
def get_parsed(self): """Return the parsed metainfo (BitTorrent.ConvertedMetainfo).""" if not hasattr(self, 'metainfo_parsed'): from BitTorrent.bencode import bdecode from BitTorrent.ConvertedMetainfo import ConvertedMetainfo import base64 # Interesting keys in metainfo: # 'hashes', 'infohash', 'is_batch', 'name', 'name_fs', 'orig_files', # 'piece_length', 'reported_errors', 'show_encoding_errors', 'sizes', # 'total_bytes'] self.metainfo_parsed = ConvertedMetainfo(bdecode(base64.decodestring(self.metainfo))) return self.metainfo_parsed
def _load(self): do_load = False try: s = open(os.path.join(self.ddir, "routing_table"), 'r').read() dict = bdecode(s) except: id = newID() else: id = dict['id'] do_load = True self.node = self._Node(self.udp.connectionForAddr).init( id, self.host, self.port) self.table = KTable(self.node) if do_load: self._loadRoutingTable(dict['rt'])
def run(self): self.d = HeadlessDisplayer(self.doneflag) try: self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error) # raises BTFailure if bad metainfo = ConvertedMetainfo(bdecode(self.metainfo)) torrent_name = metainfo.name_fs saveas = os.path.join(self.config['save_in'], torrent_name) self.d.set_torrent_values(metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes)) self.torrent = self.multitorrent.start_torrent(metainfo, Preferences(self.config), self, saveas) except BTFailure, e: self.log.exception("Problem running torrent") return
def _postrequest(self, data=None, errormsg=None, peerid=None): self.current_started = None self.last_time = bttime() if errormsg is not None: self.errorfunc(WARNING, errormsg) self._fail() return #check that the answer from the tracker is correctly formated try: r = bdecode(data) self.logcollector.log(None, 'RT NL ' + str(r.get('incomplete', 0)) + ' NS ' + str(r.get('complete', 0))) check_peers(r) except BTFailure, e: if data != '': self.errorfunc(ERROR, 'bad data from tracker - ' + str(e)) self._fail() return
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 make_meta_file_dht(path, nodes, piece_len_exp, flag=Event(), progress=dummy, title=None, comment=None, target=None, data_dir=None): # if nodes is empty, then get them out of the routing table in data_dir # else, expect nodes to be a string of comma seperated <ip>:<port> pairs # this has a lot of duplicated code from make_meta_file piece_length = 2 ** piece_len_exp a, b = os.path.split(path) if not target: if b == '': f = a + '.torrent' else: f = os.path.join(a, b + '.torrent') else: f = target info = makeinfo(path, piece_length, flag, progress) if flag.isSet(): return check_info(info) info_hash = sha(bencode(info)).digest() if not nodes: x = open(os.path.join(data_dir, 'routing_table'), 'rb') d = bdecode(x.read()) x.close() t = KTable(Node().initWithDict({'id':d['id'], 'host':'127.0.0.1','port': 0})) for n in d['rt']: t.insertNode(Node().initWithDict(n)) nodes = [(node.host, node.port) for node in t.findNodes(info_hash) if node.host != '127.0.0.1'] else: nodes = [(a[0], int(a[1])) for a in [node.strip().split(":") for node in nodes.split(",")]] data = {'nodes': nodes, 'creation date': int(time())} h = file(f, 'wb') data['info'] = info if title: data['title'] = title if comment: data['comment'] = comment h.write(bencode(data)) h.close()
def _postrequest(self, data=None, errormsg=None, exc=None, peerid=None): assert thread.get_ident() == self.rawserver.ident self.current_started = None self.errorfunc(logging.INFO, 'postrequest: ' + str(self.current_started)) self.last_time = bttime() if self.dead: return if errormsg is not None: self.errorfunc(logging.WARNING, errormsg) self._fail(exc) return try: r = bdecode(data) check_peers(r) except BTFailure, e: if data != '': self.errorfunc(logging.ERROR, _("bad data from tracker (%s)") % repr(data), exc_info=sys.exc_info()) self._fail() return
def showInfo(self, torrent): decoded = bdecode(torrent) info = decoded.get("info", None) if info is not None: name = info.get("name", "??") length = info.get("length", "??") date = decoded.get("creation date", "??") creator = decoded.get("created by", "??") announce = decoded.get("announce", "??") comment = decoded.get("comment", "??") infotuple = (name, comment, length, date, creator) infostring = "Name:%s\nComment:%s\nLength:%s\nCreation_Date:%s\nCreated_by:%s\n ----- \n" % infotuple # move info container in front of everthig self.send("Forward", "infomover_commands") self.send("Play", "infomover_commands") self.send(infostring, "torrent_info")
def run(self): try: self.multitorrent = Multitorrent(self.config, self.doneflag, self.global_error) # raises BTFailure if bad metainfo = ConvertedMetainfo(bdecode(self.metainfo)) torrent_name = metainfo.name_fs if self.config["save_as"]: if self.config["save_in"]: raise BTFailure(_("You cannot specify both --save_as and " "--save_in")) saveas = self.config["save_as"] elif self.config["save_in"]: saveas = os.path.join(self.config["save_in"], torrent_name) else: saveas = torrent_name self.d.set_torrent_values( metainfo.name, os.path.abspath(saveas), metainfo.total_bytes, len(metainfo.hashes) ) self.torrent = self.multitorrent.start_torrent(metainfo, Preferences(self.config), self, saveas) except BTFailure, e: print str(e) return
def _restore_state(self): def decode_line(line): hashtext = line[:40] try: infohash = hashtext.decode('hex') except: raise BTFailure(_("Invalid state file contents")) if len(infohash) != 20: raise BTFailure(_("Invalid state file contents")) try: path = os.path.join(self.config['data_dir'], 'metainfo', hashtext) f = file(path, 'rb') data = f.read() f.close() except Exception, e: try: f.close() except: pass self.global_error( ERROR, (_("Error reading file \"%s\".") % path) + " (" + str(e) + "), " + _("cannot restore state completely")) return None if infohash in self.torrents: raise BTFailure(_("Invalid state file (duplicate entry)")) t = TorrentInfo(Preferences(self.config)) self.torrents[infohash] = t try: t.metainfo = ConvertedMetainfo(bdecode(data)) except Exception, e: self.global_error( ERROR, (_("Corrupt data in \"%s\", cannot restore torrent.") % path) + '(' + str(e) + ')') return None
def init(self): self = super(Generate, self).init() appDefaults = { ANNOUNCEKEY: bencode([]), COMPLETEDIRKEY: 0, GWINKEY: "", SWITCHKEY: 1 } defaults.registerDefaults_(appDefaults) x = defaults.objectForKey_(ANNOUNCEKEY) try: self.trackers = bdecode(x) except ValueError: if x[:7] == "http://": self.trackers = [str(x.encode("utf-8"))] else: self.trackers = [] defaults.setObject_forKey_(bencode(self.trackers), ANNOUNCEKEY) NSBundle.loadNibNamed_owner_("Metainfo", self) self.fname = None self.done = 0 self.gWindow.registerForDraggedTypes_([NSFilenamesPboardType]) self.gWindow.setFrameAutosaveName_(GWINKEY) self.gWindow.setFrameUsingName_(GWINKEY) try: self.announce.setStringValue_(self.trackers[0]) except IndexError: pass self.subCheck.setState_(defaults.objectForKey_(COMPLETEDIRKEY)) self.trackerPop.selectItemAtIndex_(defaults.objectForKey_(SWITCHKEY)) self.popped_(self.trackerPop) return self
def torrentInfo(torrentData): from BitTorrent.bencode import bdecode info = bdecode(torrentData)["info"] return info
# Version 1.0 (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 Henry 'Pi' James and Bram Cohen from sys import argv from BitTorrent.bencode import bencode, bdecode if len(argv) < 3: print '%s http://new.uri:port/announce file1.torrent file2.torrent' % argv[ 0] print exit(2) # common exit code for syntax error for f in argv[2:]: h = open(f, 'rb') metainfo = bdecode(h.read()) h.close() if metainfo['announce'] != argv[1]: print 'old announce for %s: %s' % (f, metainfo['announce']) metainfo['announce'] = argv[1] h = open(f, 'wb') h.write(bencode(metainfo)) h.close()
class Updater(object): def __init__(self, threadwrap, newversionfunc, startfunc, installfunc, errorfunc, test_new_version='', test_current_version=''): self.threadwrap = threadwrap # for calling back to UI from thread self.newversionfunc = newversionfunc # alert to new version UI function self.startfunc = startfunc # start torrent UI function self.installfunc = installfunc # install torrent UI function self.errorfunc = errorfunc # report error UI function self.infohash = None self.version = currentversion self.currentversion = currentversion self.asked_for_install = False self.version_site = version_host if os.name == 'nt': self.version_site += 'win32/' if os_version not in ('XP', '2000', '2003'): self.version_site += 'legacy/' elif osx: self.version_site += 'osx/' self.debug_mode = DEBUG if test_new_version: test_new_version = Version.from_str(test_new_version) self.debug_mode = True def _hack_get_available(url): return test_new_version self._get_available = _hack_get_available if test_current_version: self.debug_mode = True self.currentversion = Version.from_str(test_current_version) def debug(self, message): if self.debug_mode: self.threadwrap(self.errorfunc, WARNING, message) def _get_available(self, url): self.debug('Updater.get_available() hitting url %s' % url) try: u = zurllib.urlopen(url) s = u.read() s = s.strip() except: raise BTFailure(_("Could not get latest version from %s") % url) try: assert len(s) == 5 availableversion = Version.from_str(s) except: raise BTFailure( _("Could not parse new version string from %s") % url) return availableversion def get_available(self): url = self.version_site + self.currentversion.name() availableversion = self._get_available(url) if availableversion.is_beta(): if availableversion[1] != self.currentversion[1]: availableversion = self.currentversion if self.currentversion.is_beta(): stable_url = self.version_site + 'stable' available_stable_version = self._get_available(stable_url) if available_stable_version > availableversion: availableversion = available_stable_version self.version = availableversion self.debug('Updater.get_available() got %s' % str(self.version)) return self.version def get(self): try: self.get_available() except BTFailure, e: self.threadwrap(self.errorfunc, WARNING, e) return if self.version <= self.currentversion: self.debug('Updater.get() not updating old version %s' % str(self.version)) return if not self.can_install(): self.debug('Updater.get() cannot install on this os') return self.installer_name = self.calc_installer_name() self.installer_url = self.version_site + self.installer_name + '.torrent' self.installer_dir = self.calc_installer_dir() self.torrentfile = None torrentfile, terrors = GetTorrent.get_url(self.installer_url) signature = None try: signfile = zurllib.urlopen(self.installer_url + '.sign') except: self.debug('Updater.get() failed to get signfile %s.sign' % self.installer_url) else: try: signature = pickle.load(signfile) except: self.debug('Updater.get() failed to load signfile %s' % signfile) if terrors: self.threadwrap(self.errorfunc, WARNING, '\n'.join(terrors)) if torrentfile and signature: public_key_file = open(os.path.join(doc_root, 'public.key'), 'rb') public_key = pickle.load(public_key_file) h = sha(torrentfile).digest() if public_key.verify(h, signature): self.torrentfile = torrentfile b = bdecode(torrentfile) self.infohash = sha(bencode(b['info'])).digest() self.total_size = b['info']['length'] self.debug('Updater.get() got torrent file and signature') else: self.debug( 'Updater.get() torrent file signature failed to verify.') pass else: self.debug( 'Updater.get() doesn\'t have torrentfile %s and signature %s' % (str(type(torrentfile)), str(type(signature))))
def __init__(self, config, rawserver): self.config = config self.response_size = config['response_size'] self.max_give = config['max_give'] self.dfile = config['dfile'] self.natcheck = config['nat_check'] favicon = config['favicon'] self.favicon = None if favicon: try: h = open(favicon, 'r') self.favicon = h.read() h.close() except: print _( "**warning** specified favicon file -- %s -- does not exist." ) % favicon self.rawserver = rawserver self.cached = { } # format: infohash: [[time1, l1, s1], [time2, l2, s2], [time3, l3, s3]] self.cached_t = {} # format: infohash: [time, cache] self.times = {} self.state = {} self.seedcount = {} self.only_local_override_ip = config['only_local_override_ip'] if self.only_local_override_ip == 2: self.only_local_override_ip = not config['nat_check'] if os.path.exists(self.dfile): try: h = open(self.dfile, 'rb') ds = h.read() h.close() tempstate = bdecode(ds) if not tempstate.has_key('peers'): tempstate = {'peers': tempstate} statefiletemplate(tempstate) self.state = tempstate except: print _("**warning** statefile %s corrupt; resetting") % \ self.dfile self.downloads = self.state.setdefault('peers', {}) self.completed = self.state.setdefault('completed', {}) self.becache = {} # format: infohash: [[l1, s1], [l2, s2], [l3, s3]] for infohash, ds in self.downloads.items(): self.seedcount[infohash] = 0 for x, y in ds.items(): if not y.get('nat', -1): ip = y.get('given_ip') if not (ip and self.allow_local_override(y['ip'], ip)): ip = y['ip'] self.natcheckOK(infohash, x, ip, y['port'], y['left']) if not y['left']: self.seedcount[infohash] += 1 for infohash in self.downloads: self.times[infohash] = {} for peerid in self.downloads[infohash]: self.times[infohash][peerid] = 0 self.reannounce_interval = config['reannounce_interval'] self.save_dfile_interval = config['save_dfile_interval'] self.show_names = config['show_names'] rawserver.add_task(self.save_dfile, self.save_dfile_interval) self.prevtime = time() self.timeout_downloaders_interval = config[ 'timeout_downloaders_interval'] rawserver.add_task(self.expire_downloaders, self.timeout_downloaders_interval) self.logfile = None self.log = None if (config['logfile'] != '') and (config['logfile'] != '-'): try: self.logfile = config['logfile'] self.log = open(self.logfile, 'a') sys.stdout = self.log print _("# Log Started: "), isotime() except: print _("**warning** could not redirect stdout to log file: " ), sys.exc_info()[0] if config['hupmonitor']: def huphandler(signum, frame, self=self): try: self.log.close() self.log = open(self.logfile, 'a') sys.stdout = self.log print _("# Log reopened: "), isotime() except: print _("**warning** could not reopen logfile") signal.signal(signal.SIGHUP, huphandler) self.allow_get = config['allow_get'] if config['allowed_dir'] != '': self.allowed_dir = config['allowed_dir'] self.parse_dir_interval = config['parse_dir_interval'] self.allowed = self.state.setdefault('allowed', {}) self.allowed_dir_files = self.state.setdefault( 'allowed_dir_files', {}) self.allowed_dir_blocked = {} self.parse_allowed() else: try: del self.state['allowed'] except: pass try: del self.state['allowed_dir_files'] except: pass self.allowed = None self.uq_broken = unquote('+') != ' ' self.keep_dead = config['keep_dead']
def init(self): self = super(BTAppController, self).init() self.prefs = Preferences.alloc().init() self.prefwindow = None self.generator = Generate.alloc().init() self.ic = ICHelper.alloc().init() # displayed torrent controllers self.torrents = [] # waiting to die self.dead_torrents = [] # ready to start # (<open panel>, <insert row>, (<filename>|<stream>, <is_stream>)) -1 insert row means use last row # stream = 0 if filename, 1 if bencoded torrent file self.tqueue = [] self.retain() self.inited = 0 self.launched = 0 self.in_choose = 0 self.last_qcheck = time() self.sc = 0 self.defaults = NSUserDefaults.standardUserDefaults() self.tup = bdecode(self.defaults.objectForKey_(ULBYTES)) self.tdown = bdecode(self.defaults.objectForKey_(DLBYTES)) self.config = common_options + rare_options self.config = BTPreferences().initWithDict( dict([(name, value) for (name, value, doc) in self.config])) self.config['data_dir'] = PREFDIR self.config['bind'] = '' self.config['bad_libc_workaround'] = True self.config['filesystem_encoding'] = 'utf8' #XXXX #self.config['start_trackerless_client'] = False self.legacyConfig() self.reloadConfig() self.pyi = None self.doneflag = Event() if not os.path.exists(PREFDIR): os.mkdir(PREFDIR) if not os.path.exists(RESDIR): os.mkdir(RESDIR) self.ticon = None self.stalled = [] self.terminated = False return self
def testBencode(self): #x = list('1234554545454') #i1234554545454e #13:1234554545454 x = 'i1234554545454e' print(bencode.bdecode(x))
to_add.sort() for p in to_add: # then, parse new and changed torrents new_file = new_files[p] v = new_file[0] if new_file[1] in new_parsed: # duplicate if p not in blocked or files[p][0] != v: errfunc('**warning** ' + p + ' is a duplicate torrent for ' + new_parsed[new_file[1]]['path']) new_blocked[p] = None continue if NOISY: errfunc('adding ' + p) try: ff = open(p, 'rb') d = bdecode(ff.read()) check_message(d) h = sha(bencode(d['info'])).digest() new_file[1] = h if new_parsed.has_key(h): errfunc('**warning** ' + p + ' is a duplicate torrent for ' + new_parsed[h]['path']) new_blocked[p] = None continue a = {} a['path'] = p f = os.path.basename(p) a['file'] = f i = d['info'] l = 0