def __init__(self, info_dict: Dict[bytes, Any], torrent_entry_id: int = 0) -> None: self._rows: List[_FileInfoRow] = [] self._torrent_entry_id = torrent_entry_id encoding: Optional[str] if b"files" in info_dict: offset = 0 files = cast(List[Dict[bytes, Any]], info_dict[b"files"]) utf8 = b"name.utf-8" in info_dict and all(b"path.utf-8" in v for v in files) for index, file_dict in enumerate(files): length = cast(int, file_dict[b"length"]) encoding = None if utf8: name = cast(bytes, info_dict[b"name.utf-8"]) path = cast(List[bytes], file_dict[b"path.utf-8"]) encoding = "utf-8" else: name = cast(bytes, info_dict[b"name"]) path = cast(List[bytes], file_dict[b"path"]) path = [name] + path self._rows.append( _FileInfoRow( id=torrent_entry_id, file_index=index, path=better_bencode.dumps(path), encoding=encoding, start=offset, stop=offset + length, )) offset += length else: length = cast(int, info_dict[b"length"]) utf8 = b"name.utf-8" in info_dict encoding = None if utf8: name = cast(bytes, info_dict[b"name.utf-8"]) encoding = "utf-8" else: name = cast(bytes, info_dict[b"name"]) self._rows.append( _FileInfoRow( id=torrent_entry_id, file_index=0, path=better_bencode.dumps([name]), encoding=encoding, start=0, stop=length, ))
def send_message(self, data, addr): data.setdefault(b"t", b"tt") try: msg = better_bencode.dumps(data) self.transport.sendto(msg, addr) except: logging.warning(data)
def test_update(self) -> None: info = better_bencode.dumps({ b"name": b"test.txt", b"length": 1000, b"pieces": b"\0" * 40 }) torrents_db.TorrentInfoUpdate(1, info).apply(self.conn) self.assert_golden_db(self.conn)
def __init__( self, torrent_entry_id: int, torrent_file: Union[bytes, memoryview, bytearray], ) -> None: # TODO: optimize self._inner = TorrentInfoUpdate( torrent_entry_id, better_bencode.dumps(better_bencode.loads(torrent_file)[b"info"]), )
def check( self, info: Dict[bytes, Any], expected: List[Tuple[int, int, bytes, Optional[str], int, int]], ) -> None: self.update_entry(self.entry) with self.assert_changes() as change: change.entry(ids=(self.entry_id, )) self.update_torrent_info(self.entry_id, better_bencode.dumps(info)) self.assert_file_info(expected)
def send_message(self, data, addr): data.setdefault(b"t", b"tt") if b"q" in data.keys() and data[b"q"] == b"find_node": self.transport.sendto( b"d1:ad2:id20:%s6:target20:%se1:q9:find_node1:t2:aa1:y1:qe" % (data[b"a"][b"id"], data[b"a"][b"target"]), addr) else: try: self.transport.sendto(better_bencode.dumps(data), addr) except: print(data)
def command(self, cmd): c = self.gencookie() df = defer.Deferred() self.cookies[c] = df msg = c + ' ' + bencode.dumps(cmd) if self.transport: self.send(msg) else: log.msg('Not ready, will be sent later') self.cache.append(msg) return df
def get(self, iid): """ Return a torrent adjusted correctly for webtorrents """ fs = download(iid, iid + '_archive.torrent').content t = better_bencode.loads(fs) # print(t) t[b'url-list'] = [b'https://api.archivelab.org/webtorrents/files/'] t[b'announce'] = b'wss://tracker.webtorrent.io' t[b'announce-list'] = [[b'wss://tracker.webtorrent.io'], [b'wss://tracker.btorrent.xyz'], [b'wss://tracker.fastcast.nz'], [b'wss://tracker.openwebtorrent.com']] return Response(better_bencode.dumps(t), mimetype=mimetype(iid + '_archive.torrent'))
def get(self, iid): """ Return a torrent adjusted correctly for webtorrents """ fs = download(iid, iid + '_archive.torrent').content t = better_bencode.loads(fs) # print(t) t[b'url-list'] = [b'https://api.archivelab.org/v2/webtorrents/files/'] t[b'announce'] = b'wss://tracker.webtorrent.io' t[b'announce-list'] = [[b'wss://tracker.webtorrent.io'], [b'wss://tracker.btorrent.xyz'], [b'wss://tracker.fastcast.nz'], [b'wss://tracker.openwebtorrent.com']] return Response( better_bencode.dumps(t), mimetype=mimetype(iid + '_archive.torrent') )
async def torrent2magnet(chat, document): logger.info('torrent2magnet: session start [%d]', chat.sender['id']) try: torrent = await t2m_bot.get_file(document['file_id']) async with t2m_bot.download_file(torrent['file_path']) as resp: if resp.status == 200: try: metadata = better_bencode.loads(await resp.read()) if b'info' not in metadata: raise Exception('No `info` field in meta data') hashcontents = better_bencode.dumps(metadata[b'info']) digest = hashlib.sha1(hashcontents).digest() info_hash = binascii.hexlify(digest).decode('ascii') except Exception: logger.exception('torrent2magnet: Wrong meta data') await chat.send_text( 'Failed convert torrent file to magnet link ' '(wrong metadata). Sorry 😫') else: extra_params = {} if b'name' in metadata[b'info']: extra_params.update( {'dn': metadata[b'info'][b'name'].decode('ascii')}) if b'length' in metadata[b'info']: extra_params.update( {'xl': metadata[b'info'][b'length']}) if b'announce' in metadata: extra_params.update( {'tr': metadata[b'announce'].decode('ascii')}) ep = '' if extra_params: ep = '&' + urllib.parse.urlencode(extra_params) await chat.send_text('magnet:?xt=urn:btih:%s%s' % (info_hash, ep)) else: raise RuntimeError('HTTP error [status={}]'.format( resp.status)) except Exception: await chat.send_text('Failed convert torrent file to magnet. Sorry 😫') logger.exception('torrent2magnet: unhandled error')
async def torrent2magnet(chat, document): logger.info('torrent2magnet: session start [%d]', chat.sender['id']) try: torrent = await t2m_bot.get_file(document['file_id']) async with t2m_bot.download_file(torrent['file_path']) as resp: if resp.status == 200: try: metadata = better_bencode.loads(await resp.read()) if b'info' not in metadata: raise Exception('No `info` field in meta data') hashcontents = better_bencode.dumps(metadata[b'info']) digest = hashlib.sha1(hashcontents).digest() info_hash = binascii.hexlify(digest).decode('ascii') except Exception: logger.exception('torrent2magnet: Wrong meta data') await chat.send_text('Failed convert torrent file to magnet link ' '(wrong metadata). Sorry 😫') else: extra_params = {} if b'name' in metadata[b'info']: extra_params.update({'dn': metadata[b'info'][b'name'].decode('ascii')}) if b'length' in metadata[b'info']: extra_params.update({'xl': metadata[b'info'][b'length']}) if b'announce' in metadata: extra_params.update({'tr': metadata[b'announce'].decode('ascii')}) ep = '' if extra_params: ep = '&' + urllib.parse.urlencode(extra_params) await chat.send_text('magnet:?xt=urn:btih:%s%s' % (info_hash, ep)) else: raise RuntimeError('HTTP error [status={}]'.format(resp.status)) except Exception: await chat.send_text('Failed convert torrent file to magnet. Sorry 😫') logger.exception('torrent2magnet: unhandled error')
def dumps(obj) -> bytes: try: return better_bencode.dumps(obj) except: raise BencodeEncodingError()
def encode(message: Message) -> bytes: try: return better_bencode.dumps(message) except Exception as exc: raise EncodeError(exc)
) parser.add_argument('--comment', action='store', help="add torrent file comment") parser.add_argument('--name', action='store', help="set name of shared file/directory") parser.add_argument('--private', action='store_true', help="flag for restricted access") parser.add_argument('--output', action='store', help="save torrent to file") args = parser.parse_args() torrent_data = torrent.create_torrent_data( args.path, name=args.name, announce_list=args.announce_list, private_flag=args.private) if args.comment: torrent_data['comment'] = args.comment out = sys.stdout if args.output: out = open(args.output, 'wb') out.write(bb.dumps(torrent_data))
def encode(obj: Any) -> bytes: try: return better_bencode.dumps(obj) except Exception as e: raise BencoderError(e)