Beispiel #1
0
def get_torrent_file(torrent_id, return_file=False):

    rows = db2.query(Torrent_File).filter_by(torrent_id=torrent_id).all()

    if len(rows) != 0:
        if return_file is False:
            return
        else:
            return {"file": rows[0].file, "source": "Cached"}

    login()
    r = gazelle.get("{0}/torrents.php?action=download&id={1}".format(
        gazelle_url, torrent_id))

    try:
        data = bencodepy.decode(r.content)
    except:
        print("Error decoding torrent %d" % torrent_id)
        exit()

    # data[b"announce"] = ""

    db2.merge(Torrent_File(torrent_id=torrent_id, file=bencodepy.encode(data)))
    db2.commit()
    #return {"file": None, "source": ""}

    if return_file is True:
        return {"file": bencodepy.encode(data), "source": "Fetched"}
def get_torrent_file(torrent_id, return_file=False):

	rows = db2.query(Torrent_File).filter_by(torrent_id=torrent_id).all()

	if len(rows) != 0:
		if return_file is False:
			return
		else:
			return {"file": rows[0].file, "source": "Cached"}

	login()
	r = gazelle.get("{0}/torrents.php?action=download&id={1}".format(gazelle_url, torrent_id))

	try:
		data = bencodepy.decode(r.content)
	except:
		print("Error decoding torrent %d" % torrent_id)
		exit()

	# data[b"announce"] = ""

	db2.merge(Torrent_File(torrent_id=torrent_id, file=bencodepy.encode(data)))
	db2.commit()
	#return {"file": None, "source": ""}

	if return_file is True:
		return {"file": bencodepy.encode(data), "source": "Fetched"}
def test_torrent_decode_exceptions():
    assert_raises(TorrentDecodeError, TorrentMetainfo, b'')
    assert_raises(TorrentDecodeError, TorrentMetainfo, b' ')

    sample = {
        'announce': 'http://aaa.com',
        'encoding': 'UTF-8',
        'info': {
            'name': 'bbb',
            'length': 1,
            'piece length': 1,
            'pieces': b'.....................'
        }
    }
    TorrentMetainfo(bencodepy.encode(sample))

    t = copy.deepcopy(sample)
    t['announce'] = ''
    assert_raises(TorrentDecodeError, TorrentMetainfo, bencodepy.encode(t))

    t = copy.deepcopy(sample)
    del t['encoding']
    TorrentMetainfo(bencodepy.encode(t))

    t = copy.deepcopy(sample)
    t['encoding'] = 'zzz'
    assert_raises(TorrentDecodeError, TorrentMetainfo, bencodepy.encode(t))
Beispiel #4
0
def main():
    arg = ArgumentParser.ArgumentParser()
    arg.do_parsing()
    torrent_dict = decode_from_file(os.getcwd() + "\\" + arg.torrent_file_url)
    info_dict = torrent_dict[b"info"]
    piece_length = info_dict[b"piece length"]
    piece_count = int(len(info_dict[b"pieces"])/20)
    file_name = info_dict[b"name"]
    file_name = file_name.decode("utf-8")
    if b"files" in info_dict:
       print(info_dict[b"files"])
    global chunk_number
    chunk_number = int(piece_length/chunk_size)
    if piece_length % chunk_size != 0:
        chunk_number += 1
    global pieces_bitfield
    pieces_bitfield = [None] * piece_count
    global currently_used
    currently_used = [False] * piece_count
    dictionary_sha1 = helper.get_sha1(encode(info_dict))
    bencoded_info_dict = encode(info_dict)
    info_hash = helper.get_sha1(bencoded_info_dict)
    peer_id = os.urandom(20)
    listen_port = 2710
    file_length = info_dict[b"length"]
    payload = {"info_hash": info_hash, "peer_id": peer_id,
               "port": listen_port, "uploaded": 0, "downloaded": 0, "left": file_length}
    r = requests.get(torrent_dict[b"announce"], params=payload)
    response = decode(r.content)
    if b"failure reason" in response:
        return
    interval = response[b"interval"]
    peers = response[b"peers"]
    peers_list = []
    peer_num = len(peers)/6
    for elem in range(int(peer_num)):
        start_ind = 6 * elem
        peer_ip = socket.inet_ntoa(peers[start_ind:start_ind+4])
        peer_port = struct.unpack("!H", peers[start_ind+4:start_ind+6])[0]
        peers_list.append((peer_ip, peer_port))
    print(peers_list)
    for elem in peers_list:
        test_ip = elem[0]
        test_port = elem[1]
        cur_thread = Thread(target=do_for_each_peer,
                            args=(dictionary_sha1, test_ip, test_port, piece_length, info_dict, peer_id, file_length,
                                  file_name))
        # do_for_each_peer(dictionary_sha1, test_ip, test_port, piece_length, info_dict,peer_id)
        # print(cur_thread.name)
        cur_thread.start()
