1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 05:58:58 +01:00

Fix upload callbacks in the send* methods, fix issue with plugins in a phar

This commit is contained in:
Daniil Gentili 2024-04-23 15:28:38 +02:00
parent e23043fded
commit e64c1c52eb
6 changed files with 62 additions and 30 deletions

View File

@ -4131,6 +4131,12 @@
<code><![CDATA[$media['file']]]></code> <code><![CDATA[$media['file']]]></code>
</PossiblyInvalidArgument> </PossiblyInvalidArgument>
<PossiblyNullArgument> <PossiblyNullArgument>
<code><![CDATA[$size]]></code>
<code><![CDATA[$size]]></code>
<code><![CDATA[$size]]></code>
<code><![CDATA[$size]]></code>
<code><![CDATA[$size]]></code>
<code><![CDATA[$size]]></code>
<code><![CDATA[$stderr]]></code> <code><![CDATA[$stderr]]></code>
<code><![CDATA[$stderr]]></code> <code><![CDATA[$stderr]]></code>
<code><![CDATA[$stderr]]></code> <code><![CDATA[$stderr]]></code>

View File

@ -51,7 +51,7 @@ final class API extends AbstractAPI
* *
* @var string * @var string
*/ */
public const RELEASE = '8.0.0-beta202'; public const RELEASE = '8.0.0-beta203';
/** /**
* We're not logged in. * We're not logged in.
* *

View File

@ -1081,9 +1081,9 @@ abstract class InternalDoc
/** /**
* Provide a stream for a file, URL or amp stream. * Provide a stream for a file, URL or amp stream.
*/ */
final public function getStream(\danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $stream, ?\Amp\Cancellation $cancellation = null): \Amp\ByteStream\ReadableStream final public function getStream(\danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $stream, ?\Amp\Cancellation $cancellation = null, ?int &$size = null): \Amp\ByteStream\ReadableStream
{ {
return $this->wrapper->getAPI()->getStream($stream, $cancellation); return $this->wrapper->getAPI()->getStream($stream, $cancellation, $size);
} }
/** /**
* Obtains a pipe that can be used to upload a file from a stream. * Obtains a pipe that can be used to upload a file from a stream.

View File

@ -24,6 +24,8 @@ use Amp\ByteStream\Pipe;
use Amp\ByteStream\ReadableBuffer; use Amp\ByteStream\ReadableBuffer;
use Amp\ByteStream\ReadableStream; use Amp\ByteStream\ReadableStream;
use Amp\Cancellation; use Amp\Cancellation;
use Amp\Http\Client\HttpClient;
use Amp\Http\Client\HttpClientBuilder;
use Amp\Http\Client\Request; use Amp\Http\Client\Request;
use Amp\Process\Process; use Amp\Process\Process;
use AssertionError; use AssertionError;
@ -53,6 +55,7 @@ use Webmozart\Assert\Assert;
use function Amp\async; use function Amp\async;
use function Amp\ByteStream\buffer; use function Amp\ByteStream\buffer;
use function Amp\File\getSize;
use function Amp\File\openFile; use function Amp\File\openFile;
use function Amp\Future\await; use function Amp\Future\await;
@ -65,21 +68,31 @@ use function Amp\Future\await;
*/ */
trait FilesAbstraction trait FilesAbstraction
{ {
private static ?HttpClient $client;
/** /**
* Provide a stream for a file, URL or amp stream. * Provide a stream for a file, URL or amp stream.
*/ */
public function getStream(Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $stream, ?Cancellation $cancellation = null): ReadableStream public function getStream(Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $stream, ?Cancellation $cancellation = null, ?int &$size = null): ReadableStream
{ {
if ($stream instanceof LocalFile) { if ($stream instanceof LocalFile) {
$size = getSize($stream->file);
return openFile($stream->file, 'r'); return openFile($stream->file, 'r');
} }
if ($stream instanceof RemoteUrl) { if ($stream instanceof RemoteUrl) {
self::$client ??= HttpClientBuilder::buildDefault();
$request = new Request($stream->url); $request = new Request($stream->url);
$request->setTransferTimeout(INF); $request->setTransferTimeout(INF);
return $this->getHTTPClient()->request( $request->setBodySizeLimit(512 * 1024 * 8000);
$response = self::$client->request(
$request, $request,
$cancellation $cancellation
)->getBody(); );
if (($status = $response->getStatus()) !== 200) {
throw new Exception("Wrong status code: {$status} ".$response->getReason());
}
$size = (int) ($response->getHeader('content-length') ?? $size);
$stream = $response->getBody();
return $stream;
} }
if ($stream instanceof Message) { if ($stream instanceof Message) {
$stream = $stream->media; $stream = $stream->media;
@ -88,9 +101,11 @@ trait FilesAbstraction
} }
} }
if ($stream instanceof Media) { if ($stream instanceof Media) {
$size = $stream->size;
return $stream->getStream(cancellation: $cancellation); return $stream->getStream(cancellation: $cancellation);
} }
if ($stream instanceof BotApiFileId) { if ($stream instanceof BotApiFileId) {
$size = $stream->size;
return $this->downloadToReturnedStream($stream, cancellation: $cancellation); return $this->downloadToReturnedStream($stream, cancellation: $cancellation);
} }
return $stream; return $stream;
@ -1127,9 +1142,18 @@ trait FilesAbstraction
private function extractMime(bool $secret, Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream &$file, ?string $fileName, ?callable $callback, ?Cancellation $cancellation): string private function extractMime(bool $secret, Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream &$file, ?string $fileName, ?callable $callback, ?Cancellation $cancellation): string
{ {
$file = $this->getStream($file, $cancellation); $size = 0;
$file = $this->getStream($file, $cancellation, $size);
$p = new Pipe(1024*1024); $p = new Pipe(1024*1024);
$fileFuture = async(fn () => $this->upload(new StreamDuplicator($file, $p->getSink()), $fileName ?? '', $callback, $secret, $cancellation)); $fileFuture = async(fn () => $this->uploadFromStream(
new StreamDuplicator($file, $p->getSink()),
$size,
'application/octet-stream',
$fileName ?? '',
$callback,
$secret,
$cancellation
));
$buff = ''; $buff = '';
while (\strlen($buff) < 1024*1024 && null !== $chunk = $p->getSource()->read($cancellation)) { while (\strlen($buff) < 1024*1024 && null !== $chunk = $p->getSource()->read($cancellation)) {
@ -1163,7 +1187,8 @@ trait FilesAbstraction
return; return;
} }
$file = $this->getStream($file, $cancellation); $size = 0;
$file = $this->getStream($file, $cancellation, $size);
$process = Process::start('ffmpeg -i pipe: -f image2pipe -', cancellation: $cancellation); $process = Process::start('ffmpeg -i pipe: -f image2pipe -', cancellation: $cancellation);
$stdin = $process->getStdin(); $stdin = $process->getStdin();
$stdout = $process->getStdout(); $stdout = $process->getStdout();
@ -1189,7 +1214,15 @@ trait FilesAbstraction
unset($p); unset($p);
} }
$fileFuture = async(fn () => $this->upload(new StreamDuplicator($file, ...$streams), $fileName ?? '', $callback, $secret, $cancellation)); $fileFuture = async(fn () => $this->uploadFromStream(
new StreamDuplicator($file, ...$streams),
$size,
'application/octet-stream',
$fileName ?? '',
$callback,
$secret,
$cancellation
));
[$stdout, $stderr] = await($f); [$stdout, $stderr] = await($f);
$process->join($cancellation); $process->join($cancellation);
@ -1236,7 +1269,8 @@ trait FilesAbstraction
return; return;
} }
$file = $this->getStream($file, $cancellation); $size = 0;
$file = $this->getStream($file, $cancellation, $size);
$ffmpeg = 'ffmpeg -i pipe: -ss '.$thumbSeek.' -frames:v 1 -f image2pipe -'; $ffmpeg = 'ffmpeg -i pipe: -ss '.$thumbSeek.' -frames:v 1 -f image2pipe -';
$process = Process::start($ffmpeg, cancellation: $cancellation); $process = Process::start($ffmpeg, cancellation: $cancellation);
$stdin = $process->getStdin(); $stdin = $process->getStdin();
@ -1261,7 +1295,15 @@ trait FilesAbstraction
unset($p); unset($p);
} }
$fileFuture = async(fn () => $this->upload(new StreamDuplicator($file, ...$streams), $fileName ?? '', $callback, $secret, $cancellation)); $fileFuture = async(fn () => $this->uploadFromStream(
new StreamDuplicator($file, ...$streams),
$size,
'application/octet-stream',
$fileName ?? '',
$callback,
$secret,
$cancellation
));
[$stdout, $stderr] = await($f); [$stdout, $stderr] = await($f);
if ($stdout !== '') { if ($stdout !== '') {

View File

@ -66,7 +66,6 @@ use const PHP_SAPI;
use const STR_PAD_RIGHT; use const STR_PAD_RIGHT;
use function Amp\File\openFile; use function Amp\File\openFile;
use function Amp\File\read;
use function unpack; use function unpack;
/** /**
@ -712,7 +711,7 @@ abstract class Tools extends AsyncTools
} }
$plugin = is_subclass_of($class, PluginEventHandler::class); $plugin = is_subclass_of($class, PluginEventHandler::class);
$file = (new ReflectionClass($class))->getFileName(); $file = (new ReflectionClass($class))->getFileName();
$code = read($file); $code = file_get_contents($file);
$code = (new ParserFactory)->createForNewestSupportedVersion()->parse($code); $code = (new ParserFactory)->createForNewestSupportedVersion()->parse($code);
Assert::notNull($code); Assert::notNull($code);
$traverser = new NodeTraverser; $traverser = new NodeTraverser;

View File

@ -124,21 +124,6 @@ if (!getenv('GITHUB_SHA') && stripos(($MadelineProto->readline('Do you want to m
*/ */
if (!getenv('GITHUB_SHA') && stripos(($MadelineProto->readline('Do you want to handle incoming calls? (y/n): ')) ?? '', 'y') !== false) { if (!getenv('GITHUB_SHA') && stripos(($MadelineProto->readline('Do you want to handle incoming calls? (y/n): ')) ?? '', 'y') !== false) {
$howmany = $MadelineProto->readline('How many calls would you like me to handle? '); $howmany = $MadelineProto->readline('How many calls would you like me to handle? ');
$offset = 0;
while ($howmany > 0) {
$updates = $MadelineProto->getUpdates(['offset' => $offset, 'limit' => 50, 'timeout' => 0]); // Just like in the bot API, you can specify an offset, a limit and a timeout
foreach ($updates as $update) {
$MadelineProto->logger($update);
$offset = $update['update_id'] + 1; // Just like in the bot API, the offset must be set to the last update_id
switch ($update['update']['_']) {
case 'updatePhoneCall':
if (is_object($update['update']['phone_call']) && $update['update']['phone_call']->getCallState() === VoIP::CALL_STATE_INCOMING) {
$update['update']['phone_call']->accept()->play('input.raw')->then('input.raw')->playOnHold(['input.raw'])->setOutputFile('output.raw');
$howmany--;
}
}
}
}
} }
/* /*