mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 07:18:57 +01:00
Cancellation support
This commit is contained in:
parent
7b6a65a55f
commit
949758aeb5
@ -725,6 +725,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#posmod-int-a-int-b-int" name="posmod">Positive modulo: posmod</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getBotCallbackAnswer.html" name="messages.getBotCallbackAnswer">Press an inline callback button and get a callback answer from the bot: messages.getBotCallbackAnswer</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#openbuffered-danog-madelineproto-localfile-danog-madelineproto-remoteurl-amp-bytestream-readablestream-stream-amp-cancellation-cancellation-null-callable" name="openBuffered">Provide a buffered reader for a file, URL or amp stream: openBuffered</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getstream-danog-madelineproto-eventhandler-message-danog-madelineproto-eventhandler-media-danog-madelineproto-localfile-danog-madelineproto-remoteurl-danog-madelineproto-botapifileid-amp-bytestream-readablestream-stream-amp-bytestream-readablestream" name="getStream">Provide a stream for a file, URL or amp stream: getStream</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getInlineBotResults.html" name="messages.getInlineBotResults">Query an inline bot: messages.getInlineBotResults</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/phone.setCallRating.html" name="phone.setCallRating">Rate a call, returns info about the rating message sent to the official VoIP bot: phone.setCallRating</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.rateTranscribedAudio.html" name="messages.rateTranscribedAudio">Rate transcribed voice message: messages.rateTranscribedAudio</a>
|
||||
@ -823,13 +824,13 @@ Want to add your own open-source project to this list? [Click here!](https://doc
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.acceptAuthorization.html" name="account.acceptAuthorization">Sends a Telegram Passport authorization form, effectively sharing data with the service: account.acceptAuthorization</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.setTyping.html" name="messages.setTyping">Sends a current user typing event (see SendMessageAction for all event types) to a conversation partner or group: messages.setTyping</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/bots.sendCustomRequest.html" name="bots.sendCustomRequest">Sends a custom request; for bots only: bots.sendCustomRequest</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#senddocument-int-string-peer-danog-madelineproto-eventhandler-message-danog-madelineproto-eventhandler-media-localfile-remoteurl-botapifileid-amp-bytestream-readablestream-file-danog-madelineproto-eventhandler-message-danog-madelineproto-eventhandler-media-localfile-remoteurl-botapifileid-amp-bytestream-readablestream-null-thumb-null-string-caption-parsemode-parsemode-danog-madelineproto-parsemode-text-callable-callback-null-string-filename-null-string-mimetype-null-int-ttl-null-bool-spoiler-false-int-null-replytomsgid-null-int-null-topmsgid-null-array-null-replymarkup-null-int-null-sendas-null-int-null-scheduledate-null-bool-silent-false-bool-noforwards-false-bool-background-false-bool-cleardraft-false-bool-updatestickersetsorder-false-danog-madelineproto-eventhandler-message" name="sendDocument">Sends a document: sendDocument</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#senddocument-int-string-peer-danog-madelineproto-eventhandler-message-danog-madelineproto-eventhandler-media-localfile-remoteurl-botapifileid-amp-bytestream-readablestream-file-danog-madelineproto-eventhandler-message-danog-madelineproto-eventhandler-media-localfile-remoteurl-botapifileid-amp-bytestream-readablestream-null-thumb-null-string-caption-parsemode-parsemode-danog-madelineproto-parsemode-text-callable-callback-null-string-filename-null-string-mimetype-null-int-ttl-null-bool-spoiler-false-int-null-replytomsgid-null-int-null-topmsgid-null-array-null-replymarkup-null-int-null-sendas-null-int-null-scheduledate-null-bool-silent-false-bool-noforwards-false-bool-background-false-bool-cleardraft-false-bool-updatestickersetsorder-false-amp-cancellation-cancellation-null-danog-madelineproto-eventhandler-message" name="sendDocument">Sends a document: sendDocument</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#broadcastmessages-array-messages-danog-madelineproto-broadcast-filter-filter-null-bool-pin-false-int" name="broadcastMessages">Sends a list of messages to all peers (users, chats, channels) of the bot: broadcastMessages</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.sendMessage.html" name="messages.sendMessage">Sends a message to a chat: messages.sendMessage</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#sendmessagetoadmins-string-message-parsemode-parsemode-danog-madelineproto-parsemode-text-array-null-replymarkup-null-int-null-scheduledate-null-bool-silent-false-bool-noforwards-false-bool-background-false-bool-cleardraft-false-bool-nowebpage-false-list-danog-madelineproto-eventhandler-message" name="sendMessageToAdmins">Sends a message to all report peers (admins of the bot): sendMessageToAdmins</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.sendEncryptedFile.html" name="messages.sendEncryptedFile">Sends a message with a file attachment to a secret chat: messages.sendEncryptedFile</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#sendmessage-int-string-peer-string-message-parsemode-parsemode-danog-madelineproto-parsemode-text-int-null-replytomsgid-null-int-null-topmsgid-null-array-null-replymarkup-null-int-null-sendas-null-int-null-scheduledate-null-bool-silent-false-bool-noforwards-false-bool-background-false-bool-cleardraft-false-bool-nowebpage-false-bool-updatestickersetsorder-false-danog-madelineproto-eventhandler-message" name="sendMessage">Sends a message: sendMessage</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#sendphoto-int-string-peer-danog-madelineproto-eventhandler-message-danog-madelineproto-eventhandler-media-localfile-remoteurl-botapifileid-amp-bytestream-readablestream-file-string-caption-parsemode-parsemode-danog-madelineproto-parsemode-text-callable-callback-null-string-filename-null-int-ttl-null-bool-spoiler-false-int-null-replytomsgid-null-int-null-topmsgid-null-array-null-replymarkup-null-int-null-sendas-null-int-null-scheduledate-null-bool-silent-false-bool-noforwards-false-bool-background-false-bool-cleardraft-false-bool-updatestickersetsorder-false-danog-madelineproto-eventhandler-message" name="sendPhoto">Sends a photo: sendPhoto</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#sendphoto-int-string-peer-danog-madelineproto-eventhandler-message-danog-madelineproto-eventhandler-media-localfile-remoteurl-botapifileid-amp-bytestream-readablestream-file-string-caption-parsemode-parsemode-danog-madelineproto-parsemode-text-callable-callback-null-string-filename-null-int-ttl-null-bool-spoiler-false-int-null-replytomsgid-null-int-null-topmsgid-null-array-null-replymarkup-null-int-null-sendas-null-int-null-scheduledate-null-bool-silent-false-bool-noforwards-false-bool-background-false-bool-cleardraft-false-bool-updatestickersetsorder-false-amp-cancellation-cancellation-null-danog-madelineproto-eventhandler-message" name="sendPhoto">Sends a photo: sendPhoto</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.sendEncryptedService.html" name="messages.sendEncryptedService">Sends a service message to a secret chat: messages.sendEncryptedService</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.sendEncrypted.html" name="messages.sendEncrypted">Sends a text message to a secret chat: messages.sendEncrypted</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#sendcustomevent-mixed-payload-void" name="sendCustomEvent">Sends an updateCustomEvent update to the event handler: sendCustomEvent</a>
|
||||
@ -903,7 +904,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadfromurl-string-filecallbackinterface-url-int-size-0-string-filename-callable-cb-null-bool-encrypted-false-array-inputfile-constructor" name="uploadFromUrl">Upload file from URL: uploadFromUrl</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadfromcallable-callable-callable-int-size-0-string-mime-application-octet-stream-string-filename-callable-cb-null-bool-seekable-true-bool-encrypted-false-array-inputfile-constructor" name="uploadFromCallable">Upload file from callable: uploadFromCallable</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadfromstream-mixed-stream-int-size-0-string-mime-application-octet-stream-string-filename-callable-cb-null-bool-encrypted-false-array-inputfile-constructor" name="uploadFromStream">Upload file from stream: uploadFromStream</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadencrypted-filecallbackinterface-string-array-file-string-filename-callable-cb-null-array-inputfile-constructor" name="uploadEncrypted">Upload file to secret chat: uploadEncrypted</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadencrypted-filecallbackinterface-localfile-remoteurl-botapifileid-string-array-resource-file-string-filename-callable-cb-null-array-inputfile-constructor" name="uploadEncrypted">Upload file to secret chat: uploadEncrypted</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#upload-filecallbackinterface-localfile-remoteurl-botapifileid-string-array-resource-file-string-filename-callable-cb-null-bool-encrypted-false-array-inputfile-constructor" name="upload">Upload file: upload</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.uploadRingtone.html" name="account.uploadRingtone">Upload notification sound, use account.saveRingtone to convert it and add it to the list of saved notification sounds: account.uploadRingtone</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.uploadTheme.html" name="account.uploadTheme">Upload theme: account.uploadTheme</a>
|
||||
|
2
docs
2
docs
@ -1 +1 @@
|
||||
Subproject commit 5da30efc5233a9ef6e6804dd48cdd89170e56209
|
||||
Subproject commit 1cec0caca9f9642ee120c87f0ad378da35077925
|
@ -17,6 +17,7 @@
|
||||
namespace danog\MadelineProto\EventHandler;
|
||||
|
||||
use Amp\ByteStream\ReadableStream;
|
||||
use Amp\Cancellation;
|
||||
use danog\MadelineProto\Ipc\IpcCapable;
|
||||
use danog\MadelineProto\MTProto;
|
||||
use danog\MadelineProto\TL\Types\Bytes;
|
||||
@ -138,9 +139,9 @@ abstract class Media extends IpcCapable implements JsonSerializable
|
||||
*
|
||||
* @param (callable(float, float, float): void)|null $cb Progress callback
|
||||
*/
|
||||
public function getStream(?callable $cb = null, int $offset = 0, int $end = -1): ReadableStream
|
||||
public function getStream(?callable $cb = null, int $offset = 0, int $end = -1, ?Cancellation $cancellation = null): ReadableStream
|
||||
{
|
||||
return $this->getClient()->downloadToReturnedStream($this, $cb, $offset, $end);
|
||||
return $this->getClient()->downloadToReturnedStream($this, $cb, $offset, $end, $cancellation);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,10 +150,10 @@ abstract class Media extends IpcCapable implements JsonSerializable
|
||||
* @param string $dir Directory where to download the file
|
||||
* @param (callable(float, float, float): void)|null $cb Progress callback
|
||||
*/
|
||||
public function downloadToDir(?string $dir = null, ?callable $cb = null): string
|
||||
public function downloadToDir(?string $dir = null, ?callable $cb = null, ?Cancellation $cancellation = null): string
|
||||
{
|
||||
$dir ??= \getcwd();
|
||||
return $this->getClient()->downloadToDir($this, $dir, $cb);
|
||||
return $this->getClient()->downloadToDir($this, $dir, $cb, $cancellation);
|
||||
}
|
||||
/**
|
||||
* Download the media to file.
|
||||
@ -160,9 +161,9 @@ abstract class Media extends IpcCapable implements JsonSerializable
|
||||
* @param string $file Downloaded file path
|
||||
* @param (callable(float, float, float): void)|null $cb Progress callback
|
||||
*/
|
||||
public function downloadToFile(string $file, ?callable $cb = null): string
|
||||
public function downloadToFile(string $file, ?callable $cb = null, ?Cancellation $cancellation = null): string
|
||||
{
|
||||
return $this->getClient()->downloadToFile($this, $file, $cb);
|
||||
return $this->getClient()->downloadToFile($this, $file, $cb, $cancellation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1644,11 +1644,13 @@ abstract class InternalDoc
|
||||
* @param boolean $background Send this message as background message
|
||||
* @param boolean $clearDraft Clears the draft field
|
||||
* @param boolean $updateStickersetsOrder Whether to move used stickersets to top
|
||||
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
|
||||
* @param Cancellation $cancellation Cancellation.
|
||||
*
|
||||
*/
|
||||
public function sendDocument(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream|null $thumb = null, string $caption = '', \danog\MadelineProto\ParseMode $parseMode = \danog\MadelineProto\ParseMode::TEXT, ?callable $callback = null, ?string $fileName = null, ?string $mimeType = null, ?int $ttl = null, bool $spoiler = false, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $updateStickersetsOrder = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
|
||||
public function sendDocument(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream|null $thumb, string $caption, \danog\MadelineProto\ParseMode $parseMode, ?callable $callback, ?string $fileName, ?string $mimeType, ?int $ttl, bool $spoiler, ?int $replyToMsgId, ?int $topMsgId, ?array $replyMarkup, string|int|null $sendAs, ?int $scheduleDate, bool $silent, bool $noForwards, bool $background, bool $clearDraft, bool $updateStickersetsOrder, bool $forceResend, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
|
||||
{
|
||||
return $this->wrapper->getAPI()->sendDocument($peer, $file, $thumb, $caption, $parseMode, $callback, $fileName, $mimeType, $ttl, $spoiler, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $updateStickersetsOrder, $cancellation);
|
||||
return $this->wrapper->getAPI()->sendDocument($peer, $file, $thumb, $caption, $parseMode, $callback, $fileName, $mimeType, $ttl, $spoiler, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $updateStickersetsOrder, $forceResend, $cancellation);
|
||||
}
|
||||
/**
|
||||
* Sends a message.
|
||||
@ -1709,11 +1711,13 @@ abstract class InternalDoc
|
||||
* @param boolean $background Send this message as background message
|
||||
* @param boolean $clearDraft Clears the draft field
|
||||
* @param boolean $updateStickersetsOrder Whether to move used stickersets to top
|
||||
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
|
||||
* @param Cancellation $cancellation Cancellation.
|
||||
*
|
||||
*/
|
||||
public function sendPhoto(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, string $caption = '', \danog\MadelineProto\ParseMode $parseMode = \danog\MadelineProto\ParseMode::TEXT, ?callable $callback = null, ?string $fileName = null, ?int $ttl = null, bool $spoiler = false, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $updateStickersetsOrder = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
|
||||
public function sendPhoto(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, string $caption = '', \danog\MadelineProto\ParseMode $parseMode = \danog\MadelineProto\ParseMode::TEXT, ?callable $callback = null, ?string $fileName = null, ?int $ttl = null, bool $spoiler = false, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $updateStickersetsOrder = false, bool $forceResend = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
|
||||
{
|
||||
return $this->wrapper->getAPI()->sendPhoto($peer, $file, $caption, $parseMode, $callback, $fileName, $ttl, $spoiler, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $updateStickersetsOrder, $cancellation);
|
||||
return $this->wrapper->getAPI()->sendPhoto($peer, $file, $caption, $parseMode, $callback, $fileName, $ttl, $spoiler, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $updateStickersetsOrder, $forceResend, $cancellation);
|
||||
}
|
||||
/**
|
||||
* Set NOOP update handler, ignoring all updates.
|
||||
|
@ -260,15 +260,16 @@ final class Client extends ClientAbstract
|
||||
* @param string|FileCallbackInterface $dir Directory where to download the file
|
||||
* @param callable $cb Callback
|
||||
*/
|
||||
public function downloadToDir(mixed $messageMedia, string|FileCallbackInterface $dir, ?callable $cb = null)
|
||||
public function downloadToDir(mixed $messageMedia, string|FileCallbackInterface $dir, ?callable $cb = null, ?Cancellation $cancellation = null)
|
||||
{
|
||||
if (\is_object($dir) && $dir instanceof FileCallbackInterface) {
|
||||
$cb = $dir;
|
||||
$dir = $dir->getFile();
|
||||
}
|
||||
$params = [$messageMedia, $dir, &$cb];
|
||||
$params = [$messageMedia, $dir, &$cb, &$cancellation];
|
||||
$wrapper = Wrapper::create($params, $this->session, $this->logger);
|
||||
$wrapper->wrap($cb, false);
|
||||
$wrapper->wrap($cancellation, false);
|
||||
return $this->__call('downloadToDir', $wrapper);
|
||||
}
|
||||
/**
|
||||
@ -278,15 +279,16 @@ final class Client extends ClientAbstract
|
||||
* @param string|FileCallbackInterface $file Downloaded file path
|
||||
* @param callable $cb Callback
|
||||
*/
|
||||
public function downloadToFile(mixed $messageMedia, string|FileCallbackInterface $file, ?callable $cb = null)
|
||||
public function downloadToFile(mixed $messageMedia, string|FileCallbackInterface $file, ?callable $cb = null, ?Cancellation $cancellation = null)
|
||||
{
|
||||
if (\is_object($file) && $file instanceof FileCallbackInterface) {
|
||||
$cb = $file;
|
||||
$file = $file->getFile();
|
||||
}
|
||||
$params = [$messageMedia, $file, &$cb];
|
||||
$params = [$messageMedia, $file, &$cb, &$cancellation];
|
||||
$wrapper = Wrapper::create($params, $this->session, $this->logger);
|
||||
$wrapper->wrap($cb, false);
|
||||
$wrapper->wrap($cancellation, false);
|
||||
return $this->__call('downloadToFile', $wrapper);
|
||||
}
|
||||
/**
|
||||
@ -303,17 +305,18 @@ final class Client extends ClientAbstract
|
||||
* @param int $end Offset where to stop downloading (inclusive)
|
||||
* @param int $part_size Size of each chunk
|
||||
*/
|
||||
public function downloadToCallable(mixed $messageMedia, callable $callable, ?callable $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, ?int $part_size = null)
|
||||
public function downloadToCallable(mixed $messageMedia, callable $callable, ?callable $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, ?int $part_size = null, ?Cancellation $cancellation = null)
|
||||
{
|
||||
$messageMedia = ($this->getDownloadInfo($messageMedia));
|
||||
if (\is_object($callable) && $callable instanceof FileCallbackInterface) {
|
||||
$cb = $callable;
|
||||
$callable = $callable->getFile();
|
||||
}
|
||||
$params = [$messageMedia, &$callable, &$cb, $seekable, $offset, $end, $part_size, ];
|
||||
$params = [$messageMedia, &$callable, &$cb, $seekable, $offset, $end, $part_size, &$cancellation];
|
||||
$wrapper = Wrapper::create($params, $this->session, $this->logger);
|
||||
$wrapper->wrap($callable, false);
|
||||
$wrapper->wrap($cb, false);
|
||||
$wrapper->wrap($cancellation, false);
|
||||
return $this->__call('downloadToCallable', $wrapper);
|
||||
}
|
||||
/**
|
||||
|
@ -23,6 +23,7 @@ namespace danog\MadelineProto;
|
||||
use Amp\ByteStream\ReadableStream;
|
||||
use Amp\Cache\Cache;
|
||||
use Amp\Cache\LocalCache;
|
||||
use Amp\Cancellation;
|
||||
use Amp\DeferredFuture;
|
||||
use Amp\Dns\DnsResolver;
|
||||
use Amp\Future;
|
||||
@ -713,7 +714,7 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
/**
|
||||
* Provide a stream for a file, URL or amp stream.
|
||||
*/
|
||||
public function getStream(Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $stream): ReadableStream
|
||||
public function getStream(Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $stream, ?Cancellation $cancellation = null): ReadableStream
|
||||
{
|
||||
if ($stream instanceof LocalFile) {
|
||||
return openFile($stream->file, 'r');
|
||||
@ -723,6 +724,7 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
$request->setTransferTimeout(INF);
|
||||
return $this->getHTTPClient()->request(
|
||||
$request,
|
||||
$cancellation
|
||||
)->getBody();
|
||||
}
|
||||
if ($stream instanceof Message) {
|
||||
@ -732,10 +734,10 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
}
|
||||
}
|
||||
if ($stream instanceof Media) {
|
||||
return $stream->getStream();
|
||||
return $stream->getStream(cancellation: $cancellation);
|
||||
}
|
||||
if ($stream instanceof BotApiFileId) {
|
||||
return $this->downloadToReturnedStream($stream);
|
||||
return $this->downloadToReturnedStream($stream, cancellation: $cancellation);
|
||||
}
|
||||
return $stream;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\MTProtoTools;
|
||||
|
||||
use Amp\Cancellation;
|
||||
use Amp\DeferredFuture;
|
||||
use Amp\Future;
|
||||
use Amp\Http\Client\Request;
|
||||
@ -933,14 +934,14 @@ trait Files
|
||||
*
|
||||
* @return non-empty-string Downloaded file name
|
||||
*/
|
||||
public function downloadToDir(mixed $messageMedia, string|FileCallbackInterface $dir, ?callable $cb = null): string
|
||||
public function downloadToDir(mixed $messageMedia, string|FileCallbackInterface $dir, ?callable $cb = null, ?Cancellation $cancellation = null): string
|
||||
{
|
||||
if (\is_object($dir) && $dir instanceof FileCallbackInterface) {
|
||||
$cb = $dir;
|
||||
$dir = $dir->getFile();
|
||||
}
|
||||
$messageMedia = ($this->getDownloadInfo($messageMedia));
|
||||
return $this->downloadToFile($messageMedia, $dir.'/'.$messageMedia['name'].$messageMedia['ext'], $cb);
|
||||
return $this->downloadToFile($messageMedia, $dir.'/'.$messageMedia['name'].$messageMedia['ext'], $cb, $cancellation);
|
||||
}
|
||||
/**
|
||||
* Download file.
|
||||
@ -951,7 +952,7 @@ trait Files
|
||||
*
|
||||
* @return non-empty-string Downloaded file name
|
||||
*/
|
||||
public function downloadToFile(mixed $messageMedia, string|FileCallbackInterface $file, ?callable $cb = null): string
|
||||
public function downloadToFile(mixed $messageMedia, string|FileCallbackInterface $file, ?callable $cb = null, ?Cancellation $cancellation = null): string
|
||||
{
|
||||
if (\is_object($file) && $file instanceof FileCallbackInterface) {
|
||||
$cb = $file;
|
||||
@ -969,7 +970,7 @@ trait Files
|
||||
$this->logger->logger('Waiting for lock of file to download...');
|
||||
$unlock = Tools::flock("$file.lock", LOCK_EX);
|
||||
$this->logger->logger('Got lock of file to download');
|
||||
async($this->downloadToStream(...), $messageMedia, $stream, $cb, $size, -1)->finally(function () use ($stream, $unlock, $file): void {
|
||||
async($this->downloadToStream(...), $messageMedia, $stream, $cb, $size, -1, $cancellation)->finally(function () use ($stream, $unlock, $file): void {
|
||||
$stream->close();
|
||||
$unlock();
|
||||
try {
|
||||
@ -992,7 +993,7 @@ trait Files
|
||||
* @param int $end Offset where to stop downloading (inclusive)
|
||||
* @param int $part_size Size of each chunk
|
||||
*/
|
||||
public function downloadToCallable(mixed $messageMedia, callable $callable, ?callable $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, ?int $part_size = null): void
|
||||
public function downloadToCallable(mixed $messageMedia, callable $callable, ?callable $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, ?int $part_size = null, ?Cancellation $cancellation = null): void
|
||||
{
|
||||
$messageMedia = ($this->getDownloadInfo($messageMedia));
|
||||
if (\is_object($callable) && $callable instanceof FileCallbackInterface) {
|
||||
@ -1074,7 +1075,7 @@ trait Files
|
||||
$params[0]['previous_promise'] = true;
|
||||
$start = \microtime(true);
|
||||
$old_dc = null;
|
||||
$size = $this->downloadPart($messageMedia, $cdn, $datacenter, $old_dc, $ige, $cb, $initParam = \array_shift($params), $callable, $seekable);
|
||||
$size = $this->downloadPart($messageMedia, $cdn, $datacenter, $old_dc, $ige, $cb, $initParam = \array_shift($params), $callable, $seekable, $cancellation);
|
||||
if ($initParam['part_end_at'] - $initParam['part_start_at'] !== $size) {
|
||||
// Premature end for undefined length files
|
||||
$origCb(100, 0, 0);
|
||||
@ -1086,7 +1087,7 @@ trait Files
|
||||
$promises = [];
|
||||
foreach ($params as $key => $param) {
|
||||
$param['previous_promise'] = $previous_promise;
|
||||
$previous_promise = async($this->downloadPart(...), $messageMedia, $cdn, $datacenter, $old_dc, $ige, $cb, $param, $callable, $seekable);
|
||||
$previous_promise = async($this->downloadPart(...), $messageMedia, $cdn, $datacenter, $old_dc, $ige, $cb, $param, $callable, $seekable, $cancellation);
|
||||
$previous_promise->map(static function (int $res) use (&$size): void {
|
||||
$size += $res;
|
||||
});
|
||||
@ -1137,7 +1138,7 @@ trait Files
|
||||
* @param boolean $seekable Whether the download file is seekable
|
||||
* @param boolean $postpone Whether to postpone method call
|
||||
*/
|
||||
private function downloadPart(array &$messageMedia, bool &$cdn, int &$datacenter, ?int &$old_dc, ?IGE &$ige, callable $cb, array $offset, callable $callable, bool $seekable, bool $postpone = false): int
|
||||
private function downloadPart(array &$messageMedia, bool &$cdn, int &$datacenter, ?int &$old_dc, ?IGE &$ige, callable $cb, array $offset, callable $callable, bool $seekable, ?Cancellation $cancellation): int
|
||||
{
|
||||
do {
|
||||
if (!$cdn) {
|
||||
@ -1151,7 +1152,7 @@ trait Files
|
||||
$res = $this->methodCallAsyncRead(
|
||||
$cdn ? 'upload.getCdnFile' : 'upload.getFile',
|
||||
$basic_param + $offset,
|
||||
['heavy' => true, 'FloodWaitLimit' => 0, 'datacenter' => &$datacenter, 'postpone' => $postpone]
|
||||
['heavy' => true, 'FloodWaitLimit' => 0, 'datacenter' => &$datacenter, 'cancellation' => $cancellation]
|
||||
);
|
||||
break;
|
||||
} catch (FloodWaitError $e) {
|
||||
@ -1186,7 +1187,7 @@ trait Files
|
||||
$this->config['expires'] = 0;
|
||||
$this->getConfig();
|
||||
try {
|
||||
$this->addCdnHashes($messageMedia['file_token'], $this->methodCallAsyncRead('upload.reuploadCdnFile', ['file_token' => $messageMedia['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc]));
|
||||
$this->addCdnHashes($messageMedia['file_token'], $this->methodCallAsyncRead('upload.reuploadCdnFile', ['file_token' => $messageMedia['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc, 'cancellation' => $cancellation]));
|
||||
} catch (RPCErrorException $e) {
|
||||
switch ($e->rpc) {
|
||||
case 'FILE_TOKEN_INVALID':
|
||||
@ -1213,7 +1214,7 @@ trait Files
|
||||
if (isset($messageMedia['cdn_key'])) {
|
||||
$ivec = \substr($messageMedia['cdn_iv'], 0, 12).\pack('N', $offset['offset'] >> 4);
|
||||
$res['bytes'] = Crypt::ctrEncrypt($res['bytes'], $messageMedia['cdn_key'], $ivec);
|
||||
$this->checkCdnHash($messageMedia['file_token'], $offset['offset'], $res['bytes'], $old_dc);
|
||||
$this->checkCdnHash($messageMedia['file_token'], $offset['offset'], $res['bytes'], $old_dc, $cancellation);
|
||||
}
|
||||
if (isset($messageMedia['key'])) {
|
||||
$res['bytes'] = $ige->decrypt($res['bytes']);
|
||||
@ -1244,11 +1245,11 @@ trait Files
|
||||
$this->cdn_hashes[$file][$hash['offset']] = ['limit' => $hash['limit'], 'hash' => (string) $hash['hash']];
|
||||
}
|
||||
}
|
||||
private function checkCdnHash(string $file, int $offset, string $data, int &$datacenter): void
|
||||
private function checkCdnHash(string $file, int $offset, string $data, int &$datacenter, ?Cancellation $cancellation): void
|
||||
{
|
||||
while (\strlen($data)) {
|
||||
if (!isset($this->cdn_hashes[$file][$offset])) {
|
||||
$this->addCdnHashes($file, $this->methodCallAsyncRead('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => $datacenter]));
|
||||
$this->addCdnHashes($file, $this->methodCallAsyncRead('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => $datacenter, 'cancellation' => $cancellation]));
|
||||
}
|
||||
if (!isset($this->cdn_hashes[$file][$offset])) {
|
||||
throw new Exception('Could not fetch CDN hashes for offset '.$offset);
|
||||
|
@ -69,6 +69,8 @@ trait FilesAbstraction
|
||||
* @param boolean $background Send this message as background message
|
||||
* @param boolean $clearDraft Clears the draft field
|
||||
* @param boolean $updateStickersetsOrder Whether to move used stickersets to top
|
||||
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
|
||||
* @param Cancellation $cancellation Cancellation.
|
||||
*
|
||||
*/
|
||||
public function sendDocument(
|
||||
@ -92,6 +94,7 @@ trait FilesAbstraction
|
||||
bool $background = false,
|
||||
bool $clearDraft = false,
|
||||
bool $updateStickersetsOrder = false,
|
||||
bool $forceResend,
|
||||
?Cancellation $cancellation = null,
|
||||
): Message {
|
||||
if ($file instanceof Message) {
|
||||
@ -123,6 +126,7 @@ trait FilesAbstraction
|
||||
replyMarkup: $replyMarkup,
|
||||
scheduleDate: $scheduleDate,
|
||||
sendAs: $sendAs,
|
||||
forceResend: $forceResend,
|
||||
cancellation: $cancellation
|
||||
);
|
||||
}
|
||||
@ -146,6 +150,8 @@ trait FilesAbstraction
|
||||
* @param boolean $background Send this message as background message
|
||||
* @param boolean $clearDraft Clears the draft field
|
||||
* @param boolean $updateStickersetsOrder Whether to move used stickersets to top
|
||||
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
|
||||
* @param Cancellation $cancellation Cancellation.
|
||||
*
|
||||
*/
|
||||
public function sendPhoto(
|
||||
@ -167,6 +173,7 @@ trait FilesAbstraction
|
||||
bool $background = false,
|
||||
bool $clearDraft = false,
|
||||
bool $updateStickersetsOrder = false,
|
||||
bool $forceResend = false,
|
||||
?Cancellation $cancellation = null,
|
||||
): Message {
|
||||
if ($file instanceof Message) {
|
||||
@ -198,6 +205,7 @@ trait FilesAbstraction
|
||||
replyMarkup: $replyMarkup,
|
||||
scheduleDate: $scheduleDate,
|
||||
sendAs: $sendAs,
|
||||
forceResend: $forceResend,
|
||||
cancellation: $cancellation
|
||||
);
|
||||
}
|
||||
@ -230,7 +238,8 @@ trait FilesAbstraction
|
||||
bool $background,
|
||||
bool $clearDraft,
|
||||
bool $updateStickersetsOrder,
|
||||
?Cancellation $cancellation = null,
|
||||
bool $forceResend,
|
||||
?Cancellation $cancellation,
|
||||
): Message {
|
||||
$peer = $this->getId($peer);
|
||||
if ($file instanceof Media) {
|
||||
@ -253,6 +262,7 @@ trait FilesAbstraction
|
||||
if ($file instanceof $type
|
||||
&& ($fileName ?? $file->fileName) === $file->fileName
|
||||
&& !$file->protected
|
||||
&& !$forceResend
|
||||
) {
|
||||
// Re-use
|
||||
$reuseId = $file->botApiFileId;
|
||||
@ -261,6 +271,7 @@ trait FilesAbstraction
|
||||
&& $file->getTypeClass() === $type
|
||||
&& ($fileName ?? $file->fileName) === $file->fileName
|
||||
&& !$file->protected
|
||||
&& !$forceResend
|
||||
) {
|
||||
// Re-use
|
||||
$reuseId = $file->fileId;
|
||||
@ -299,7 +310,7 @@ trait FilesAbstraction
|
||||
if (!\extension_loaded('gd')) {
|
||||
throw Exception::extension('gd');
|
||||
}
|
||||
$file = buffer($this->getStream($file), $cancellation);
|
||||
$file = buffer($this->getStream($file, $cancellation), $cancellation);
|
||||
$img = \imagecreatefromstring($file);
|
||||
$width = \imagesx($img);
|
||||
$height = \imagesy($img);
|
||||
@ -326,7 +337,7 @@ trait FilesAbstraction
|
||||
unset($stream);
|
||||
$file = new ReadableBuffer($file);
|
||||
} elseif ($thumb !== null) {
|
||||
$thumb = buffer($this->getStream($thumb), $cancellation);
|
||||
$thumb = buffer($this->getStream($thumb, $cancellation), $cancellation);
|
||||
if (!\extension_loaded('gd')) {
|
||||
throw Exception::extension('gd');
|
||||
}
|
||||
@ -368,6 +379,7 @@ trait FilesAbstraction
|
||||
if ($file instanceof $type
|
||||
&& ($fileName ?? $file->fileName) === $file->fileName
|
||||
&& $file->encrypted
|
||||
&& !$forceResend
|
||||
) {
|
||||
// Reuse
|
||||
$file = $file->location;
|
||||
|
@ -23,6 +23,7 @@ use Amp\ByteStream\ReadableStream;
|
||||
use Amp\ByteStream\StreamException;
|
||||
use Amp\ByteStream\WritableResourceStream;
|
||||
use Amp\ByteStream\WritableStream;
|
||||
use Amp\Cancellation;
|
||||
use Amp\File\File;
|
||||
use Amp\File\Whence;
|
||||
use Amp\Http\HttpStatus;
|
||||
@ -82,7 +83,7 @@ trait FilesLogic
|
||||
* @param null|string $mime MIME type of file to download, required for bot API file IDs.
|
||||
* @param null|string $name Name of file to download, required for bot API file IDs.
|
||||
*/
|
||||
public function downloadToBrowser(array|string|FileCallbackInterface|Message $messageMedia, ?callable $cb = null, ?int $size = null, ?string $name = null, ?string $mime = null): void
|
||||
public function downloadToBrowser(array|string|FileCallbackInterface|Message $messageMedia, ?callable $cb = null, ?int $size = null, ?string $name = null, ?string $mime = null, ?Cancellation $cancellation = null): void
|
||||
{
|
||||
if (\is_object($messageMedia) && $messageMedia instanceof FileCallbackInterface) {
|
||||
$cb = $messageMedia;
|
||||
@ -128,7 +129,8 @@ trait FilesLogic
|
||||
\ob_end_flush();
|
||||
\ob_implicit_flush();
|
||||
}
|
||||
$this->downloadToStream($messageMedia, \fopen('php://output', 'w'), $cb, ...$result->getServeRange());
|
||||
[$start, $end] = $result->getServeRange();
|
||||
$this->downloadToStream($messageMedia, \fopen('php://output', 'w'), $cb, $start, $end, $cancellation);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -139,11 +141,11 @@ trait FilesLogic
|
||||
* @param int $offset Offset where to start downloading
|
||||
* @param int $end Offset where to end download
|
||||
*/
|
||||
public function downloadToReturnedStream(mixed $messageMedia, ?callable $cb = null, int $offset = 0, int $end = -1): ReadableStream
|
||||
public function downloadToReturnedStream(mixed $messageMedia, ?callable $cb = null, int $offset = 0, int $end = -1, ?Cancellation $cancellation = null): ReadableStream
|
||||
{
|
||||
$pipe = new Pipe(1024*1024);
|
||||
$sink = $pipe->getSink();
|
||||
async($this->downloadToStream(...), $messageMedia, $sink, $cb, $offset, $end)->finally($sink->close(...));
|
||||
async($this->downloadToStream(...), $messageMedia, $sink, $cb, $offset, $end, $cancellation)->finally($sink->close(...));
|
||||
return $pipe->getSource();
|
||||
}
|
||||
/**
|
||||
@ -155,7 +157,7 @@ trait FilesLogic
|
||||
* @param int $offset Offset where to start downloading
|
||||
* @param int $end Offset where to end download
|
||||
*/
|
||||
public function downloadToStream(mixed $messageMedia, mixed $stream, ?callable $cb = null, int $offset = 0, int $end = -1): void
|
||||
public function downloadToStream(mixed $messageMedia, mixed $stream, ?callable $cb = null, int $offset = 0, int $end = -1, ?Cancellation $cancellation = null): void
|
||||
{
|
||||
$messageMedia = $this->getDownloadInfo($messageMedia);
|
||||
if (\is_object($stream) && $stream instanceof FileCallbackInterface) {
|
||||
@ -193,7 +195,7 @@ trait FilesLogic
|
||||
}
|
||||
return \strlen($payload);
|
||||
};
|
||||
$this->downloadToCallable($messageMedia, $callable, $cb, $seekable, $offset, $end);
|
||||
$this->downloadToCallable($messageMedia, $callable, $cb, $seekable, $offset, $end, null, $cancellation);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -208,7 +210,7 @@ trait FilesLogic
|
||||
* @param null|string $name Name of file to download, required for bot API file IDs.
|
||||
* @param null|string $mime MIME type of file to download, required for bot API file IDs.
|
||||
*/
|
||||
public function downloadToResponse(array|string|FileCallbackInterface|Message $messageMedia, ServerRequest $request, ?callable $cb = null, ?int $size = null, ?string $mime = null, ?string $name = null): Response
|
||||
public function downloadToResponse(array|string|FileCallbackInterface|Message $messageMedia, ServerRequest $request, ?callable $cb = null, ?int $size = null, ?string $mime = null, ?string $name = null, ?Cancellation $cancellation = null): Response
|
||||
{
|
||||
if (\is_object($messageMedia) && $messageMedia instanceof FileCallbackInterface) {
|
||||
$cb = $messageMedia;
|
||||
@ -235,7 +237,8 @@ trait FilesLogic
|
||||
$body = null;
|
||||
if ($result->shouldServe()) {
|
||||
$pipe = new Pipe(1024 * 1024);
|
||||
EventLoop::queue($this->downloadToStream(...), $messageMedia, $pipe->getSink(), $cb, ...$result->getServeRange());
|
||||
[$start, $end] = $result->getServeRange();
|
||||
EventLoop::queue($this->downloadToStream(...), $messageMedia, $pipe->getSink(), $cb, $start, $end, $cancellation);
|
||||
$body = $pipe->getSource();
|
||||
} elseif (!\in_array($result->getCode(), [HttpStatus::OK, HttpStatus::PARTIAL_CONTENT], true)) {
|
||||
$body = $result->getCodeExplanation();
|
||||
|
Loading…
Reference in New Issue
Block a user