Beispiel #5
0
def spawn(url):
    torrent_url_components = urlparse(url)
    torrent_url_query = torrent_url_components.query
    match = re.search('ref=(.*)', torrent_url_query)
    if match is None:
        pass
    else:
        torrent_file = str(match.groups(0)[0]) + '.torrent'
        blob = download_torrent(url)
        dbx = dropbox.Dropbox(
            'JUEnSrL_pnAAAAAAAAAADGNPxjjbk3nYLnatbTN8vvJ01JM8yQIhn-MI5DqW41nR')
        path = '/torrents/%s' % torrent_file
        dbx.files_upload(blob, path)
        link = dbx.sharing_create_shared_link_with_settings(path).url
        link = re.sub('dl=0', 'dl=1', link)
        try:
            metainfo = decode(blob)
            info = metainfo[b'info']
            btih = hashlib.sha1(encode(info)).hexdigest()
            dn = metainfo[b'info'][b'name']
            magnet = 'magnet:?xt=urn:btih:{btih}&dn={dn}'.format(btih=btih,
                                                                 dn=dn)
            torrent = {'status': 'OK', 'magnet': magnet, 'torrent': link}
            r.hmset(url, torrent)
            record_event({'type': 'aisex.newtorrent'})
        except:
            torrent = {'status': 'ERROR', 'error': 'not a valid torrent file'}
        return torrent
Beispiel #6
0
    def __init__(self, bencontent):
        """
        Args:
            bencontent (bytes): bencoded torrent file contents
        """
        if not bencontent:
            raise TorrentDecodeError('Empty torrent file')

        try:
            content = bencodepy.decode(bencontent)
        except bencodepy.DecodingError as e:
            # TODO: better msg
            raise TorrentDecodeError from e

        # TODO: validate shape using voluptuous or schema libraries

        # 'encoding' field defines character encoding for 'pieces' field.
        encoding = content.get(b'encoding')
        if encoding and encoding.decode('utf-8').lower() != 'utf-8':
            raise(TorrentDecodeError('Unsupported encoding: %s' % encoding))

        self.announce = content[b'announce'].decode('utf-8')
        try:
            vol.Url()(self.announce)
        except vol.UrlInvalid as e:
            msg = 'Invalid announce URL: %s' % self.announce
            raise TorrentDecodeError(msg) from e

        # Ignore 'creation date', 'comment', 'created by', 'announce-list'

        info_dict = content[b'info']
        self.info_hash = hashlib.sha1(bencodepy.encode(info_dict)).digest()
        self.info = self._decode_info_dict(info_dict)
Beispiel #7
0
def handle(request):
    logging.warning('Tracker connection received!')

    def create_sock(_peer, ip):
        server = yield from loop.create_server(lambda: TorrentProxy(_peer), ip, 0)
        port = server.sockets[0].getsockname()[1]
        return port

    ip = request.GET['ip'] if ip in request.GET else '127.0.0.1'

    port = yield from create_sock({ 
        'ip': ip,
        'port': request.GET['port'] 
    }, '0.0.0.0')

    path = request.path_qs.replace('port={}'.format(request.GET['port']),
        'port={}'.format(port))

    r = yield from aiohttp.get(sys.argv[1] + path)
    data = yield from r.read()
    yield from r.release()

    torrent = bencodepy.decode(data)
    proxied_peers = []

    base_ip = ip2int('127.13.37.0')
    for index, peer in enumerate(decode_peers(torrent[b'peers'])):
        ip = int2ip(base_ip + index)
        port = yield from create_sock(peer, ip) 
        proxied_peers.append({ 'ip': ip, 'port': port })
        logging.info('Opened listener on {}'.format(port))

    torrent[b'peers'] = encode_peers(proxied_peers)

    return web.Response(body=bencodepy.encode(torrent))
Beispiel #8
0
    def _send(self, tid, data, addr, type):
        bytes_sent = self.sock.sendto(bencodepy.encode(data), addr)

        with self.lock:
            self.requests[tid] = Request(tid, time.time(), addr, type)

        return bytes_sent
 def encode(self, message):
     """
     bencodes a message
     :param message: a dictionary representing the message
     :return: the bencoded message
     """
     return bencodepy.encode(message)
Beispiel #10
0
def magnetCheck(stringPassed):
    if "magnet:?xt=" in stringPassed[:11]:
        addTorrent(stringPassed)
    elif os.path.isfile(stringPassed) and stringPassed.endswith('.torrent'):
        metadata = bencodepy.decode_from_file(stringPassed)
        subj = metadata[b'info']
        hashcontents = bencodepy.encode(subj)
        digest = hashlib.sha1(hashcontents).digest()
        b32hash = base64.b32encode(digest).decode()
        convertedMagnet = 'magnet:?'\
            + 'xt=urn:btih:' + b32hash\
            + '&dn=' + metadata[b'info'][b'name'].decode()\
            + '&tr=' + metadata[b'announce'].decode()\
            + '&xl=' + str(metadata[b'info'][b'piece length'])
        addTorrent(convertedMagnet)
    elif stringPassed.startswith('http') and stringPassed.endswith('.torrent'):
        addTorrent(stringPassed)
    elif stringPassed.startswith('http') and not stringPassed.endswith('.torrent'):
        fd, path = tempfile.mkstemp(suffix=".torrent")
        try:
            with os.fdopen(fd, 'wb') as tmp:
                tmp.write(s.get(stringPassed, allow_redirects=True).content)
                magnetCheck(path)
        finally:
            os.remove(path)
    else:
        console.print("Invalid input. Exiting...", style="red")
Beispiel #11
0
def ext_handshake(s):
    """
    Format: <length prefix><message ID><payload>
    """
    msg_body = {"m": {"ut_metadata": 1}}
    msg = b"\x14\x00" + bencodepy.encode(msg_body)
    send_msg(s, msg)
