Beispiel #1
0
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))
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
 def datagramReceived(self, str, addr):
     # bdecode
     try:
         msg = bdecode(str)
     except Exception, e:
         if self.noisy:
             print "response decode error: " + `e`, `str`
Beispiel #5
0
 def datagramReceived(self, str, addr):
     # bdecode
     try:
         msg = bdecode(str)
     except Exception, e:
         if self.noisy:
             print "response decode error: " + ` e `, ` str `
    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 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
Beispiel #9
0
    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
Beispiel #10
0
        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
Beispiel #13
0
    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)
Beispiel #16
0
 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
Beispiel #17
0
 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
Beispiel #19
0
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)
Beispiel #21
0
 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
Beispiel #22
0
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:
Beispiel #23
0
 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()
Beispiel #27
0
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
Beispiel #29
0
 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
Beispiel #30
0
    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
Beispiel #31
0
 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'])
Beispiel #32
0
 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
Beispiel #33
0
 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
Beispiel #34
0
    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
Beispiel #35
0
    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'])
Beispiel #36
0
        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
Beispiel #37
0
 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
Beispiel #41
0
    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")
Beispiel #42
0
    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
Beispiel #44
0
 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
Beispiel #45
0
    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
Beispiel #46
0
def torrentInfo(torrentData):
    from BitTorrent.bencode import bdecode
    info = bdecode(torrentData)["info"]
    return info
Beispiel #47
0
# 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()
Beispiel #48
0
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))))
Beispiel #49
0
    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
Beispiel #51
0
 def testBencode(self):
     #x = list('1234554545454')  #i1234554545454e #13:1234554545454
     x = 'i1234554545454e'
     print(bencode.bdecode(x))
Beispiel #52
0
    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