def __init__(self, loop, token, incoming_queue, outgoing_queue, bale_futures, timeout): self._loop = loop self.network = Network(token=token, incoming_queue=incoming_queue, outgoing_queue=outgoing_queue, loop=loop) self._bale_futures = bale_futures self.timeout = timeout
class Bot: def __init__(self, loop, token, incoming_queue, outgoing_queue, bale_futures, timeout): self._loop = loop self.network = Network(token=token, incoming_queue=incoming_queue, outgoing_queue=outgoing_queue, loop=loop) self._bale_futures = bale_futures self.timeout = timeout def set_future(self, request_id, request_body, success_callback=None, failure_callback=None, **kwargs): response_body_module, response_body_class = RequestToResponseMapper.get_response(request_body) bale_future = BaleFuture(request_id, response_body_module, response_body_class, success_callback, failure_callback, **kwargs) self._bale_futures.append(bale_future) self._loop.call_later(self.timeout, functools.partial(self.timeout_future, bale_future)) def timeout_future(self, bale_future): if bale_future in self._bale_futures: bot_timeout_json = {"body": {"tag": "CLIENT_REQUEST_TIMEOUT"}} error_response = response.Response(bot_timeout_json) bale_future.reject(error_response) self._bale_futures.remove(bale_future) def send_request(self, request_data): self.network.send(request_data) def reply(self, update, message, success_callback=None, failure_callback=None, **kwargs): if isinstance(update, FatSeqUpdate) and update.is_message_update(): message_id = update.body.random_id user_peer = update.get_effective_user() if isinstance(message, BaseMessage): return self.send_message(message, user_peer, BotQuotedMessage(message_id, user_peer), success_callback=success_callback, failure_callback=failure_callback, **kwargs) else: return self.send_message(TextMessage(message), user_peer, BotQuotedMessage(message_id, user_peer), success_callback=success_callback, failure_callback=failure_callback, **kwargs) def respond(self, update, message, success_callback=None, failure_callback=None, **kwargs): user_peer = update.get_effective_user() if isinstance(message, BaseMessage): return self.send_message(message, user_peer, success_callback=success_callback, failure_callback=failure_callback, **kwargs) else: return self.send_message(TextMessage(message), user_peer, success_callback=success_callback, failure_callback=failure_callback, **kwargs) # messaging def send_message(self, message, peer, quoted_message=None, random_id=None, success_callback=None, failure_callback=None, **kwargs): receiver = peer request_body = SendMessage(message=message, receiver_peer=receiver, quoted_message=quoted_message, random_id=random_id) request = Request(service=ServiceType.Messaging, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request def edit_message(self, message, user_peer, random_id, success_callback=None, failure_callback=None, **kwargs): text_message = message receiver = user_peer request_body = EditMessage(updated_message=text_message, peer=receiver, random_id=random_id) request = Request(service=ServiceType.Messaging, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request # group def create_group(self, title, success_callback=None, failure_callback=None, **kwargs): request_body = CreateGroup(title) request = Request(service=ServiceType.Groups, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request def get_group_api_struct(self, group_id, client_user_id, success_callback=None, failure_callback=None, **kwargs): request_body = GetGroupApiStruct(group_id=group_id, client_user_id=client_user_id) request = Request(service=ServiceType.Groups, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request def invite_user(self, group_peer_id, group_peer_access_hash, user_peer_id, user_peer_access_hash, success_callback=None, failure_callback=None, **kwargs): group_peer = GroupPeer(peer_id=group_peer_id, access_hash=group_peer_access_hash) user_peer = UserPeer(peer_id=user_peer_id, access_hash=user_peer_access_hash) request_body = InviteUser(group_peer=group_peer, user_peer=user_peer) request = Request(service=ServiceType.Groups, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request # sequence-update def get_difference(self, seq, how_many, success_callback=None, failure_callback=None, **kwargs): request_body = GetDifference(seq=seq, how_many=how_many) request = Request(service=ServiceType.SequenceUpdate, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request # last_sequence def get_last_seq(self, success_callback=None, failure_callback=None, **kwargs): request_body = GetLastSequence() request = Request(service=ServiceType.SequenceUpdate, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request # file def get_file_download_url(self, file_id, user_id, file_type, file_version=1, is_server=False, is_resume_upload=False, success_callback=None, failure_callback=None, **kwargs): request_body = GetFileDownloadUrl(file_id, user_id, file_type, file_version, is_server, is_resume_upload) request = Request(service=ServiceType.Files, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request def get_file_upload_url(self, size, crc, file_type, is_server=False, success_callback=None, failure_callback=None, **kwargs): request_body = GetFileUploadUrl(size, crc, file_type, is_server) request = Request(service=ServiceType.Files, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request def download_file(self, file_id, user_id, file_type="file", success_callback=None, failure_callback=None, **kwargs): future = BaleFuture(request_id=None, response_body_module=None, response_body_class=None, success_callback=success_callback, failure_callback=failure_callback, **kwargs) def file_download_url_success(result, user_data): async def get_data(download_url): try: async with aiohttp.ClientSession() as session: async with session.get(download_url) as download_response: status = download_response.status if status == 200: byte_stream = await download_response.content.read() future.set_user_data(byte_stream=byte_stream) future.resolve(response=None) else: future.reject(response=None) except Exception as e: future.reject(response=None) url = result.body.url asyncio.ensure_future(get_data(url)) def file_download_url_failure(result, user_data): future.reject(response=result) self.get_file_download_url(file_id, user_id, file_type, success_callback=file_download_url_success, failure_callback=file_download_url_failure) def upload_file(self, file, file_type, success_callback=None, failure_callback=None, **kwargs): future = BaleFuture(request_id=None, response_body_module=None, response_body_class=None, success_callback=success_callback, failure_callback=failure_callback, **kwargs) buffer = get_file_buffer(file=file) if buffer is None: future.reject(response=None) return file_size = get_file_size(buffer) file_crc32 = get_file_crc32(buffer) def file_upload_url_success(result, user_data): file_id = result.body.file_id user_id = result.body.user_id url = result.body.url dup = result.body.dup data = buffer headers = {'filesize': str(file_size)} async def upload_data(): try: async with aiohttp.ClientSession() as session: async with session.put(url, data=data, headers=headers) as upload_response: status = upload_response.status if status == 200: future.set_user_data(file_id=file_id, user_id=user_id, url=url, dup=dup) future.resolve(response=None) else: future.reject(response=None) except Exception as e: future.reject(response=None) asyncio.ensure_future(upload_data()) def file_upload_url_failure(result, user_data): future.reject(response=result) self.get_file_upload_url(size=file_size, crc=file_crc32, file_type=file_type, success_callback=file_upload_url_success, failure_callback=file_upload_url_failure) def send_photo(self, user_peer, image, caption_text="", name="", file_storage_version=1, mime_type="image/jpeg", success_callback=None, failure_callback=None, **kwargs): image_buffer = get_file_buffer(file=image) file_size = sys.getsizeof(image_buffer) im = Image.open(io.BytesIO(image_buffer)) width, height = im.size thumb = get_image_thumbnails(im) def success_upload_image(user_data, server_response): file_id = str(server_response.get("file_id", None)) access_hash = str(server_response.get("user_id", None)) photo_message = PhotoMessage(file_id=file_id, access_hash=access_hash, name=name, file_size=file_size, mime_type=mime_type, file_storage_version=file_storage_version, width=width, height=height, caption_text=TextMessage(text=caption_text), thumb=thumb) self.send_message(message=photo_message, peer=user_peer, success_callback=success_callback, failure_callback=failure_callback, kwargs=kwargs) self.upload_file(file=image, file_type="file", success_callback=success_upload_image, failure_callback=failure_callback) def send_document(self, user_peer, doc_file, mime_type, caption_text="", file_type="file", name="", file_storage_version=1, success_callback=None, failure_callback=None, **kwargs): file_size = os.path.getsize(doc_file) def success_upload_document(user_data, server_response): file_id = str(server_response.get("file_id", None)) access_hash = str(server_response.get("user_id", None)) document_message = DocumentMessage(file_id=file_id, access_hash=access_hash, name=name, file_size=file_size, mime_type=mime_type, caption_text=TextMessage(text=caption_text), file_storage_version=file_storage_version) self.send_message(message=document_message, peer=user_peer, success_callback=success_callback, failure_callback=failure_callback, kwargs=kwargs) self.upload_file(file=doc_file, file_type=file_type, success_callback=success_upload_document, failure_callback=failure_callback)
class Bot: def __init__(self, loop, token, incoming_queue, outgoing_queue, bale_futures, timeout): self._loop = loop self.network = Network(token=token, incoming_queue=incoming_queue, outgoing_queue=outgoing_queue, loop=loop) self._bale_futures = bale_futures self.timeout = timeout def set_future(self, request_id, request_body, success_callback=None, failure_callback=None, **kwargs): response_body_module, response_body_class = RequestToResponseMapper.get_response( request_body) bale_future = BaleFuture(request_id, response_body_module, response_body_class, success_callback, failure_callback, **kwargs) self._bale_futures.append(bale_future) self._loop.call_later( self.timeout, functools.partial(self.timeout_future, bale_future)) def timeout_future(self, bale_future): if bale_future in self._bale_futures: bot_timeout_json = {"body": {"tag": "CLIENT_REQUEST_TIMEOUT"}} error_response = response.Response(bot_timeout_json) bale_future.reject(error_response) self._bale_futures.remove(bale_future) def send_request(self, request_data): self.network.send(request_data) def reply(self, update, message, success_callback=None, failure_callback=None, **kwargs): if isinstance(update, FatSeqUpdate) and update.is_message_update(): message_id = update.body.random_id user_peer = update.get_effective_user() if isinstance(message, BaseMessage): self.send_message(message, user_peer, BotQuotedMessage(message_id, user_peer), success_callback=success_callback, failure_callback=failure_callback, **kwargs) else: self.send_message(TextMessage(message), user_peer, BotQuotedMessage(message_id, user_peer), success_callback=success_callback, failure_callback=failure_callback, **kwargs) def respond(self, update, message, success_callback=None, failure_callback=None, **kwargs): user_peer = update.get_effective_user() if isinstance(message, BaseMessage): self.send_message(message, user_peer, success_callback=success_callback, failure_callback=failure_callback, **kwargs) else: self.send_message(TextMessage(message), user_peer, success_callback=success_callback, failure_callback=failure_callback, **kwargs) # messaging def send_message(self, message, peer, quoted_message=None, random_id=None, success_callback=None, failure_callback=None, **kwargs): receiver = peer request_body = SendMessage(message=message, receiver_peer=receiver, quoted_message=quoted_message, random_id=random_id) request = Request(service=ServiceType.Messaging, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request # group def create_group(self, title, success_callback=None, failure_callback=None, **kwargs): request_body = CreateGroup(title) request = Request(service=ServiceType.Groups, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request def get_group_api_struct(self, group_id, client_user_id, success_callback=None, failure_callback=None, **kwargs): request_body = GetGroupApiStruct(group_id=group_id, client_user_id=client_user_id) request = Request(service=ServiceType.Groups, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request def invite_user(self, group_peer_id, group_peer_access_hash, user_peer_id, user_peer_access_hash, success_callback=None, failure_callback=None, **kwargs): group_peer = GroupPeer(peer_id=group_peer_id, access_hash=group_peer_access_hash) user_peer = UserPeer(peer_id=user_peer_id, access_hash=user_peer_access_hash) request_body = InviteUser(group_peer=group_peer, user_peer=user_peer) request = Request(service=ServiceType.Groups, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request # sequence-update def get_difference(self, seq, how_many, success_callback=None, failure_callback=None, **kwargs): request_body = GetDifference(seq=seq, how_many=how_many) request = Request(service=ServiceType.SequenceUpdate, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request # last_sequence def get_last_seq(self, success_callback=None, failure_callback=None, **kwargs): request_body = GetLastSequence() request = Request(service=ServiceType.SequenceUpdate, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request # file def get_file_download_url(self, file_id, user_id, file_type, file_version=1, is_server=False, is_resume_upload=False, success_callback=None, failure_callback=None, **kwargs): request_body = GetFileDownloadUrl(file_id, user_id, file_type, file_version, is_server, is_resume_upload) request = Request(service=ServiceType.Files, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request def get_file_upload_url(self, size, crc, file_type, is_server=False, success_callback=None, failure_callback=None, **kwargs): request_body = GetFileUploadUrl(size, crc, file_type, is_server) request = Request(service=ServiceType.Files, body=request_body) self.set_future(request.id, request_body, success_callback, failure_callback, **kwargs) self.send_request(request.get_json_str()) return request def download_file(self, file_id, user_id, file_type="file", success_callback=None, failure_callback=None, **kwargs): future = BaleFuture(request_id=None, response_body_module=None, response_body_class=None, success_callback=success_callback, failure_callback=failure_callback, **kwargs) def file_download_url_success(result, user_data): async def get_data(download_url): try: async with aiohttp.ClientSession() as session: async with session.get( download_url) as download_response: status = download_response.status if status == 200: byte_stream = await download_response.content.read( ) future.set_user_data(byte_stream=byte_stream) future.resolve(response=None) else: future.reject(response=None) except Exception as e: future.reject(response=None) url = result.body.url asyncio.ensure_future(get_data(url)) def file_download_url_failure(result, user_data): future.reject(response=result) self.get_file_download_url(file_id, user_id, file_type, success_callback=file_download_url_success, failure_callback=file_download_url_failure) def upload_file(self, file, file_type, success_callback=None, failure_callback=None, **kwargs): future = BaleFuture(request_id=None, response_body_module=None, response_body_class=None, success_callback=success_callback, failure_callback=failure_callback, **kwargs) buffer = get_file_buffer(file=file) if buffer is None: future.reject(response=None) return file_size = get_file_size(buffer) file_crc32 = get_file_crc32(buffer) def file_upload_url_success(result, user_data): file_id = result.body.file_id user_id = result.body.user_id url = result.body.url dup = result.body.dup data = buffer headers = {'filesize': str(file_size)} async def upload_data(): try: async with aiohttp.ClientSession() as session: async with session.put( url, data=data, headers=headers) as upload_response: status = upload_response.status if status == 200: future.set_user_data(file_id=file_id, user_id=user_id, url=url, dup=dup) future.resolve(response=None) else: future.reject(response=None) except Exception as e: future.reject(response=None) asyncio.ensure_future(upload_data()) def file_upload_url_failure(result, user_data): future.reject(response=result) self.get_file_upload_url(size=file_size, crc=file_crc32, file_type=file_type, success_callback=file_upload_url_success, failure_callback=file_upload_url_failure)