Beispiel #12
0
def get_info_hash(torrent):

    info = bencodepy.encode(torrent[b'info'])
    hexdigest = hashlib.sha1(info).hexdigest()
    info_hash = bytes.fromhex(hexdigest)

    return info_hash
 def generate_info_hash(self):
     sha1_hash = hashlib.sha1()
     # get the raw info value
     raw_info = self.torrent_file_raw_extract[b'info']
     # update the sha1 hash value
     sha1_hash.update(bencodepy.encode(raw_info))
     return sha1_hash.digest()
Beispiel #14
0
def send(data, port):
    if config['protocol'] == 'udp':
        local_sock = create_udp_socket(config['local_address'], port)
    else:
        local_sock = create_tcp_socket(config["local_address"], port)
    cookie = ''.join(random.choice(string.ascii_lowercase) for i in range(5))
    data = bencodepy.encode(data).decode()
    message = str(cookie) + " " + str(data)
    logging.debug('message: ' + message)
    local_sock.sendto(message.encode('utf-8'),
                      (config['rtpe_address'], int(config['rtpe_port'])))
    logging.debug('Command sent to rtpengine.')
    try:
        response = local_sock.recv(10240)
        logging.debug(f'Received from rtpengine: {str(response)}')
    except Exception:
        logging.error('After 10 seconds not received any response.')
        local_sock.close()
        return None
    try:
        data = response.decode()
        data = data.split(" ", 1)
        local_sock.close()
        return bc.decode(data[1])
    except Exception as e:
        logging.info(e)
        logging.error(f'Received response is not a string. {str(response)}.')
        local_sock.close()
        return None
Beispiel #15
0
    def do_GET(self):

        parsed_url = urllib.parse.urlparse(self.path)
        print(parsed_url)

        parsed_query = urllib.parse.parse_qs(parsed_url.query)

        error, client_id, info_hash = self.query_errors(parsed_query)

        if error:
            self.wfile.write(error)
        else:
            curr_peer = {
                "peer_id": client_id,
                "ip": self.client_address[0],
                "port": parsed_query["port"][0],
            }
            print(curr_peer)
            if do_handshake(curr_peer, info_hash):
                peers_list = [
                    peer for peer in retrv_peers() if peer != curr_peer
                ]
                res = bencodepy.encode({
                    "interval": INTERV_REQ,
                    "peers": peers_list,
                    "tracker_id": TRACKER_ID,
                })
                self.wfile.write(res)
Beispiel #16
0
def ext_handshake(s):
    """
    Format: <length prefix><message ID><payload>
    """
    msg_body = {"m": {"ut_metadata": 1}}
    msg = b"\x14\x00" + bencodepy.encode(msg_body)
    send_msg(s, msg)
Beispiel #17
0
def make_magnet_from_file(file):
    metadata = bencodepy.decode_from_file(file)
    subj = metadata[b'info']
    hashcontents = bencodepy.encode(subj)
    digest = hashlib.sha1(hashcontents).digest()
    b32hash = base64.b32encode(digest).decode()
    return 'magnet:?' + 'xt=urn:btih:' + b32hash
def get_info_hash(btdata):
    # https://docs.python.org/3/library/hashlib.html
    # get the info directory, re-encode it into bencode, then encrypt it with
    # SHA1 using the hashlib library and generate a digest.

    # XXX test print XXX
    # print("\n\n::::::btdata backup  : \n\n", btdata_backup, "\n\n")
    # print("\n\n::::::INFO btdata backup  : \n\n", btdata_info_backup, "\n\n")

    # XXX test print XXX
    # print('re-encoded : ', btdata['info'])

    # first, encode info_dictionary in bencode before encrypting using sha1
    encoded_info_dictionary = bencodepy.encode(btdata_info_backup)

    # XXX test print XXX
    # print('encoded info dictionary : ', encoded_info_dictionary)

    # encrypt the encoded_info_dictionary using sha1 & generate sha1 hash digest
    digest_builder = hashlib.sha1()
    digest_builder.update(encoded_info_dictionary)
    digest_builder = digest_builder.digest()

    # XXX test print XXX
    # print('digest builder : ', digest_builder,'\n\n')

    return digest_builder
Beispiel #19
0
 def _download_torrent(self):
     res = self.session.get(self.dl_link)
     torrent = bytes()
     for chunk in res.iter_content(100000):
         torrent += chunk
     ggn_dir = os.path.join(TORRENT_DIR, 'ggn/')
     if not os.path.exists(ggn_dir):
         os.makedirs(ggn_dir)
     with open(
             os.path.join(
                 ggn_dir,
                 os.path.basename('[GGn]{}.torrent'.format(
                     self.release_title))), 'wb') as t:
         t.write(torrent)
     torrent = bencodepy.decode(torrent)
     torrent[
         b'announce'] = b'https://tracker.pterclub.com/announce?passkey=' + bytes(
             PTER_KEY, encoding='utf-8')
     torrent[b'info'][b'source'] = bytes('[pterclub.com] PT之友俱乐部',
                                         encoding='utf-8')
     del torrent[b'comment']
     torrent = bencodepy.encode(torrent)
     with open(
             os.path.join(
                 'torrents',
                 os.path.basename('[PTer]{}.torrent'.format(
                     self.release_title))), 'wb') as t:
         t.write(torrent)
