Ejemplo n.º 1
0
	def __init__(self, torrent_file):
		with open(torrent_file, 'rb') as f:
			self.torrent_file = f.read()
		self.meta_info_dict = bdecode(self.torrent_file)
		self.announce = self.meta_info_dict[b'announce'].decode('utf-8')
		self.info_dict = self.meta_info_dict[b'info']
		self.bencoded_info_dict = self.info_dict['ben_string']
		self.filename = self.info_dict[b'name'].decode('utf-8')
		self.path = 'torrents_in_progress'
		self.info_hash = sha1(self.bencoded_info_dict).digest()
		self.peer_id = '-'.join(['','TZ', '0000', str(randrange(10000000000,99999999999))])
		self.ip = self.get_IP_address()
		self.port =  '6881' #TODO: Try ports in range (6881,6889)
		self.length = int(self.info_dict[b'length']) if b'length' in self.info_dict \
				else sum([int((f[b'length'])) for f in self.info_dict[b'files']])
		self.piece_length = int(self.info_dict[b'piece length'])
		self.pieces = self.info_dict[b'pieces']
		self.piece_hashes = [self.pieces[i:i+20] for i in range(0, len(self.pieces), 20)]
		self.number_of_pieces = ceil(self.length/self.piece_length)
		self.downloaded = 0
		self.uploaded = 0
		self.have = [False] * self.number_of_pieces #TODO: pass torrent class a bitfield and handle restarting torrents
		self.complete = False #TODO: Update when self.pieces_needed is empty
		self.io_loop = get_event_loop()
		self.pieces_needed = []
Ejemplo n.º 2
0
 def __init__(self, torrent_file):
     with open(torrent_file, 'rb') as f:
         self.torrent_file = f.read()
     self.meta_info_dict = bdecode(self.torrent_file)
     self.announce = self.meta_info_dict[b'announce'].decode('utf-8')
     self.info_dict = self.meta_info_dict[b'info']
     self.bencoded_info_dict = self.info_dict['ben_string']
     self.filename = self.info_dict[b'name'].decode('utf-8')
     self.path = 'torrents_in_progress'
     self.info_hash = sha1(self.bencoded_info_dict).digest()
     self.peer_id = '-'.join(
         ['', 'TZ', '0000',
          str(randrange(10000000000, 99999999999))])
     self.ip = self.get_IP_address()
     self.port = '6881'  #TODO: Try ports in range (6881,6889)
     self.length = int(self.info_dict[b'length']) if b'length' in self.info_dict \
       else sum([int((f[b'length'])) for f in self.info_dict[b'files']])
     self.piece_length = int(self.info_dict[b'piece length'])
     self.pieces = self.info_dict[b'pieces']
     self.piece_hashes = [
         self.pieces[i:i + 20] for i in range(0, len(self.pieces), 20)
     ]
     self.number_of_pieces = ceil(self.length / self.piece_length)
     self.downloaded = 0
     self.uploaded = 0
     self.have = [
         False
     ] * self.number_of_pieces  #TODO: pass torrent class a bitfield and handle restarting torrents
     self.complete = False  #TODO: Update when self.pieces_needed is empty
     self.io_loop = get_event_loop()
     self.pieces_needed = []
Ejemplo n.º 3
0
def hash(filename):
    for file_fuck in filename:
        torrent_file = f'{torrent_folder}{file_fuck}'
        objTorrentFile = open(torrent_file, 'rb')
        decodedDict = bencoding.bdecode(objTorrentFile.read())
        objTorrentFile.close()
        info_hash = hashlib.sha1(bencoding.bencode(
            decodedDict[b"info"])).hexdigest()
        list2.append(f'{info_hash}==>{torrent_file}')
