def test_decode_dict(self): self.assertDictEqual(decode(b'd3:cow3:moo4:spam4:eggse'), { b"cow": b"moo", b"spam": b"eggs" }) self.assertDictEqual(decode(b'd4:spaml1:a1:bee'), {b"spam": [b"a", b"b"]})
def test_decode_unsupported_data_type_1(): """Try to decode unsupported object (a text string)""" with pytest.raises(ValueError) as excinfo: bencode.decode("abcd") assert str(excinfo.value) == ( "Cannot decode data, expected bytes, got <class 'str'> instead.")
def test_list(self): self.assertEqual(bencode.decode('le'), []) self.assertEqual(bencode.decode('ll4:testi2eell3:fooeli3eeee'), [ ['test', 2], [ ['foo'], [3] ] ])
def test_decode_unsupported_data_type_2(): """Try to decode unsupported object (a binary string of unknown type)""" with pytest.raises(ValueError) as excinfo: bencode.decode(b"abcd") assert str(excinfo.value) == ( "Cannot decode data, expected the first byte to be one " "of 'd', 'i', 'l' or a digit, got 'a' instead.")
def test_decode_dict(self): self.assertDictEqual( decode( b'd3:cow3:moo4:spam4:eggse'), {b"cow": b"moo", b"spam": b"eggs"} ) self.assertDictEqual( decode(b'd4:spaml1:a1:bee'), {b"spam": [b"a", b"b"]} )
def test_dict(self): self.assertEqual(bencode.decode('de'), {}) self.assertEqual(bencode.decode('d3:fool3:bard4:testl5:againi12eeee4:testi12ee'), { 'test': 12, 'foo': [ 'bar', {'test': ['again', 12]} ] }) self.assertRaises(ValueError, bencode.decode, 'di1ei1ee')
def test_decode_dictionary(self): self.assertEqual(decode(b'de'), {}) self.assertEqual(decode(b'd1:1i1ee'), {'1': 1}) self.assertEqual(decode(b'd1:1i1e4:abcd3:abce'), { '1': 1, 'abcd': 'abc' }) self.assertEqual(decode(b'd0:i1e4:abcd3:abce'), {'': 1, 'abcd': 'abc'}) self.assertEqual(decode(b'd1:ali10e3:abcded1:a1:beee'), {'a': [10, 'abc', {}, { 'a': 'b' }]})
def test_05_Message_GetList_decode_01(self): decoded = decode("d4:txidi123e4:type7:getliste") msg = Message_GetList(decoded[str.encode("type")], decoded[str.encode("txid")], bytes_=True) self.assertEqual(msg.type_, 'getlist') self.assertEqual(msg.txid_, 123)
def test_17_Message_Ack_decode_01(self): decoded = decode("d4:txidi123e4:type3:acke") msg = Message_Ack(decoded[str.encode("type")], decoded[str.encode("txid")], bytes_=True) self.assertEqual(msg.type_, 'ack') self.assertEqual(msg.txid_, 123)
def test_15_Message_Disconnect_decode_01(self): decoded = decode("d4:txidi123e4:type10:disconnecte") msg = Message_Disconnect(decoded[str.encode("type")], decoded[str.encode("txid")], bytes_=True) self.assertEqual(msg.type_, 'disconnect') self.assertEqual(msg.txid_, 123)
def test_09_Message_List_decode_01(self): decoded = decode( "d5:peersd1:0d4:ipv49:192.0.2.14:porti34567e8:username8:xlogin00e1:1d4:ipv49:192.0.2.24:porti45678e8:username8:xnigol99ee4:txidi123e4:type4:liste" ) records = Peer_Records() for i in range(len(decoded[str.encode("peers")].keys())): rec = Peer_Record(decoded[str.encode("peers")][str.encode( str(i))][str.encode("username")], decoded[str.encode("peers")][str.encode( str(i))][str.encode("ipv4")], decoded[str.encode("peers")][str.encode( str(i))][str.encode("port")], bytes_=True) records.add_record(rec) msg = Message_List(decoded[str.encode("type")], decoded[str.encode("txid")], records, bytes_=True) self.assertEqual(msg.type_, 'list') self.assertEqual(msg.txid_, 123) self.assertEqual(msg.peers_.records[0].username_, 'xlogin00') self.assertEqual(msg.peers_.records[0].ipv4_, '192.0.2.1') self.assertEqual(msg.peers_.records[0].port_, 34567) self.assertEqual(msg.peers_.records[1].username_, 'xnigol99') self.assertEqual(msg.peers_.records[1].ipv4_, '192.0.2.2') self.assertEqual(msg.peers_.records[1].port_, 45678)
def test_decode_open_file(self): for name in self.filenames: with open(name, 'rb') as f: d1 = decode(f) f.seek(0) d2 = raw_decode(f.read()) self.assertEqual(d1, d2)
def main(): ss = Preferences() # settings.1py directory_path = os.path.join( ss.get("maindir"), u"All-Torrs\\" ) # needs a unicode symbol so os. commands work at all on paths with funny chars files = [ os.path.join(directory_path, fn) for fn in next(os.walk(directory_path))[2] ] # gives absolute paths + names torrentnamelist = [] for eachfile in files: with open(eachfile, "rb") as stringfile: try: torrent = bencode.decode(stringfile.read()) for key, value in torrent.iteritems(): if key == "announce": announce = value domain = "{uri.netloc}".format(uri=urlparse(announce)) colon = domain.find(":", 0) if colon != -1: domain = domain[:colon] if domain: tracker = domain # only using 1 value here(lazy) elif key == "announce-list": tracker = "Multiple Trackers" except: tracker = "None" torrentfilename = eachfile[eachfile.rfind("\\") + 1 :] if not os.path.exists(directory_path + tracker): os.makedirs(directory_path + tracker) os.rename(eachfile, os.path.join(directory_path + tracker + "\\" + torrentfilename))
def main(): """ Runs the server loop taking in GET and POST requests and handling them accordingly """ args = parser().parse_args() tcp_ip = args.ip tcp_port = args.port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((tcp_ip, int(tcp_port))) s.listen(5) while 1: conn, addr = s.accept() print('Connection address:', addr) request = b'' while 1: data = conn.recv(2**20) if not data: break else: request += data print('Data recieved') try: request = bencode.decode(request) handle_request(conn, request) except Exception: print("Bad request recieved; continuing") pass conn.close()
def send_request(request): """ Sends message to backend over socket connection and waits for a response :param request: dictionary of info to be sent to backend """ # Convert dictionary to send-able type data_string = bencode.encode(request) op_sys = platform.system() try: if op_sys == 'Windows': response_string = _tcp_send_message(data_string) else: response_string = _unix_send_message(data_string) except socket.timeout: response = { 'status': 'error', 'message': 'Connection Timeout. Check Backend Status', } return response except socket.error: response = { 'status': 'error', 'message': 'Backend Communication Error', } return response response = bencode.decode(response_string) return response
def decode_from_bencode(path): with open(path, 'rb') as f: meta_info = f.read() # torrent = Decoder(meta_info).decode() torrent = decode(meta_info) print(torrent) return torrent
def get_from_file(self): try: torrent_path = os.path.join(self.torrent_dir, self.hash + '.torrent') return bencode.decode(open(torrent_path, 'rb').read()) except Exception: return False
async def send_request_to_node( request: Dict[str, Any], ip: str, port: int, ) -> Any: """ Creates a connection a node and sends a given request to the node and returns the response :param port: port where node is serving :param ip: ip of node :param request: Dictionary of a request as specified in the Spec Document :return: node response """ reader, writer = await asyncio.open_connection(ip, port) writer.write(bencode.encode(request)) writer.write_eof() await writer.drain() data = b'' while 1: sockdata = await reader.read() if not sockdata: break data += sockdata reader.feed_eof() response = bencode.decode(data) if (response['status'] == 'ok'): logger.debug("sending OK") return response['response'] else: logger.debug("sending error") raise_network_error(response['error'])
def __init__(self, bencoded_msg, sender_addr, auto_sanitize=False): self.sender_addr = sender_addr try: self._msg_dict = bencode.decode(bencoded_msg) except (bencode.DecodeError): logger.exception('invalid bencode') raise MsgError, 'invalid bencode' # Make sure the decoded data is a dict and has a TID key try: self.tid = self._msg_dict[TID] except (TypeError): raise MsgError, 'decoded data is not a dictionary' except (KeyError): raise MsgError, 'key TID not found' # Sanitize TID if not (isinstance(self.tid, str) and self.tid): raise MsgError, 'TID must be a non-empty binary string' # Sanitize TYPE try: self.type = self._msg_dict[TYPE] except (KeyError): raise MsgError, 'key TYPE not found' if self.type == QUERY: self._sanitize_query() elif self.type == RESPONSE: if auto_sanitize: self.sanitize_response() elif self.type == ERROR: self._sanitize_error() else: raise MsgError, 'Unknown TYPE value' return
def scrapeHTTP(self, torrent, tracker): params = { 'info_hash': torrent.info_hash, 'peer_id': torrent.peer_id, 'uploaded': 0, 'downloaded': 0, 'left': torrent.total_length, 'event': 'started', 'port': 6881 } try: answerTracker = requests.get( tracker, params=params, timeout=30, headers={ 'user-agent': "AT-Client/" + __version__ + " " + requests.utils.default_user_agent() }) lstPeers = bencode.decode(answerTracker.content) for peer in lstPeers['peers']: self.new_peers_queue.put([peer['ip'], peer['port']]) except Exception as e: logging.info(e) pass
def __init__(self, bencoded_msg): try: self._msg_dict = bencode.decode(bencoded_msg) except (bencode.DecodeError): log.exception('invalid bencode') raise MsgError, 'invalid bencode' # Make sure the decoded data is a dict and has a TID key try: self.tid = self._msg_dict[TID] except (TypeError): raise MsgError, 'decoded data is not a dictionary' except (KeyError): raise MsgError, 'key TID not found' # Sanitize TID if not (isinstance(self.tid, str) and self.tid): raise MsgError, 'TID must be a non-empty binary string' # Sanitize TYPE try: self.type = self._msg_dict[TYPE] except (KeyError): raise MsgError, 'key TYPE not found' if not self.type in (QUERY, RESPONSE, ERROR): raise MsgError, 'Unknown TYPE value' if self.type == QUERY: self._sanitize_query() elif self.type == ERROR: self._sanitize_error() return
def __init__(self, hash, torrent_dir): self.hash = hash self.torrent_dir = torrent_dir if not self.get_from_url() and not self.get_from_file(): raise Exception( "Could not find a torrent with this hash on the tracker or in the torrent directory:" + str(self.torrent_dir)) with open(torrent_dir + hash + '.torrent', 'rb') as file: contents = file.read() self.torrentFile = bencode.decode(contents) self.totalLength = 0 self.pieceLength = self.torrentFile['info']['piece length'] self.pieces = self.torrentFile['info']['pieces'] self.info_hash = utils.sha1_hash( bencode.encode(self.torrentFile['info'])) self.peer_id = self.generate_peer_id() self.announceList = self.getTrakers() self.fileNames = [] self.get_files() if self.totalLength % self.pieceLength == 0: self.numberOfPieces = self.totalLength / self.pieceLength else: self.numberOfPieces = int(self.totalLength / self.pieceLength) + 1 logging.debug(self.announceList) logging.debug(self.fileNames) assert (self.totalLength > 0) assert (len(self.fileNames) > 0)
def read_torrent_file( self, path ) -> dict: #Metodo utilizado para obtener una lectura del archivo with open(path, 'rb') as file: meta_info = file.read() torrent = bencode.decode(meta_info) return torrent
def check_data(self, data, sender): try: packet = bencode.decode(data) except Exception: self.send_error(generate_txid(), "The packet could not be decoded.", sender) return False if type(packet) is not dict: self.send_error(generate_txid(), "Wrong packet format. Expected json.", sender) return False if not all(f in packet for f in ("type", "txid")): self.send_error( generate_txid(), "Missing fields in packet. Expected at least 'type' and 'txid'.", sender) return False dbg_print("Recieved: {msg}\nFrom: {frm}\n- - - - - - - - - -".format( msg=packet, frm=sender)) if packet["type"] == "error": self.packet_queue.pop_ack(packet["txid"]) if "verbose" in packet: err_print("Error: " + packet["verbose"]) else: err_print("Unknown error.") return False packet["address"] = sender return packet
async def send_request_to_tracker( request: Dict[str, Any], ip: str, port: int, ) -> Dict[str, Any]: """ Creates a connection with the tracker and sends a given request to the tracker and returns the response :param port: port where tracker is serving :param ip: ip of tracker :param request: ['POST'/'GET', node_id|drop_id, data] :return: tracker response """ reader, writer = await asyncio.open_connection(ip, port) writer.write(bencode.encode(request)) writer.write_eof() await writer.drain() response = b'' while 1: data = await reader.read() if not data: break else: response += data reader.feed_eof() return bencode.decode(response)
def _handle_response(self, response: bytes): response_dict = bencode.decode(response) if response_dict.get('failure reason'): raise AnnounceFailureError(response_dict['failure reason']) # Decompose peers from the tracker response raw_peers = response_dict['peers'] if isinstance(raw_peers, list): peers = self._decode_peers_dict_model(raw_peers) else: peers = self._decode_peers_binary_model(raw_peers) # Debug print statements print(response_dict.get('interval')) print(response_dict.get('min interval')) print(response_dict.get('tracker id')) print(response_dict.get('complete')) print(response_dict.get('incomplete')) print(peers) self._tracker_response = TrackerResponse( response_dict.get('interval'), response_dict.get('min interval'), response_dict.get('tracker id'), response_dict.get('complete'), response_dict.get('incomplete'), peers)
def __init__(self, bencoded_msg): try: self._msg_dict = bencode.decode(bencoded_msg) except (bencode.DecodeError): logging.exception('invalid bencode') raise MsgError, 'invalid bencode' # Make sure the decoded data is a dict and has a TID key try: self.tid = self._msg_dict[TID] except (TypeError): raise MsgError, 'decoded data is not a dictionary' except (KeyError): raise MsgError, 'key TID not found' # Sanitize TID if not (isinstance(self.tid, str) and self.tid): raise MsgError, 'TID must be a non-empty binary string' # Sanitize TYPE try: self.type = self._msg_dict[TYPE] except (KeyError): raise MsgError, 'key TYPE not found' if not self.type in (QUERY, RESPONSE, ERROR): raise MsgError, 'Unknown TYPE value' if self.type == QUERY: self._sanitize_query() elif self.type == ERROR: self._sanitize_error() return
def parse_bytes(content: bytes) -> dict: """Parse only needed values by this app from content of torrent file (.torrent) See: https://wiki.theory.org/index.php/BitTorrentSpecification#Metainfo_File_Structure Args: content (bytes): binary content of torrent file Returns: dict: with following keys * 'name': str * 'info_hash': str (hexadecimal values), * 'tracker_urls': list * 'creation_date': datetime.datetime * 'length': integer, number of bytes with 1024 convention (for kilo,...) """ decoded_content = bencode.decode(content) return_dict = {} return_dict['name'] = decoded_content['info']['name'] return_dict['info_hash'] = hashlib.sha1( bencode.encode(decoded_content['info'])).hexdigest() announce_list = [] announce_list.append(decoded_content.get('announce')) if "announce-list" in decoded_content: announce_list.extend([ url for urls in decoded_content.get('announce-list') for url in urls ]) tracker_urls = [ extract_tracker_url_from_announce(url) for url in announce_list if url ] tracker_urls = [ url_split for url_split in tracker_urls if url_split.scheme and url_split.netloc ] return_dict['tracker_urls'] = tracker_urls if "creation date" in decoded_content: return_dict['creation_date'] = datetime.datetime.fromtimestamp( int(decoded_content['creation date'])) if "length" in decoded_content['info']: return_dict['size'] = int(decoded_content['info']['length']) if "files" in decoded_content['info']: for file_info in decoded_content['info']['files']: if "length" in file_info: if 'size' in return_dict: return_dict['size'] += int(file_info['length']) else: return_dict['size'] = int(file_info['length']) return return_dict
def decode_peerlist(rawpl: bytes) -> Optional[List[Any]]: """ decodes peerlist from bytes representation to list >>> from syncr_backend.util.crypto_util import encode_peerlist >>> from syncr_backend.util.crypto_util import decode_peerlist >>> peers = [('foo', '1.2.3.4', 2), ('bar', '2.3.4.5', 3)] >>> encoded_peers = encode_peerlist(peers) >>> encoded_peers b'type:peerlistll3:foo7:1.2.3.4i2eel3:bar7:2.3.4.5i3eee' >>> decode_peerlist(encoded_peers) [('foo', '1.2.3.4', 2), ('bar', '2.3.4.5', 3)] :param rawpl: bytes form of peerlist :return: A list of peers, or None """ if rawpl[:len(encode_peerlist_prefix)] == encode_peerlist_prefix: peerlist = rawpl[len(encode_peerlist_prefix):] else: return None try: declist = bencode.decode(peerlist) return list(map(lambda x: tuple(x), declist)) except Exception: return None
def main(path, dry=False): # Path to resume.dat resume_path = os.path.join(path, 'resume.dat') data = open(resume_path, 'rb').read() # Find ongoing .torrent files from resume.dat torrents = bencode.decode(data) ongoing = [] for k, _ in torrents.items(): ongoing.append(os.path.join(path, k)) # List all .torrent files in the specified directory. p = Path(path).glob('*.torrent') trashes = {str(x) for x in p} - set(ongoing) # Path to the trash directory trash_path = os.path.join(path, 'trash') if not dry and not os.path.isdir(trash_path): os.mkdir(trash_path) # Move unnecessary torrent files to the trash directory. for x in trashes: print('Moving %s' % x) if not dry: shutil.move(x, trash_path)
async def decode(b: bytes) -> 'DropMetadata': """Decodes a bencoded drop metadata file to a DropMetadata object Also verifies the files hash and header signature, and throws an exception if they're not OK :param b: The bencoded file :return: A DropMetadata object from b """ # Note: assumes signed header decoded = bencode.decode(b) dm = DropMetadata( drop_id=decoded["drop_id"], name=decoded["name"], version=DropVersion(decoded["version"], decoded["version_nonce"]), previous_versions=[ DropVersion( v["version"], v["nonce"], ) for v in decoded["previous_versions"] ], primary_owner=decoded["primary_owner"], other_owners=decoded["other_owners"], signed_by=decoded["signed_by"], files_hash=decoded["files_hash"], files=decoded["files"], sig=decoded["header_signature"], ) await dm.verify_files_hash() await dm.verify_header() return dm
def test_announce_with_multiple_trackers(self): """ Test that announce is correct with multiple tracker. """ self.t = bencode.decode(torrent.make_torrent_file \ (file = self.filename, \ tracker = [self.tracker, "http://tracker2.com"], \ comment = self.comment)) self.assertEqual(self.tracker, self.t["announce"])
def get_the_hash(self): # Open torrent file torrent_file = open(self.filepath, "rb") metainfo = bencode.decode(torrent_file.read()) info = metainfo['info'] thehash = hashlib.sha1(bencode.encode(info)).hexdigest().upper() logger.info('Hash: %s' % thehash) return thehash
def is_torrent_content(content): try: meta_info = bencode.decode(content, 'encoding; default is utf-8') info = meta_info['info'] return info['name'] except: return False
def get_size(torrent_link): r = HTMLSession().get( 'https://yts.mx/torrent/download/295D6D644F4D40E9909E5736AFE178DBBEF320D9' ) torrent_content = bencode.decode(r.content) del torrent_content['info'] print(torrent_content['info']['files'])
def request(self): tracker_request = self.construct_request() ## attempt to request tracker and decode the response with urllib.request.urlopen(tracker_request) as response: decoded_response = bencode.decode(response.read()) return decoded_response
def get_the_hash(self, filepath): # Open torrent file torrent_file = open(filepath, "rb") metainfo = bencode.decode(torrent_file.read()) info = metainfo['info'] thehash = hashlib.sha1(bencode.encode(info)).hexdigest().upper() logger.fdebug('Hash: ' + thehash) return thehash
def test_dict(self): self.assertEqual( decode('d4:agesli26ei27ee4:name5:Riley6:parentd4:name5:Scottee'), { 'name': 'Riley', 'ages': [26, 27], 'parent': { 'name': 'Scott', }, })
def __init__(self, encoded_info): root = bencode.decode(encoded_info) info = root["info"] self.fname = info["name"] self.flength = int(info["length"]) self.piece_length = int(info["piece length"]) self.pieces = [] for i in range(0, len(info["pieces"]), 20): self.pieces.append(info["pieces"][i:i+20])
def test_announce_list(self): """ Test that the announce list is correct. """ self.t = bencode.decode(torrent.make_torrent_file \ (file = self.filename, \ tracker = [self.tracker, "http://tracker2.com"], \ comment = self.comment)) self.assertEqual([[self.tracker], ["http://tracker2.com"]], \ self.t["announce-list"])
def get_the_hash(self, filepath): import hashlib, StringIO import bencode # Open torrent file torrent_file = open(filepath, "rb") metainfo = bencode.decode(torrent_file.read()) info = metainfo['info'] thehash = hashlib.sha1(bencode.encode(info)).hexdigest().upper() return thehash
def setUp(self): """ Write a little torrent file. """ self.filename = "test.txt" self.tracker = "http://tracker.com" self.comment = "test" with open(self.filename, "w") as self.file: self.file.write("Test file.") self.t = bencode.decode(torrent.make_torrent_file \ (file = self.filename, \ tracker = self.tracker, \ comment = self.comment))
def metadata_load(info_hash): h = binascii.hexlify(info_hash) fname = h + ".meta" if not os.path.exists(fname): return None with file(fname, "rb") as f: data = f.read() if metainfo.hash(data) == info_hash: meta = metainfo.MetaInfo(bencode.decode(data)) log.info('MetaInfo "{}" ({} hashes) = {:.1f}MB'.format(meta.name, len(meta.hashes), meta.total / 1e6)) return meta
def calculate_torrent_hash(self, link=None, filepath=None, data=None): thehash = None if link is None: if filepath: torrent_file = open(filepath, "rb") metainfo = bencode.decode(torrent_file.read()) else: metainfo = bencode.decode(data) info = metainfo['info'] thehash = hashlib.sha1(bencode.encode(info)).hexdigest().upper() logger.info('Hash: ' + thehash) else: if link.startswith("magnet:"): torrent_hash = re.findall("urn:btih:([\w]{32,40})", link)[0] if len(torrent_hash) == 32: torrent_hash = b16encode(b32decode(torrent_hash)).lower() thehash = torrent_hash.upper() if thehash is None: logger.warn('Cannot calculate torrent hash without magnet link or data') return thehash
def __init__(self, path): with open(path, "r") as f: data = f.read() self._raw = bencode.decode(data) self._announce = self._raw["announce"] self._name = self._raw["info"]["name"] self._piece_length = self._raw["info"]["piece length"] self._length = self._raw["info"]["length"] self._hash_size = hs = 20 pcs = self._raw["info"]["pieces"] self._pieces = [pcs[i*hs:(i+1)*hs] for i in range(len(pcs)/hs)] self._files = self._raw["info"].get("files", {})
def datagram_received(self, payload, addr): logging.info('Received datagram %s', payload) try: request = decode(payload) logging.info('Received request %s', request) query = request.get('q') callback = getattr(self, 'handle_' + query) except (ValueError, AttributeError): logging.warning('Could not handle the request') else: callback(request, addr)
def readtorrent(self, path): with open(path, 'r') as fh: data = fh.read() self.data = bencode.decode(data) info = bencode.encode(self.data['info']) self.hash = hashlib.sha1(info).digest() if 'length' in self.data['info']: self.size = int(self.data['info']['length']) else: self.size = 0 for file in self.data['info']['files']: self.size += int(file['length']) self.numpieces = int(len(self.data['info']['pieces'])) / 20 self.pieces = bytearray(self.numpieces) self.piecelength = int(self.data['info']['piece length']) self.bytes_left = self.size
def __init__(self, bencoded_msg, sender_addr): self.sender_addr = sender_addr try: self._msg_dict = bencode.decode(bencoded_msg) self._sanitize_common() if self.type == QUERY: self._sanitize_query() elif self.type == RESPONSE: self._sanitize_response() elif self.type == ERROR: self._sanitize_error() else: raise MsgError, 'Unknown TYPE value' except MsgError: raise except: logger.warning('This bencoded message is broken:\n%s' % repr(bencoded_msg)) raise MsgError, 'Invalid message'
def make_tracker_request(info, peer_id, tracker_url): """ Given a torrent info, and tracker_url, returns the tracker response. """ # Generate a tracker GET request. payload = {"info_hash" : info, "peer_id" : peer_id, "port" : 6881, "uploaded" : 0, "downloaded" : 0, "left" : 1000, "compact" : 1} payload = urlencode(payload) # Send the request response = urlopen(tracker_url + "?" + payload).read() return decode(response)
def __init__(self, private_dht_name, datagram): self.private_dht_name = private_dht_name bencoded_msg = datagram.data src_addr = datagram.addr self.src_addr = src_addr # COMMON self.tid = None self.type = None self.version = None self.ns_node = None # never used self.src_id = None self.src_node = None # QUERY self.query = None self.target = None # find_node self.info_hash = None # announce_peer self.bt_port = None # announce_peer self.token = None # announce_peer # RESPONSE self.nodes = None self.nodes2 = None self.all_nodes = None self.token = None self.peers = None # ERROR self.error = None try: # bencode.decode may raise bencode.DecodeError self._msg_dict = bencode.decode(bencoded_msg) self._sanitize_common() if self.type == QUERY: self._sanitize_query() elif self.type == RESPONSE: self._sanitize_response() elif self.type == ERROR: self._sanitize_error() else: raise MsgError, 'Unknown TYPE value' except (MsgError): raise except: logger.warning( 'This bencoded message is broken:\n%s' % repr(bencoded_msg)) raise MsgError, 'Invalid message'
def retrieve_peers(self, torrent): parameters = dict( info_hash = torrent.hash, peer_id = utils.clientid, port = 6881, event = 'started', uploaded = torrent.bytes_uploaded, downloaded = torrent.bytes_downloaded, left = torrent.bytes_left, compact = 1, numwant = 10) url = '{0.scheme}://{0.netloc}{0.path}?{1}'.format( self.url, urllib.urlencode(parameters)) try: fh = urllib.urlopen(url) data = fh.read() fh.close() except IOError as e: raise TrackerException('Impossible to open url') try: self.data = bencode.decode(data) if 'failure reason' in self.data: raise TrackerException('Failure when reading tracker: ' + self.data['failure reason']) if 'interval' in self.data: self.update_interval(int(self.data['interval'])) except: raise TrackerException('Tracker response is not bencoded') peers = set() data = self.data['peers'] while len(data) != 0: peer = data[0:6] data = data[6:] ip = socket.inet_ntoa(peer[0:4]) port = struct.unpack('!H', peer[4:])[0] peers.add((ip, port)) return peers
def __init__(self, bencoded_msg, sender_addr): self.sender_addr = sender_addr try: # bencode.decode may raise bencode.DecodeError self._msg_dict = bencode.decode(bencoded_msg) self._sanitize_common() if self.type == QUERY: self._sanitize_query() elif self.type == RESPONSE: self._sanitize_response() elif self.type == ERROR: self._sanitize_error() else: raise MsgError, 'Unknown TYPE value' except (MsgError): raise except: logger.critical( 'This bencoded message crashed:\n%s' % repr(bencoded_msg)) raise MsgError, 'Invalid message'
def make_seeding_folder(torrent_name, src_dir, dst_dir): with open(torrent_name, 'rb') as fh: torrent_bytes = fh.read() torrent = bencode.decode(torrent_bytes) tor_name = torrent['info']['name'] print(tor_name) dst_dir_1 = os.path.join(dst_dir, tor_name) os.makedirs(name = dst_dir_1, exist_ok = True) prf = Profiler() files = get_files_list(src_dir) prf.log('get_files_list() delay:') files = matching_files_by_size(torrent, files) prf.log('matching_files_by_size() delay:') pieces = make_pieces_from_metadata(torrent, files) prf.log('make_pieces_from_metadata() delay:') for idx in range(len(pieces)): pieces[idx].find_match() # print('Checked ', idx, ' piece from ', len(pieces)) prf.log('find_matches() delay:') for f in files: if f.is_matched(): dst_file = os.path.join(dst_dir, f.get_torrent_name()) src_file = f.get_matched_name() dst_path = os.path.join(dst_dir, f.get_path_from_torrent()) if not os.path.exists(dst_path): os.makedirs(name = dst_path, exist_ok = True) # print(src_file, '=>', dst_file) shutil.copy(src_file, dst_file) prf.log('copy files delay:')
def __init__(self, datagram): bencoded_msg = datagram.data src_addr = datagram.addr self.src_addr = src_addr try: # bencode.decode may raise bencode.DecodeError self._msg_dict = bencode.decode(bencoded_msg) self._sanitize_common() if self.type == QUERY: self._sanitize_query() elif self.type == RESPONSE: self._sanitize_response() elif self.type == ERROR: self._sanitize_error() else: raise MsgError, 'Unknown TYPE value' except (MsgError): raise except: logger.warning( 'This bencoded message is broken:\n%s' % repr(bencoded_msg)) raise MsgError, 'Invalid message'
def make_tracker_request(info, peer_id, tracker_url): """ Given a torrent info, and tracker_url, returns the tracker response. """ # Generate a tracker GET request. payload = {"info_hash" : info, "peer_id" : peer_id, "port" : 6881, "uploaded" : 0, "downloaded" : 0, "left" : 1000, "compact" : 1} payload = urlencode(payload) # Send the request if re.search('\?',tracker_url): s = '&' else: s = '?' print 'DEBUG: urlopen(tracker_url + s + payload)', tracker_url + s + payload response = urlopen(tracker_url + s + payload).read() print 'DEBUG: response: ', response return decode(response)
def SetData(self,data): #init Panel Data self.download_dir.SetValue(self.Parent.tc.get_session().download_dir) self.started.SetValue(self.Parent.tc.get_session().start_added_torrents) metainfo = decode(data) self.__torrentData = b64encode(data) self.Wanted.SetColumns([ColumnDefn("File Name","left",500,"name"), ColumnDefn("Size","size",80,"size",stringConverter=formatSize)]) self.Wanted.InstallCheckStateColumn(self.Wanted.GetPrimaryColumn()) index = 0 if 'files' in metainfo['info']: for i in metainfo['info']['files']:#torrent basic decoding path = '' for item in i['path']: path +=item + '\\' path = path.rstrip('\\') self.Wanted.AddObject( File(path.decode('ascii','ignore'),i['length'],index) ) index+=1 elif 'length' in metainfo['info']: name = metainfo['info']['name'].decode('ascii','ignore') self.Wanted.AddObject(File(name,metainfo['info']['length'],0) ) self.SelectAll(wx.Event)
def make_tracker_request(info, peer_id, tracker_url): """ Given a torrent info, and tracker_url, returns the tracker response. """ # Generate a tracker GET request. payload = {"info_hash" : info, "peer_id" : peer_id, "port" : 6881, "uploaded" : 0, "downloaded" : 0, "left" : 1000, "compact" : 1} payload = urlencode(payload) # Send the request if tracker_url.startswith("udp"): (host, port) = parse_url(tracker_url) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(payload, (host, port)) response = sock.recv(1024) else: response = urlopen(tracker_url + "?" + payload).read() return decode(response)
def test_decode_int(self): self.assertEqual(decode(b'i3e'), 3) self.assertEqual(decode(b'i0e'), 0) self.assertEqual(decode(b'i-4e'), -4)