Beispiel #20
0
 def test_encode_bytes(self):
     pass
     b = b"TheseAreSomeBytes"
     coded = bencodepy.encode(b)
     l = bytes(str(len(b)), 'utf-8')
     self.assertEqual(coded,
                      l + b':' + b,
                      msg='Failed to encode string from bytes.')
Beispiel #21
0
 def __init__(self, torrent_path):
     self.torrent_path = torrent_path
     self.files = []
     if self._validate_torrent_file():
         self.meta_info = bencodepy.bread(self.torrent_path)
         info = bencodepy.encode(self.meta_info[b"info"])
         self.info_hash = sha1(info).digest()
         self._get_torrent_files()
Beispiel #22
0
 def test_encode_dict(self):
     od = collections.OrderedDict()
     od['ka'] = 'va'
     od['kb'] = 2
     coded = bencodepy.encode(od)
     self.assertEqual(coded,
                      b'd2:ka2:va2:kbi2ee',
                      msg='Failed to encode dictionary from dict.')
Beispiel #23
0
 def dumpb(self, obj, options: dict) -> bytes:
     kwargs = {}
     kwargs.update(Options.pop_origin_kwargs(options))
     self.check_options(options)
     try:
         return bencodepy.encode(obj, **kwargs)
     except TypeError as e:
         raise SerializeError(e)
Beispiel #24
0
    def _calc_info_hash(self):
        self.info_hash = None
        if "info" in self._torrent_decoded:
            info_encoded = bencodepy.encode(self._torrent_decoded["info"])

            if info_encoded:
                self.info_hash = hashlib.sha1(info_encoded).hexdigest().upper()

        return self.info_hash
Beispiel #25
0
    def __init__(self, filepath):
        self.file = filepath

        with open(self.file, 'rb') as f:
            self.meta_info = f.read()
            self.meta_info = bencodepy.decode(self.meta_info)
            info = bencodepy.encode(self.meta_info[b'info'])
            self.info_hash = sha1(info).digest()
            self.count_files()
Beispiel #26
0
 def create_info_hash(self):
     """
     Bencode the info dict and hash it with SHA1
     :param meta_data: decoded meta data from .torrent file
     :return: hashlib digest
     """
     self.info_hash = hashlib.sha1()
     self.info_hash.update(bencodepy.encode(self.metadata['info']))
     self.info_hash = self.info_hash.digest()
     return self.info_hash
Beispiel #27
0
 def test_encode_complex(self):
     od = collections.OrderedDict()
     od['KeyA'] = ['listitemA', {'k': 'v'}, 3]
     od['KeyB'] = {'k': 'v'}
     od['KeyC'] = 3
     od['KeyD'] = 'AString'
     expected_result = b'd4:KeyAl9:listitemAd1:k1:vei3ee4:KeyBd1:k1:ve4:KeyCi3e4:KeyD7:AStringe'
     coded = bencodepy.encode(od)
     self.assertEqual(coded, expected_result, msg='Failed to encode complex object.')
     pass
Beispiel #28
0
 def torrentToMagnet(cls, torrentByte):
     try:
         metadata = bencodepy.decode(torrentByte)
         subj = metadata[b'info']
         hashcontents = bencodepy.encode(subj)
         digest = hashlib.sha1(hashcontents).digest()
         b32hash = base64.b32encode(digest).decode()
         return 'magnet:?' \
                + 'xt=urn:btih:' + b32hash
     except:
         return ""
def make_magnet_from_file(file):
    metadata = bencodepy.decode_from_file(file)
    subj = metadata[b'info']
    hashcontents = bencodepy.encode(subj)
    digest = hashlib.sha1(hashcontents).digest()
    b32hash = base64.b32encode(digest).decode()
    return 'magnet:?'\
             + 'xt=urn:btih:' + b32hash\
             + '&dn=' + metadata[b'info'][b'name'].decode()\
             + '&tr=' + metadata[b'announce'].decode()\
             + '&xl=' + str(metadata[b'info'][b'length'])
Beispiel #30
0
def _encodeError(krpcError):
    """
    Encode a KRPC error message.
    """
    error = {
        't': krpcError.transactionID,
        'y': 'e',
        'e': [krpcError.errorCode, krpcError.errorMessage]
    }
    
    return bencodepy.encode(error)
Beispiel #31
0
 def test_encode_complex(self):
     od = collections.OrderedDict()
     od['KeyA'] = ['listitemA', {'k': 'v'}, 3]
     od['KeyB'] = {'k': 'v'}
     od['KeyC'] = 3
     od['KeyD'] = 'AString'
     expected_result = b'd4:KeyAl9:listitemAd1:k1:vei3ee4:KeyBd1:k1:ve4:KeyCi3e4:KeyD7:AStringe'
     coded = bencodepy.encode(od)
     self.assertEqual(coded,
                      expected_result,
                      msg='Failed to encode complex object.')
     pass
Beispiel #32
0
 def startProtocol(self):
     data = {
         'y': 'q',
         'q': 'ping',
         'a': {
             'id': hashlib.sha1(b'bla').digest()
         },
         't': b'42'
     }
     
     self.transport.write(bencodepy.encode(data), ('127.0.0.1', 8043))
     print("Sent ping")