Ejemplo n.º 4
0
def read_metainfo(filepath):
    with open(filepath, 'rb') as f:
        metainfo = bencoding.bdecode(f.read())

    if metainfo is None:
        raise Exception("Metainfo read failed.")

    encoding = metainfo[b"encoding"] if b"encoding" in metainfo else b"utf-8"

    announce = meta_decode(metainfo[b"announce"], encoding)

    creation_date = meta_decode(metainfo[b"creation date"], encoding) \
        if b"creation data" in metainfo else None
    creator = meta_decode(metainfo[b"created by"], encoding) \
        if b"created by" in metainfo else None
    comment = meta_decode(metainfo[b"comment"], encoding) \
        if b"comment" in metainfo else None
    announce_list = meta_decode(metainfo[b"announce-list"], encoding) \
        if b"announce-list" in metainfo else None

    piece_length = meta_decode(metainfo[b"info"][b"piece length"], encoding)
    pieces = metainfo[b"info"][b"pieces"]
    private = meta_decode(metainfo[b"info"][b"private"], encoding) \
        if b"private" in metainfo[b"info"] else 0

    single_file_mode = b"files" not in metainfo[b"info"]
    name = meta_decode(metainfo[b"info"][b"name"], encoding)
    files = []
    if single_file_mode:
        tfile = {"length": meta_decode(metainfo[b"info"][b"length"], encoding),
                 "md5sum": meta_decode(metainfo[b"info"][b"md5sum"], encoding) \
                     if b"md5sum" in metainfo[b"info"] else None,
                 "path": None}
        files.append(tfile)
    else:
        for tf in metainfo[b"info"][b"files"]:
            tfile = {"length": meta_decode(tf[b"length"], encoding),
                     "md5sum": meta_decode(tf[b"md5sum"], encoding) \
                         if b"md5sum" in tf else None,
                     "path": meta_decode(tf[b"path"], encoding)}
            files.append(tfile)

    return {
        "announce": announce,
        "cdate": creation_date,
        "creator": creator,
        "comment": comment,
        "announce_list": announce_list,
        "single_file": single_file_mode,
        "piece_length": piece_length,
        "pieces": pieces,
        "private": private,
        "name": name,
        "files": files
    }
Ejemplo n.º 5
0
    def is_torrent_file(cls, torrent_file_path):
        if not torrent_file_path.is_file():
            return False

        with open(torrent_file_path, 'rb') as f:
            try:
                data = bdecode(f.read())
                if data.get(b'info'):
                    return True
            except DecoderError:
                return False
        return False
Ejemplo n.º 6
0
    async def get_peers(self, numwant=100):
        """
        # TODO Separate out metadata parsing and HTTP client implementation
        HTTP(S) Tracker client implementation
        :param numwant: required number of peers
        """
        peer_id = 'SA' + ''.join(
            random.choice(string.ascii_lowercase + string.digits)
            for _ in range(18))
        params = {
            'info_hash': self.info_hash,
            'peer_id': peer_id,
            'port': 6881,
            'uploaded': 0,
            'downloaded': 0,
            'left': self._total_length,
            'compact': 1,
            'no_peer_id': 1,
            'event': 'started',
            'numwant': numwant
        }
        for url in self._trackers:
            if b'udp' not in url:
                try:
                    print(url)
                    r = requests.get(url, params=params, timeout=10)
                except Exception as e:
                    print("Exception occurred for {}\n{}".format(url, e))
                    continue
                resp = bencoding.bdecode(r.content)
                print(r.status_code, r.reason)
                peers = resp[b'peers']
                start = 0

                if isinstance(peers, list):
                    self.peers = peers
                elif len(peers) % 6 == 0:
                    while start < len(peers):
                        ip = peers[start:start + 4]
                        ip = socket.inet_ntoa(ip)
                        port = peers[start + 4:start + 6]
                        port, = struct.unpack('!H', port)
                        self.peers.append((ip, port))
                        start += 6
            else:
                try:
                    print(url)
                    udp_peers = await self.udp_tracker_client(url.decode())
                    self.peers.extend(udp_peers)
                except Exception as e:
                    print("Exception occurred for {}\n{}".format(url, e))
                    continue
