def _create(metainfo): # TODO: replace with constructor # raises ValueErrors if not good validTorrentFile(metainfo) t = TorrentDef() t.metainfo = metainfo t.metainfo_valid = True # copy stuff into self.input maketorrent.copy_metainfo_to_input(t.metainfo, t.input) # For testing EXISTING LIVE, or EXISTING MERKLE: DISABLE, i.e. keep true infohash if t.get_url_compat(): t.infohash = makeurl.metainfo2swarmid(t.metainfo) else: # Two places where infohash calculated, here and in maketorrent.py # Elsewhere: must use TorrentDef.get_infohash() to allow P2PURLs. t.infohash = sha(bencode(metainfo['info'])).digest() assert isinstance( t.infohash, str), "INFOHASH has invalid type: %s" % type(t.infohash) assert len( t.infohash ) == INFOHASH_LENGTH, "INFOHASH has invalid length: %d" % len( t.infohash) #print >>sys.stderr,"INFOHASH",`t.infohash` return t
def make_torrent_file(input, userabortflag=None, userprogresscallback=lambda x: None): """ Create a torrent file from the supplied input. Returns a (infohash,metainfo) pair, or (None,None) on userabort. """ (info, piece_length) = makeinfo(input, userabortflag, userprogresscallback) if userabortflag is not None and userabortflag.isSet(): return None, None if info is None: return None, None metainfo = {'info': info, 'encoding': input['encoding'], 'creation date': long(time())} validTorrentFile(metainfo) # http://www.bittorrent.org/DHT_protocol.html says both announce and nodes # are not allowed, but some torrents (Azureus?) apparently violate this. if input['nodes'] is None and input['announce'] is None: raise ValueError('No tracker set') for key in ['announce', 'announce-list', 'nodes', 'comment', 'created by', 'httpseeds', 'url-list']: if input[key] is not None and len(input[key]) > 0: metainfo[key] = input[key] if key == 'comment': metainfo['comment.utf-8'] = uniconvert(input['comment'], 'utf-8') if 'private' in input: metainfo['info']['private'] = input['private'] if 'anonymous' in input: metainfo['info']['anonymous'] = input['anonymous'] # Two places where infohash calculated, here and in TorrentDef. # Elsewhere: must use TorrentDef.get_infohash() to allow P2PURLs. infohash = sha1(bencode(info)).digest() return infohash, metainfo
def test_valid_torrent_file_info_name_wrong_type(self): validTorrentFile({ "info": { "name": 42, "piece length": 12345, "pieces": "12345678901234567890" } })
def test_valid_torrent_file_info_piece_size_wrong_type(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": "12345", "pieces": "12345678901234567890" } })
def test_valid_torrent_file_root_hash_wrong_length(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "root hash": "12345" } })
def test_valid_torrent_file_info_no_files(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "files": [] } })
def test_valid_torrent_root_hash(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "root hash": "12345678901234567890", "files": [] } })
def test_valid_torrent_file_url_list_empty(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "length": 42 }, "url-list": [] })
def test_valid_torrent_file_url_list_string(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "length": 42 }, "url-list": "http://google.com" })
def test_valid_torrent_file_httpseeds_empty(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "length": 42 }, "httpseeds": [] })
def test_valid_torrent_file_announce_list_correct(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "length": 42 }, "announce-list": [[]] })
def test_valid_torrent_file_httpseeds_valid_url(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "length": 42 }, "httpseeds": ["http://google.com"] })
def test_valid_torrent_file_info_files_missing_path(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "files": [{ "length": 42 }] } })
def test_valid_torrent_file_info_files_path_correct(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "files": [{ "length": 42, "path": ["/foo/bar"] }] } })
def test_valid_torrent_file_info_files_length_wrong_type(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "files": [{ "length": "42", "path": [] }] } })
def _create(metainfo): # TODO: replace with constructor # raises ValueErrors if not good validTorrentFile(metainfo) t = TorrentDef() t.metainfo = metainfo t.metainfo_valid = True t.infohash = sha.sha(bencode(metainfo['info'])).digest() # copy stuff into self.input maketorrent.copy_metainfo_to_input(t.metainfo, t.input) return t
def test_valid_torrent_file_url_list_files(self): validTorrentFile({ "info": { "name": "my_torrent", "piece length": 12345, "pieces": "12345678901234567890", "files": [{ "length": 42, "path": ["/foo/bar"] }] }, "url-list": [] })
def _create(metainfo): # TODO: replace with constructor # raises ValueErrors if not good validTorrentFile(metainfo) t = TorrentDef() t.metainfo = metainfo t.metainfo_valid = True t.infohash = sha.sha(bencode(metainfo['info'])).digest() # copy stuff into self.input maketorrent.copy_metainfo_to_input(t.metainfo,t.input) return t
def _create(metainfo): # TODO: replace with constructor # raises ValueErrors if not good validTorrentFile(metainfo) t = TorrentDef() t.metainfo = metainfo t.metainfo_valid = True # copy stuff into self.input maketorrent.copy_metainfo_to_input(t.metainfo, t.input) # Two places where infohash calculated, here and in maketorrent.py # Elsewhere: must use TorrentDef.get_infohash() to allow P2PURLs. t.infohash = sha1(bencode(metainfo['info'])).digest() assert isinstance(t.infohash, str), "INFOHASH has invalid type: %s" % type(t.infohash) assert len(t.infohash) == INFOHASH_LENGTH, "INFOHASH has invalid length: %d" % len(t.infohash) return t
def make_torrent_file(input, userabortflag=None, userprogresscallback=lambda x: None): """ Create a torrent file from the supplied input. Returns a (infohash,metainfo) pair, or (None,None) on userabort. """ (info, piece_length) = makeinfo(input, userabortflag, userprogresscallback) if userabortflag is not None and userabortflag.isSet(): return None, None if info is None: return None, None metainfo = { 'info': info, 'encoding': input['encoding'], 'creation date': long(time()) } validTorrentFile(metainfo) # http://www.bittorrent.org/beps/bep_0005.html says both announce and nodes # are not allowed, but some torrents (Azureus?) apparently violate this. if input['nodes'] is None and input['announce'] is None: raise ValueError('No tracker set') for key in [ 'announce', 'announce-list', 'nodes', 'comment', 'created by', 'httpseeds', 'url-list' ]: if input[key] is not None and len(input[key]) > 0: metainfo[key] = input[key] if key == 'comment': metainfo['comment.utf-8'] = uniconvert(input['comment'], 'utf-8') if 'private' in input: metainfo['info']['private'] = input['private'] if 'anonymous' in input: metainfo['info']['anonymous'] = input['anonymous'] # Two places where infohash calculated, here and in TorrentDef. # Elsewhere: must use TorrentDef.get_infohash() to allow P2PURLs. infohash = sha1(bencode(info)).digest() return infohash, metainfo
def _create(metainfo): # TODO: replace with constructor # raises ValueErrors if not good validTorrentFile(metainfo) t = TorrentDef() t.metainfo = metainfo t.metainfo_valid = True # copy stuff into self.input maketorrent.copy_metainfo_to_input(t.metainfo, t.input) # For testing EXISTING LIVE, or EXISTING MERKLE: DISABLE, i.e. keep true infohash if t.get_url_compat(): t.infohash = makeurl.metainfo2swarmid(t.metainfo) else: # Two places where infohash calculated, here and in maketorrent.py # Elsewhere: must use TorrentDef.get_infohash() to allow P2PURLs. t.infohash = sha(bencode(metainfo["info"])).digest() # print >>sys.stderr,time.asctime(),'-', "INFOHASH",`t.infohash` return t
def _create(metainfo): # TODO: replace with constructor # raises ValueErrors if not good validTorrentFile(metainfo) t = TorrentDef() t.metainfo = metainfo t.metainfo_valid = True # copy stuff into self.input maketorrent.copy_metainfo_to_input(t.metainfo,t.input) # For testing EXISTING LIVE, or EXISTING MERKLE: DISABLE, i.e. keep true infohash if t.get_url_compat(): t.infohash = makeurl.metainfo2swarmid(t.metainfo) else: # Two places where infohash calculated, here and in maketorrent.py # Elsewhere: must use TorrentDef.get_infohash() to allow P2PURLs. t.infohash = sha(bencode(metainfo['info'])).digest() assert isinstance(t.infohash, str), "INFOHASH has invalid type: %s" % type(t.infohash) assert len(t.infohash) == INFOHASH_LENGTH, "INFOHASH has invalid length: %d" % len(t.infohash) #print >>sys.stderr,"INFOHASH",`t.infohash` return t
def test_valid_torrent_file_nodes_invalid_length(self): validTorrentFile({"info": {}, "nodes": [["a", "b", "c"]]})
def test_valid_torrent_file_info_wrong_type(self): validTorrentFile({"info": []})
def test_valid_torrent_file_announce_dht_invalid_url(self): validTorrentFile({"info": {}, "announce": "dht:test"})
def test_valid_torrent_file_nodes_invalid_node_type(self): validTorrentFile({"info": {}, "nodes": [{}]})
def test_valid_torrent_file_invalid_metainfo_type(self): validTorrentFile([])
def make_torrent_file(input, userabortflag=None, userprogresscallback=lambda x: None): """ Create a torrent file from the supplied input. Returns a (infohash,metainfo) pair, or (None,None) on userabort. """ (info, piece_length) = makeinfo(input, userabortflag, userprogresscallback) if userabortflag is not None and userabortflag.isSet(): return (None, None) if info is None: return (None, None) # if DEBUG: # print >>sys.stderr,"mktorrent: makeinfo returned",`info` metainfo = {'info': info, 'encoding': input['encoding'], 'creation date': long(time())} validTorrentFile(metainfo) # http://www.bittorrent.org/DHT_protocol.html says both announce and nodes # are not allowed, but some torrents (Azureus?) apparently violate this. if input['nodes'] is None and input['announce'] is None: raise ValueError('No tracker set') for key in ['announce', 'announce-list', 'nodes', 'comment', 'created by', 'httpseeds', 'url-list']: if input[key] is not None and len(input[key]) > 0: metainfo[key] = input[key] if key == 'comment': metainfo['comment.utf-8'] = uniconvert(input['comment'], 'utf-8') # Assuming 1 file, Azureus format no support multi-file torrent with diff # bitrates bitrate = None for file in input['files']: if file['playtime'] is not None: secs = parse_playtime_to_secs(file['playtime']) bitrate = file['length'] / secs break if input.get('bps') is not None: bitrate = input['bps'] break if bitrate is not None or input['thumb'] is not None: mdict = {} mdict['Publisher'] = 'Tribler' if input['comment'] is None: descr = '' else: descr = input['comment'] mdict['Description'] = descr if bitrate is not None: mdict['Progressive'] = 1 mdict['Speed Bps'] = int(bitrate) # bencode fails for float else: mdict['Progressive'] = 0 mdict['Title'] = metainfo['info']['name'] mdict['Creation Date'] = long(time()) # Azureus client source code doesn't tell what this is, so just put in random value from real torrent mdict['Content Hash'] = 'PT3GQCPW4NPT6WRKKT25IQD4MU5HM4UY' mdict['Revision Date'] = long(time()) if input['thumb'] is not None: mdict['Thumbnail'] = input['thumb'] cdict = {} cdict['Content'] = mdict metainfo['azureus_properties'] = cdict if input['torrentsigkeypairfilename'] is not None: from Tribler.Core.Overlay.permid import create_torrent_signature create_torrent_signature(metainfo, input['torrentsigkeypairfilename']) if 'url-compat' in input: metainfo['info']['url-compat'] = input['url-compat'] # Arno, 2010-03-02: # Theoretically should go into 'info' field, to get infohash protection # because the video won't play without them. In the future we'll sign # the whole .torrent IMHO so it won't matter. Keeping it out of 'info' # at the moment makes the .tstream files more stable (in case you restart # the live source, and the Ogg header generated contains some date or # what not, we'd need a new .tstream to be distributed to all. # if 'ogg-headers' in input: metainfo['ogg-headers'] = input['ogg-headers'] # Two places where infohash calculated, here and in TorrentDef. # Elsewhere: must use TorrentDef.get_infohash() to allow P2PURLs. infohash = sha(bencode(info)).digest() return (infohash, metainfo)
def test_valid_torrent_file_root_hash(self): validTorrentFile({"info": {"root hash": "12345"}})
def test_valid_torrent_file_initial_peers_port_wrong_type(self): validTorrentFile({ "info": {}, "initial peers": [("127.0.0.1", "8081")] })
def test_valid_torrent_file_initial_peers_address_wrong_type(self): validTorrentFile({"info": {}, "initial peers": [{}]})
def test_valid_torrent_file_valid_node(self): validTorrentFile({"info": {}, "nodes": [["127.0.0.1", 8081]]})
def test_valid_torrent_file_empty_nodes(self): validTorrentFile({"info": {}, "nodes": []})
def test_valid_torrent_file_nodes_invalid_port_type(self): validTorrentFile({"info": {}, "nodes": [["127.0.0.1", "8081"]]})
def test_valid_torrent_file_nodes_invalid_host_type(self): validTorrentFile({"info": {}, "nodes": [[80, "127.0.0.1"]]})