Beispiel #33
0
def create_resource(call_id, from_tag, to_tag, sock):
    global kubernetes_apis
    for a in kubernetes_apis:
        if a.call_id == call_id:
            logging.debug(
                f'A kubernetes resource are exist with this call-id: {call_id}'
            )
            return

    cookie = ''.join(random.choice(string.ascii_lowercase) for i in range(5))
    message = str(cookie) + " " + str(
        bencodepy.encode(commands.query(call_id)).decode())
    ws = False
    if config["protocol"] == "ws":
        query = ws_send(message, sock)
        ws = True
    else:
        send(message, sock, (config['rtpe_address'], int(config['rtpe_port'])))
    logging.debug(f'Received query: {str(query)}')

    to_port = query['tags'][to_tag]['medias'][0]['streams'][0]['local port']
    to_c_address = query['tags'][to_tag]['medias'][0]['streams'][0][
        'endpoint']['address']
    to_c_port = query['tags'][to_tag]['medias'][0]['streams'][0]['endpoint'][
        'port']
    from_port = query['tags'][from_tag]['medias'][0]['streams'][0][
        'local port']
    from_c_address = query['tags'][from_tag]['medias'][0]['streams'][0][
        'endpoint']['address']
    from_c_port = query['tags'][from_tag]['medias'][0]['streams'][0][
        'endpoint']['port']
    logging.debug('Every port and address is mapped.')

    kubernetes_apis.append(
        Client(call_id=call_id,
               tag=from_tag,
               local_ip=from_c_address,
               local_rtp_port=from_c_port,
               local_rtcp_port=from_c_port + 1,
               remote_rtp_port=from_port,
               remote_rtcp_port=from_port + 1,
               without_jsonsocket=config['without_jsonsocket'],
               ws=ws))
    kubernetes_apis.append(
        Client(call_id=call_id,
               tag=to_tag,
               local_ip=to_c_address,
               local_rtp_port=to_c_port,
               local_rtcp_port=to_c_port + 1,
               remote_rtp_port=to_port,
               remote_rtcp_port=to_port + 1,
               without_jsonsocket=config['without_jsonsocket'],
               ws=ws))
Beispiel #34
0
    def startProtocol(self):
        data = {
            'y': 'q',
            'q': 'ping',
            'a': {
                'id': hashlib.sha1(b'bla').digest()
            },
            't': b'42'
        }

        self.transport.write(bencodepy.encode(data), ('127.0.0.1', 8043))
        print("Sent ping")
Beispiel #35
0
def _encodeResponse(krpcResponse):
    """
    Encode a KRPC response.
    """
    if krpcResponse.type == b'ping':
        response = {
            't': krpcResponse.transactionID,
            'y': 'r',
            'r': {
                'id': bytes(krpcResponse.fromNode)
            }
        }
    elif krpcResponse.type == b'find_node':
        response = {
            't': krpcResponse.transactionID,
            'y': 'r',
            'r': {
                'id': bytes(krpcResponse.fromNode),
                'nodes': _encodeNodes(krpcResponse.nodes)
            }
        }
    elif krpcResponse.type == b'get_peers':
        if krpcResponse.peers != None:
            response = {
                't': krpcResponse.transactionID,
                'y': 'r',
                'r': {
                    'id': bytes(krpcResponse.fromNode),
                    'token': bytes(krpcResponse.token),
                    'values': _encodePeers(krpcResponse.peers)
                }
            }   
        else:
            response = {
                't': krpcResponse.transactionID,
                'y': 'r',
                'r': {
                    'id': bytes(krpcResponse.fromNode),
                    'token': bytes(krpcResponse.token),
                    'nodes': _encodeNodes(krpcResponse.nodes)
                }
            }
    elif krpcResponse.type == b'announce_peer':
        response = {
            't': krpcResponse.transactionID,
            'y': 'r',
            'r': {
                'id': bytes(krpcResponse.fromNode)
            }
        }
        
    return bencodepy.encode(response)
Beispiel #36
0
    def startProtocol(self):
        data = {
            'y': 'q',
            'q': 'find_node',
            'a': {
                'id': hashlib.sha1(b'bla').digest(),
                'target': hashlib.sha1(b'bla2').digest()
            },
            't': b'44'
        }

        self.transport.write(bencodepy.encode(data), ('127.0.0.1', 8043))
        print("Sent find node")
Beispiel #37
0
def make_magnet_from_torrent_file(file):
    metadata = bencodepy.decode_from_file(file)
    subj = metadata.get(b"info", {})
    hashcontents = bencodepy.encode(subj)
    digest = hashlib.sha1(hashcontents).digest()
    b16hash = base64.b16encode(digest).decode().lower()
    return ("magnet:?" + "xt=urn:btih:" + b16hash + "&dn=" +
            metadata.get(b"info", {}).get(b"name", b"").decode() + "&tr=" +
            metadata.get(b"announce", b"").decode() + "".join([
                "&tr=" + tr.decode()
                for trlist in metadata.get(b"announce-list", [])
                for tr in trlist if tr.decode().strip()
            ]) + "&xl=" + str(metadata.get(b"info", {}).get(b"length")))
Beispiel #38
0
 def startProtocol(self):
     data = {
         'y': 'q',
         'q': 'get_peers',
         'a': {
             'id': hashlib.sha1(b'bla').digest(),
             'info_hash': hashlib.sha1(b'someTorrent').digest()
         },
         't': b'42'
     }
     
     self.transport.write(bencodepy.encode(data), ('127.0.0.1', 8043))
     
     print("Sent get_peers")