Ejemplo n.º 7
0
def sendAnnounce(event = ""):
    global announce_delay, announce_count
    announce_count += 1
    announce_params["event"] = event
    if (announce_params["event"] == ""):
        del announce_params["event"]
    r = requests.get(announce_url, params=announce_params, headers=announce_headers)
    body_decode = bencoding.bdecode(r.content)
    if (b'interval' in body_decode):
        announce_delay = int(body_decode[b'interval'])
    print("%s announce %02i" % (timestamp(), announce_count), end="")
    if ("event" in announce_params):
        print(" " + announce_params["event"], end="")
    print(" uploaded: %i/%iMB, downloaded: %i/%iMB" % (announce_params["uploaded"]/1024/1024, max_upload/1024/1024, announce_params["downloaded"]/1024/1024, max_down/1024/1024), end="")
    print(", delay %im%is" % (announce_delay//60, announce_delay%60))
Ejemplo n.º 8
0
    def add_torrent(self, torrent):
        with open(torrent, "rb") as file:
            data = bdecode(file.read())
        info = data[b"info"]
        hash = sha1(bencode(info)).hexdigest()
        if hash in self.torrent_hashes or []:
            raise TorrentAlreadyPresentException(hash)

        with open(torrent, "rb") as file:
            filedump = encodestring(file.read())
        filename = basename(torrent)
        result = self.client.call("core.add_torrent_file", filename, filedump, {})
        logger.debug("Returning {}", result.decode("utf-8"))
        if result.decode("utf-8") != hash:
            raise Exception(result.decode("utf-8"))
        self._torrent_hashes = None
        return True
    def add_torrent(self, torrent):
        with open(torrent, "rb") as file:
            data = bdecode(file.read())
        info = data[b"info"]
        hash = sha1(bencode(info)).hexdigest()
        if hash in self.torrent_hashes:
            raise TorrentAlreadyPresentInCollectionException(hash)

        host = min(self.hosts, key=lambda host: host.torrent_count)
        if host.torrent_count >= self.max_torrents:
            raise AllDelugeHostsInCollectionFullException()

        if host.add_torrent(torrent):
            logger.success("Added {} to {}", torrent, host.display)
            self._torrent_hashes = None
            return True
        return False
Ejemplo n.º 10
0
def add_from_file(update: Update, context: CallbackContext):
    logger.info('application/x-bittorrent document from %s',
                update.effective_user.first_name)

    document = update.message.document
    if document.mime_type != "application/x-bittorrent" and not document.file_name.lower(
    ).endswith(".torrent"):
        logger.info('invalid document from %s (mime type: %s; file name: %s)',
                    update.effective_user.full_name, document.mime_type,
                    document.file_name)

        update.message.reply_markdown(
            'Please send me a valid torrent file (`.torrent` extension or `application/x-bittorrent` mime type)',
            quote=True)
        return

    file_id = document.file_id
    torrent_file = context.bot.get_file(file_id)

    file_path = './downloads/{}'.format(document.file_name)
    torrent_file.download(file_path)

    kwargs = get_qbt_request_kwargs()

    with open(file_path, 'rb') as f:
        # https://stackoverflow.com/a/46270711
        decoded_dict = bencoding.bdecode(f.read())
        torrent_hash = hashlib.sha1(bencoding.bencode(
            decoded_dict[b"info"])).hexdigest()

        f.seek(0)

        # this method always returns an empty json:
        # https://python-qbittorrent.readthedocs.io/en/latest/modules/api.html#qbittorrent.client.Client.download_from_file
        qb.download_from_file(f, **kwargs)

    update.message.reply_text('Torrent added',
                              quote=True,
                              reply_markup=kb.short_markup(torrent_hash))

    os.remove(file_path)

    notify_addition(update.effective_chat.id, context.bot,
                    update.effective_user, document.file_name
                    or "[unknown file name]")
Ejemplo n.º 11
0
    def __init__(self, torrent_file):
        self.torrent_data = bencoding.bdecode(open(torrent_file, 'rb').read())
        self.announce = self.torrent_data['announce']
        self.info = self.torrent_data['info']
        self.info_hash = hashlib.sha1(bencoding.bencode(self.torrent_data['info'])).digest()
        self.peer_id = 'liutorrent1234567890'
        self.uploaded = 0
        self.downloaded = 0
        self.port = 6881  # how do I choose a port? randomly within the unreserved range?
        self.filename = os.path.join(os.getcwd(), self.info['name'].decode('utf-8'))  # for now, single file only
        # handshake: <pstrlen><pstr><reserved><info_hash><peer_id>
        self.handshake = ''.join([chr(19), 'BitTorrent protocol', chr(0) * 8, self.info_hash, self.peer_id])

        self.length = self.info['length'] if 'length' in self.info.keys() \
            else sum([f['length'] for f in self.info['files']])
        self.piece_len = self.info['piece length']
        self.block_len = BLOCK_LEN

        self.last_piece_len = self.length % self.piece_len
        self.num_pieces = self.length / self.piece_len + 1 * (self.last_piece_len != 0)
        self.last_piece = self.num_pieces - 1  # TODO: do I need that?
        self.last_block_len = self.piece_len % self.block_len
        self.blocks_per_piece = self.piece_len / self.block_len + 1 * (self.last_block_len != 0)
        #Pieces/need_blocks data: need_pieces BitArray represents the pieces that I need and have not requested;
        #need_blocks is a list of BitArray, each of which keeps track of blocks not yet requested
        self.need_pieces = BitArray(bin='1' * self.num_pieces)
        self.need_blocks = [BitArray(bin='1' * self.blocks_per_piece) for i in range(self.num_pieces)]
        self.have_pieces = BitArray(bin='0' * self.num_pieces)
        self.have_blocks = [BitArray(bin='0' * self.blocks_per_piece) for i in range(self.num_pieces)]
        self.pieces = defaultdict(self.blocklist)  # index : array of blocks
        self.piece_hashes = self.get_piece_hashes()
        self.initialize_file(self.filename)

        self.info_from_tracker = self.update_info_from_tracker()
        self.peers = self.get_peers()
        self.active_peers = []

        self.num_connected = 0
        self.max_connections = MAX_CONNECTIONS
Ejemplo n.º 12
0
    def get_info_hash(self):
        torrent_bytes = self.session.get(
            f"{self.DOWNLOAD_URL}{self.topic['id']}")
        if not torrent_bytes.ok:
            raise TVShowsSkipTopicError(
                'Couldn\t get torrent file', self.topic['title'])
            return

        torrent_bytes = torrent_bytes.content
        _decoded = bdecode(torrent_bytes)[b'info']
        info_hash = hashlib.sha1(bencode(_decoded)).hexdigest().upper()

        if not info_hash:
            raise TVShowsSkipTopicError(
                'Couldn\t calculate torrent hash', self.topic['title'])
            return

        if info_hash == self.topic['info_hash']:
            raise TVShowsSkipTopicError(
                'Hashes are equal', self.topic['title'])
            return

        manager.update_file(self.topic, torrent_bytes)
        return info_hash
def infohash(fname):
    objTorrentFile = open(fname, "rb")
    decodedDict = bencoding.bdecode(objTorrentFile.read())
    info_hash = hashlib.sha1(bencoding.bencode(
        decodedDict[b"info"])).hexdigest()
    return info_hash
Ejemplo n.º 14
0
 def get_torr_info_hash(data):
     import hashlib, bencoding
     bencode_dict = bencoding.bdecode(data)
     return hashlib.sha1(bencoding.bencode(
         bencode_dict[b"info"])).hexdigest()
Ejemplo n.º 15
0
    # 'numwant': '', #Optional. Number of peers that the client would like to receive from the tracker. This value is permitted to be zero. If omitted, typically defaults to 50 peers.
    # 'key': '', #Optional. An additional client identification mechanism that is not shared with any peers. It is intended to allow a client to prove their identity should their IP address change.
    # 'trackerid': '' # Optional. If a previous announce contained a tracker id, it should be set here.
}
encoded_params = parse.urlencode(params)

url = tracker_url + "?" + encoded_params

print(url)

with request.urlopen(url) as req:
    reponse = req.read().decode('ISO-8859-1')
    print(reponse)
    l = [x.encode() for x in reponse]
    l.reverse()
    dict_reponse = bencoding.bdecode(l, 'UTF-8')
    # print(repr(dict_reponse))
    if ("failure reason" in dict_reponse):
        print('Erreur tracker:', dict_reponse['failure reason'])
    else:
        if ("warning message" in dict_reponse):
            print('Avertissement tracker:', dict_reponse['warning message'])
        interval = dict_reponse['interval']
        min_interval = dict_reponse['min interval']
        tracker_id = dict_reponse['tracker id'] if 'tracker id' in dict_reponse else ''
        complete = dict_reponse['complete']
        incomplete = dict_reponse['incomplete']
        peers = dict_reponse['peers']
        if (type(peers) is collections.OrderedDict):# dict model
            pass
        else:# binary model
Ejemplo n.º 16
0
 def update_info_from_tracker(self):
     tracker_response = requests.get(self.announce, params=self.get_params())
     return bencoding.bdecode(tracker_response.text)
Ejemplo n.º 17
0
    def __init__(self, file_path):
        if os.path.isfile(file_path) and file_path.split('.')[-1] == 'torrent':
            with open(file_path, 'rb') as f:
                self.metaData = bencoding.bdecode(f.read())
        else:
            raise ValueError('Invalid torrent file')

        self._announce = self.metaData[b'announce']

        if b'private' in self.metaData[b'info']:
            self._isPrivate = True if int(
                self.metaData[b'info'][b'private']) == 1 else False
        else:
            self._isPrivate = False

        self._pieces = self.metaData[b'info'][b'pieces']

        self._piece_length = self.metaData[b'info'][b'piece length']

        if b'announce-list' not in self.metaData:
            self._trackers = [self._announce]
        else:
            self._trackers = self.metaData[b'announce-list']
            self._trackers = [
                tracker for sublist in self._trackers for tracker in sublist
                if b'ipv6' not in tracker
            ]

        if b'creation date' in self.metaData:
            self._creationDate = self.metaData[b'creation date']

        if b'comment' in self.metaData:
            self._comment = self.metaData[b'comment']

        if b'created by' in self.metaData:
            self._createdBy = self.metaData[b'created by']

        if b'encoding' in self.metaData:
            self._encoding = self.metaData[b'encoding']

        if b'files' not in self.metaData[b'info']:
            self.mode = 'single'
            self._total_length = self.metaData[b'info'][b'length']
            if b'md5sum' in self.metaData:
                self._md5sum = self.metaData[b'info'][b'md5sum']
        else:
            self.mode = 'multiple'
            self.files = self.metaData[b'info'][b'files']
            # Man Made stuff here onwards

            # self.Fractures stores File finish indexes
            self.files, self._total_length, self.fractures = self.__parse_files(
            )

        self.number_of_pieces = math.ceil(self._total_length /
                                          self._piece_length)

        print("MODE:", self.mode)
        print("TOTAL LENGTH:", self._total_length)
        print("PIECE_LEN:", self._piece_length)
        print("NO. OF PIECES:", self.number_of_pieces)
        print("LAST PIECE LEN:", self._total_length % self._piece_length)
        print("NO. OF PIECE HASHES", len(self._pieces) / 20)

        self.name = self.metaData[b'info'][b'name']  # Usage depends on mode

        self.info_hash = sha1(bencoding.bencode(
            self.metaData[b'info'])).digest()

        self.peers = []
Ejemplo n.º 18
0
def _get_hash_file(path):
    with open(path, "rb") as f:
        decodedDict = bdecode(f.read())
    hash_ = sha1(bencode(decodedDict[b'info'])).hexdigest()
    return str(hash_)
Ejemplo n.º 19
0
announce_delay = 180

arguments = sys.argv
if (len(arguments) > 1):
    if ("--help" in arguments):
        print("-t <torrent file> -mu <max_upload in MB> -md <max_down in MB> -su <min_speed in KB/s> <max_speed in KB/s> -sd <min_speed in KB/s> <max_speed in KB/s>")
        sys.exit()
    else:
        max_down = 0
        max_upload = 0
        speed_up = (800, 3000)
        speed_down = (800, 2000)

        if ("-f" in arguments):
            torrent_file = open(arguments[arguments.index("-f") + 1], "rb")
            torrent_decoded = bencoding.bdecode(torrent_file.read())
            announce_params["info_hash"] = codecs.decode(hashlib.sha1(bencoding.bencode(torrent_decoded[b"info"])).hexdigest(), "hex")
            torrent_length = (len(torrent_decoded[b"info"][b"pieces"]) / 20) * torrent_decoded[b"info"][b"piece length"]
            announce_url = torrent_decoded[b"announce"]
            print("torrent size: %iMB" % (torrent_length // 1024 // 1024))
            max_upload = random.randrange(40, 80) * torrent_length // 100
            max_down = random.randrange(1, 8) * torrent_length // 100

        if ("-mu" in arguments):
            max_upload = int(arguments[arguments.index("-mu") + 1]) * 1024 * 1024
        if ("-md" in arguments):
            max_down = int(arguments[arguments.index("-md") + 1]) * 1024 * 1024
        if ("-su" in arguments):
            speed_up = (int(arguments[arguments.index("-su") + 1]), int(arguments[arguments.index("-su") + 2]))
        if ("-sd" in arguments):
            speed_down = (int(arguments[arguments.index("-sd") + 1]), int(arguments[arguments.index("-sd") + 2]))
Ejemplo n.º 20
0
import os, bencoding, hashlib
for f_name in os.listdir('1'):
    if f_name.endswith('.torrent'):
        #     print(f_name)

        objTorrentFile = open("1/%s" % f_name, "rb")
        decodedDict = bencoding.bdecode(objTorrentFile.read())

        info_hash = hashlib.sha1(bencoding.bencode(
            decodedDict[b"info"])).hexdigest()

        print('magnet:?xt=urn:btih:%s' % info_hash)