Beispiel #39
0
def generate_magnet_from_file(file) :
    meta_data     = bencodepy.decode_from_file(file)
    meta_info     = meta_data[b'info']
    meta_announce = meta_data[b'announce']

    hash_contents = bencodepy.encode(meta_info)
    digest        = hashlib.sha1(hash_contents).digest()
    b32hash       = base64.b32encode(digest).decode()

    return "magnet:?xt=urn:btih:{0}&dn={1}&tr={2}".format(
        b32hash,
        meta_info[b'name'].decode(),
        meta_announce.decode()
    )
Beispiel #40
0
 def startProtocol(self):
     data = {
         'y': 'q',
         'q': 'find_node',
         'a': {
             'id': hashlib.sha1(b'bla').digest(),
             'target': hashlib.sha1(b'bla2').digest()
         },
         't': b'44'
     }
     
     
     self.transport.write(bencodepy.encode(data), ('127.0.0.1', 8043))
     print("Sent find node")
Beispiel #41
0
def make_magnet_from_file(file):  # Создание magnet ссылок из torrent файла
    try:
        metadata = bencodepy.decode_from_file(file)
    except:
        # print('Вы использовали доступное Вам количество торрент-файлов в сутки')
        return 'Вы использовали доступное Вам количество торрент-файлов в сутки'
    subj = metadata[b'info']
    hashcontents = bencodepy.encode(subj)
    digest = hashlib.sha1(hashcontents).digest()
    b32hash = base64.b32encode(digest).decode()
    return 'magnet:?'\
             + 'xt=urn:btih:' + b32hash\
             + '&dn=' + metadata[b'info'][b'name'].decode()\
             + '&tr=' + metadata[b'announce'].decode()\
Beispiel #42
0
    def from_dict(cls, dictionary: OrderedDict):
        info_hash = hashlib.sha1(bencodepy.encode(dictionary)).digest()

        if len(dictionary[b'pieces']) % SHA1_DIGEST_LEN != 0:
            raise ValueError('Invalid length of "pieces" string')
        piece_hashes = grouper(dictionary[b'pieces'], SHA1_DIGEST_LEN)

        if b'files' in dictionary:
            files = list(map(FileInfo.from_dict, dictionary[b'files']))
        else:
            files = [FileInfo.from_dict(dictionary)]

        return cls(info_hash,
                   dictionary[b'piece length'], piece_hashes, get_utf8(dictionary, b'name').decode(), files,
                   private=dictionary.get('private', False))
Beispiel #43
0
 def datagramReceived(self, data, addressPort):
     (address, port) = addressPort
     print("Datagram %s received from %s" % (repr(data), repr((address, port))))
     
     data = bencodepy.decode(data)
     if data[b'y'] == b'r' and data[b't'] == b'42':
         token = data[b'r'][b'token']
         newData = {
             'y': 'q',
             'q': 'announce_peer',
             'a': {
                 'id': hashlib.sha1(b'bla').digest(),
                 'info_hash': hashlib.sha1(b'someTorrent').digest(),
                 'port': 8046,
                 'token': token
             },
             't': b'43'
         }
         
         self.transport.write(bencodepy.encode(newData), ('127.0.0.1', 8043))
         
         print("Sent announce")
Beispiel #44
0
def infohash(tdict):
    """
    given a decoded torrent file compute the infohash
    """
    return hashlib.sha1(bencodepy.encode(tdict[b'info'])).digest()
Beispiel #45
0
 def test_no_exception_when_not_strict(self):
     invalid_obj = None
     bencodepy.encode(invalid_obj, strict=False)
     self.assert_(True)
Beispiel #46
0
    def find_new(self):
        # find our shows
        builtins = ('daemon', 'transmission', 'defaults', 'tvdb')
        shows = [s for s in self.config.sections() if s not in builtins]
        defaults = self.config.items('defaults', SHOW_DEFAULTS)

        for cfg_name in shows:
            show = self.config.items(cfg_name, defaults)
            show['name'] = show.get('name', cfg_name)
            show['feed_search'] = show.get('feed_search', show['name'])
            log.debug('Looking up %s' % show['feed_search'])

            # if we're at downloading max_concurrent episodes, then stop
            # processing this show
            max_concurrent = int(show.get('max_concurrent'))
            c = self.db.cursor()
            c.execute(
                'select count(*) from shows where cfg_name=? and status=?',
                (cfg_name, STATUS_INCOMPLETE)
            )
            count = c.fetchone()[0]
            if count >= max_concurrent:
                log.debug(
                    'Reached maximum concurrent torrents (%d) for "%s".' % (
                        max_concurrent, cfg_name)
                )
                continue

            # Get the show data from TVDB
            if show.get('tvdb_id'):
                try:
                    tvdb_show = self.tvdb.get(show['tvdb_id'], self.tvdb_lang)
                except tvdb_error.TVDBIdError:
                    result = []
            else:
                result = self.tvdb.search(show['name'], self.tvdb_lang)
                if not len(result):
                    log.error('Show not found on tvdb: %s' % show['name'])
                    continue

                if len(result) > 1:
                    log.warning('Multiple matches found for "{r.search}"'
                                .format(r=result))

                tvdb_show = result[0]
            try:
                # if show has a season 0 (extras), don't count it in the total
                # number of seasons.
                tvdb_show[0]
            except tvdb_error.TVDBIndexError:
                num_seasons = len(tvdb_show)
            else:
                num_seasons = len(tvdb_show) - 1

            if num_seasons <= 0:
                log.error('No seasons found for "{r.search}"'.format(r=result))
                continue

            # Get last downloaded season from the database to see which season
            # to start with. If no downloads, use start_season
            c = self.db.cursor()
            c.execute(
                'select max(season) from shows where cfg_name=?', (cfg_name,))
            max = c.fetchone()[0]
            start_season = max or show['start_season']

            # load torrent feeds one season at a time, since the feed only
            # returns a max of 30 shows.
            entries = []
            for season in range(int(start_season), num_seasons + 1):
                # load rss feed:
                feed_params = {
                    'mode': 'rss',
                    'show_name': show['feed_search'],
                    'quality': show.get('quality'),
                    'season': season
                }
                if show.get('feed_search_exact', 'false').lower() != 'false':
                    feed_params['show_name_exact'] = 'true'

                show_feed_url = feed_url + '?' + urlencode(feed_params)
                log.debug('checking feed url: %s' % show_feed_url)
                feed = feedparser.parse(show_feed_url)

                log.debug('found %d entries for %s, season %s' %
                          (len(feed['entries']), show['name'], season))

                # assume that feed has given episodes sorted by seed quality,
                # and maintain that order.
                for i, e in enumerate(feed['entries']):
                    feed['entries'][i]['ord'] = i

                # sort feed entries by episode
                def ordkey(ep):
                    summary = self._parse_summary(ep['summary'])
                    return summary['episode'] * 100 + ep['ord']
                entries += sorted(feed['entries'], key=ordkey)

                eps = [self._parse_summary(e['summary'])['episode']
                       for e in entries]
                log.debug('   Found episodes: {}'
                          .format(str([int(s) for s in set(eps)])))

            added = 0
            for entry in entries:
                if count >= max_concurrent:
                    log.info(
                        'Reached maximum concurrent torrents (%d) for this '
                        'show "%s".' % (max_concurrent, cfg_name))
                    break

                link = entry['link']
                summary = entry['summary']

                # parse summary details (assuming ezrss keeps this consistent)
                # ex: 'Show Name: Dexter; Episode Title: My Bad; Season: 5;
                # Episode: 1'
                info = self._parse_summary(summary)
                log.debug(
                    'Found: %(show_name)s: Season: %(season)s; '
                    'Episode: %(episode)s; Title: %(title)s' % info
                )

                season = int(info['season'])
                episode = int(info['episode'])

                # skip if less than start_episode. eg, s04e06 would be 406
                e2n = lambda s, e: int(s) * 100 + int(e)
                start_ssn = show['start_season']
                start_ep = show['start_episode']
                if (e2n(season, episode) < e2n(start_ssn, start_ep)):
                    log.debug(
                        'Skipping, s%02de%02d is earlier than start_episode'
                        % (season, episode))
                    continue

                # Check and see if we need this episode
                c = self.db.cursor()
                c.execute(
                    'SELECT COUNT() FROM shows WHERE cfg_name=? '
                    'AND season=? AND episode=?', (cfg_name, season, episode)
                )
                if c.fetchone()[0] > 0:
                    # already have this one, or are already downloading it.
                    log.debug(
                        '"%(show_name)s-%(season)s-%(episode)s" has already '
                        'been downloaded or is currently downloading' % info
                    )
                    continue

                # Get torrent file so that we can parse info out of it
                log.debug('Decoding torrent...')
                try:
                    request = Request(link)
                    request.add_header('Accept-encoding', 'gzip')
                    response = urlopen(request)
                except HTTPError as e:
                    log.debug('Could not download torrent: %s, %s' % (link, e))
                    continue

                if response.info().get('Content-Encoding') == 'gzip':
                    buf = io.BytesIO(response.read())
                    f = gzip.GzipFile(fileobj=buf)
                    data = f.read()
                else:
                    data = response.read()

                try:
                    torrent = bencodepy.decode(data)
                except DecodingError as e:
                    log.debug(str(e))
                    log.error('Could not parse torrent: %s' % link)
                    continue

                filename = torrent[b'info'].get(b'name').decode()
                if not filename:
                    files = torrent[b'info'][b'files']
                    # get largest file
                    files = sorted(
                        files, key=lambda f: f['length'], reverse=True)
                    filename = files[0]['path']

                ext = os.path.splitext(filename)[1][1:]
                if ext in show['exclude_extensions'].split(','):
                    log.debug(
                        'Skipping %s, file extension blacklisted' % filename)
                    continue

                # Add the show
                added += 1
                log.info(
                    'Adding %(show_name)s-%(season)s-%(episode)s to '
                    'transmission queue' % info)
                log.debug(link)
                b64_data = base64.b64encode(data).decode()
                try:
                    trans_info = self.transmission.add_torrent(b64_data)
                except transmissionrpc.error.TransmissionError as e:
                    if '"duplicate torrent"' in str(e):
                        log.info('Torrent already exists. Resuming.')
                        # TODO: Find the duplicate torrent
                        binfo = bencodepy.encode(torrent[b'info'])
                        hash = hashlib.sha1(binfo)
                        trans_info = self.transmission.inf(hash.hexdigest())
                        self.transmission.start(trans_info.id)
                    else:
                        raise

                # Record in db
                c = self.db.cursor()
                show_name = tvdb_show.SeriesName
                try:
                    title = tvdb_show[season][episode].EpisodeName
                except (tvdb_error.TVDBIndexError, KeyError):
                    title = info.get('title', '(no title)')
                c.execute(
                    'INSERT INTO shows (name, season, episode, title, status, '
                    'url, transid, cfg_name) VALUES (?, ?, ? ,? ,? ,?, ?, ?)',
                    (show_name, season, episode, title, STATUS_INCOMPLETE,
                     link, trans_info.id, cfg_name)
                )
                self.db.commit()
                count += 1

            if added == 0:
                log.info('No new episodes found for %s' % cfg_name)
Beispiel #47
0
 def test_encode_str(self):
     coded = bencodepy.encode('ThisIsAString')
     self.assertEqual(coded, b'13:ThisIsAString', msg='Failed to encode string from str.')
Beispiel #48
0
 def test_encode_int(self):
     coded = bencodepy.encode(42)
     self.assertEqual(coded, b'i42e', msg='Failed to encode integer from int.')
Beispiel #49
0
 def send_krpc(self, msg, address):
     try:
         self.ufd.sendto(encode(msg), address)
     except Exception:
         pass
Beispiel #50
0
 def test_encode_list(self):
     l = ['a', 'b', 3]
     coded = bencodepy.encode(l)
     self.assertEqual(coded, b'l1:a1:bi3ee', msg='Failed to encode list from list.')
Beispiel #51
0
	def send_krpc(self, message, address):
		try:
			self.sock.sendto(encode(message), address)
		except Exception as error:
			self.logger.error("send_krpc: {}".format(error))
Beispiel #52
0
 def test_encode_tuple(self):
     t = ('a', 'b', 3)
     coded = bencodepy.encode(t)
     self.assertEqual(coded, b'l1:a1:bi3ee', msg='Failed to encode list from tuple.')
Beispiel #53
0
 def test_encode_dict(self):
     od = collections.OrderedDict()
     od['ka'] = 'va'
     od['kb'] = 2
     coded = bencodepy.encode(od)
     self.assertEqual(coded, b'd2:ka2:va2:kbi2ee', msg='Failed to encode dictionary from dict.')
Beispiel #54
0
def send_request_metadata(s, ut_metadata, i):
    msg_body = {"m": {"msg_type": 0, "piece": i}}
    msg = b"\x14" + chr(ut_metadata).encode() + bencodepy.encode(msg_body)
    send_msg(s, msg)
Beispiel #55
0
 def test_exception_when_strict(self):
     invalid_obj = None
     with self.assertRaises(bencodepy.EncodingError):
         bencodepy.encode(invalid_obj, strict=True)
Beispiel #56
0
def open_torrent_url(url):
  """Mount the specified torrent and open it in the file browser

  Keyword arguments:
  url -- url to download the torrent file, path of torrent in filesystem, or magnet url
  """

  url_parsed = urlparse(url)
  
  
  # Magnet
  if url_parsed.scheme == 'magnet':
    print('MAGNET', url)
    query_params = parse_qs(url_parsed.query)
    
    magnet_params = {}
    if 'tr' in query_params:
      magnet_params['tr'] = query_params['tr']
    
    if magnet_params:
      encoded_params = '&' + urlencode(magnet_params, doseq=True)
    else:
      encoded_params = ''
    
    # For each torrent in the magnet
    for param_name, param_data in query_params.items():
      if param_name[:2] != 'xt':
        continue
      
      xt_data = param_data[0]
      
      btih = re.search(r'^urn:btih:([0-9a-fA-F]{40}|[2-7A-Z]{32})$', xt_data)
      if btih is not None:
        btih = btih.group(1)
        
        # Hex encoded
        if (len(btih) == 40):
          btih = btih.lower()
          
        # Base32 encoded
        else:
          btih = base64.b32decode(btih).hex()
        
        open_torrent_btih(btih, 'magnet:?xt=' + xt_data + encoded_params)
    
    return
    
    
  # Download torrent from URL
  if len(url_parsed.scheme):
    print('URL', url)
    torrent_file = os.path.join(config.torrent_dir, hashlib.md5(url.encode('utf-8')).hexdigest()+'.torrent')
    urllib.request.urlretrieve(url, torrent_file)
    url = torrent_file
  
  
  # Open torrent in file system
  if os.path.isfile(url):
    print('FILE', url)
    
    # Calculate bittorrent info hash
    metadata = bencodepy.decode_from_file(url)
    hashcontents = bencodepy.encode(metadata[b'info'])
    digest = hashlib.sha1(hashcontents).digest()
    btih = digest.hex()
    
    open_torrent_btih(btih, url)
    return
  
  
  print('Torrent URL is not supported')
Beispiel #57
0
def dumpTorrent(tdict, fd):
    """
    dump a parsed torrent into a file
    """
    data = bencodepy.encode(tdict)
    fd.write(data)
Beispiel #58
0
 def test_encode_bytes(self):
     pass
     b = b"TheseAreSomeBytes"
     coded = bencodepy.encode(b)
     l = bytes(str(len(b)), 'utf-8')
     self.assertEqual(coded, l + b':' + b, msg='Failed to encode string from bytes.')
Beispiel #59
0
def get_hash(binary):
	decoded_data = bencodepy.decode(binary)
	decoded_info = decoded_data[b'info']
	encoded_info = bencodepy.encode(decoded_info)
	torrent_hash = hashlib.sha1(encoded_info).hexdigest()
	return torrent_hash
Beispiel #60
0
 def send_krpc(self, msg, address):
     try:
         self.socket.sendto(bencodepy.encode(msg), address)
     except Exception:
         pass