Adding getUrl command in the downloadbot

This commit is contained in:
Daniil Gentili 2020-02-09 17:29:39 +01:00
parent 47228712a6
commit 4b1cf229e5
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
10 changed files with 137 additions and 52 deletions

View File

@ -22,7 +22,9 @@
use Amp\Http\Server\HttpServer; use Amp\Http\Server\HttpServer;
use danog\MadelineProto\API; use danog\MadelineProto\API;
use danog\MadelineProto\Logger; use danog\MadelineProto\Logger;
use danog\MadelineProto\MTProtoTools\Files;
use danog\MadelineProto\RPCErrorException; use danog\MadelineProto\RPCErrorException;
use danog\MadelineProto\Tools;
use League\Uri\Contracts\UriException; use League\Uri\Contracts\UriException;
/* /*
@ -99,16 +101,17 @@ class EventHandler extends \danog\MadelineProto\EventHandler
if ($this->UPLOAD && $update['message']['message'] === '/getUrl') { if ($this->UPLOAD && $update['message']['message'] === '/getUrl') {
yield $this->messages->sendMessage(['peer' => $peerId, 'message' => 'Give me a file: ', 'reply_to_msg_id' => $messageId]); yield $this->messages->sendMessage(['peer' => $peerId, 'message' => 'Give me a file: ', 'reply_to_msg_id' => $messageId]);
$this->states[$peerId] = $this->UPLOAD; $this->states[$peerId] = $this->UPLOAD;
return;
} }
if ($update['message']['message'] === '/start') { if ($update['message']['message'] === '/start') {
return $this->messages->sendMessage(['peer' => $peerId, 'message' => self::START, 'parse_mode' => 'Markdown', 'reply_to_msg_id' => $messageId]); return $this->messages->sendMessage(['peer' => $peerId, 'message' => self::START, 'parse_mode' => 'Markdown', 'reply_to_msg_id' => $messageId]);
} }
if (isset($update['message']['media']['_']) && $update['message']['media']['_'] !== 'messageMediaWebPage') { if (isset($update['message']['media']['_']) && $update['message']['media']['_'] !== 'messageMediaWebPage') {
if ($this->UPLOAD && ($this->states[$peerId] ?? false) === $this->UPLOAD) { if ($this->UPLOAD && ($this->states[$peerId] ?? false) === $this->UPLOAD) {
$media = yield $this->getDownloadInfo($this->states[$peerId]);
unset($media['MessageMedia']);
$media = yield
unset($this->states[$peerId]); unset($this->states[$peerId]);
$update = Files::extractBotAPIFile(yield $this->MTProtoToBotAPI($update));
$file = [$update['file_size'], $update['mime_type']];
\var_dump($update['file_id'].'.'.Tools::base64urlEncode(json_encode($file))."/".$update['file_name']);
return; return;
} }
yield $this->messages->sendMessage(['peer' => $peerId, 'message' => 'Give me a new name for this file: ', 'reply_to_msg_id' => $messageId]); yield $this->messages->sendMessage(['peer' => $peerId, 'message' => 'Give me a new name for this file: ', 'reply_to_msg_id' => $messageId]);

View File

@ -53,10 +53,10 @@ class Exception extends \Exception
} }
} }
/** /**
* Complain about missing extensions * Complain about missing extensions.
* *
* @param string $extensionName Extension name * @param string $extensionName Extension name
* *
* @return self * @return self
*/ */
public static function extension(string $extensionName): self public static function extension(string $extensionName): self

View File

@ -4373,7 +4373,7 @@ class InternalDoc extends APIFactory
* *
* @return \Generator<array> Chat object * @return \Generator<array> Chat object
*/ */
public function getPwrChat($id, $fullfetch = true, $send = true, array $extra = []) public function getPwrChat($id, bool $fullfetch = true, bool $send = true, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$id, $fullfetch, $send, $extra]); return $this->__call(__FUNCTION__, [$id, $fullfetch, $send, $extra]);
} }
@ -4499,7 +4499,7 @@ class InternalDoc extends APIFactory
* `$info['mime']` - The file mime type * `$info['mime']` - The file mime type
* `$info['size']` - The file size * `$info['size']` - The file size
* *
* @param mixed $message_media File ID * @param mixed $messageMedia File ID
* *
* @return \Generator<array> * @return \Generator<array>
*/ */
@ -4507,6 +4507,17 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$data, $extra]); return $this->__call(__FUNCTION__, [$data, $extra]);
} }
/**
* Extract file info from bot API message.
*
* @param array $info Bot API message object
*
* @return ?array
*/
public function extractBotAPIFile(array $info): ?array
{
return \danog\MadelineProto\MTProto::extractBotAPIFile($info);
}
/** /**
* Get download info of file * Get download info of file
* Returns an array with the following structure:. * Returns an array with the following structure:.
@ -4516,44 +4527,84 @@ class InternalDoc extends APIFactory
* `$info['mime']` - The file mime type * `$info['mime']` - The file mime type
* `$info['size']` - The file size * `$info['size']` - The file size
* *
* @param mixed $message_media File ID * @param mixed $messageMedia File ID
* *
* @return \Generator<array> * @return \Generator<array>
*/ */
public function getDownloadInfo($message_media, array $extra = []) public function getDownloadInfo($messageMedia, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$message_media, $extra]); return $this->__call(__FUNCTION__, [$messageMedia, $extra]);
}
/**
* Download file to browser.
*
* Supports HEAD requests and content-ranges for parallel and resumed downloads.
*
* @param array|string $messageMedia File to download
* @param callable $cb Status callback (can also use FileCallback)
*
* @return \Generator
*/
public function downloadToBrowser($messageMedia, ?callable $cb = null, array $extra = [])
{
return $this->__call(__FUNCTION__, [$messageMedia, $cb, $extra]);
}
/**
* Download file to amphp/http-server response.
*
* Supports HEAD requests and content-ranges for parallel and resumed downloads.
*
* @param array|string $messageMedia File to download
* @param ServerRequest $request Request
* @param callable $cb Status callback (can also use FileCallback)
*
* @return \Generator<Response> Returned response
*/
public function downloadToResponse($messageMedia, \Amp\Http\Server\Request $request, ?callable $cb = null, array $extra = [])
{
return $this->__call(__FUNCTION__, [$messageMedia, $request, $cb, $extra]);
}
/**
* Get explanation for HTTP error.
*
* @param integer $code HTTP error code
*
* @return string
*/
public function getExplanation(int $code): string
{
return \danog\MadelineProto\MTProto::getExplanation($code);
} }
/** /**
* Download file to directory. * Download file to directory.
* *
* @param mixed $message_media File to download * @param mixed $messageMedia File to download
* @param string|FileCallbackInterface $dir Directory where to download the file * @param string|FileCallbackInterface $dir Directory where to download the file
* @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface)
* *
* @return \Generator<string> Downloaded file path * @return \Generator<string> Downloaded file path
*/ */
public function downloadToDir($message_media, $dir, $cb = null, array $extra = []) public function downloadToDir($messageMedia, $dir, $cb = null, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$message_media, $dir, $cb, $extra]); return $this->__call(__FUNCTION__, [$messageMedia, $dir, $cb, $extra]);
} }
/** /**
* Download file. * Download file.
* *
* @param mixed $message_media File to download * @param mixed $messageMedia File to download
* @param string|FileCallbackInterface $file Downloaded file path * @param string|FileCallbackInterface $file Downloaded file path
* @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface)
* *
* @return \Generator<string> Downloaded file path * @return \Generator<string> Downloaded file path
*/ */
public function downloadToFile($message_media, $file, $cb = null, array $extra = []) public function downloadToFile($messageMedia, $file, $cb = null, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$message_media, $file, $cb, $extra]); return $this->__call(__FUNCTION__, [$messageMedia, $file, $cb, $extra]);
} }
/** /**
* Download file to stream. * Download file to stream.
* *
* @param mixed $message_media File to download * @param mixed $messageMedia File to download
* @param mixed|FileCallbackInterface $stream Stream where to download file * @param mixed|FileCallbackInterface $stream Stream where to download file
* @param callable $cb Callback (DEPRECATED, use FileCallbackInterface) * @param callable $cb Callback (DEPRECATED, use FileCallbackInterface)
* @param int $offset Offset where to start downloading * @param int $offset Offset where to start downloading
@ -4561,9 +4612,9 @@ class InternalDoc extends APIFactory
* *
* @return \Generator<bool> * @return \Generator<bool>
*/ */
public function downloadToStream($message_media, $stream, $cb = null, int $offset = 0, int $end = -1, array $extra = []) public function downloadToStream($messageMedia, $stream, $cb = null, int $offset = 0, int $end = -1, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$message_media, $stream, $cb, $offset, $end, $extra]); return $this->__call(__FUNCTION__, [$messageMedia, $stream, $cb, $offset, $end, $extra]);
} }
/** /**
* Download file to callable. * Download file to callable.
@ -4571,7 +4622,7 @@ class InternalDoc extends APIFactory
* The callable will be called (possibly out of order, depending on the value of $seekable). * The callable will be called (possibly out of order, depending on the value of $seekable).
* The callable should return the number of written bytes. * The callable should return the number of written bytes.
* *
* @param mixed $message_media File to download * @param mixed $messageMedia File to download
* @param callable|FileCallbackInterface $callable Chunk callback * @param callable|FileCallbackInterface $callable Chunk callback
* @param callable $cb Status callback (DEPRECATED, use FileCallbackInterface) * @param callable $cb Status callback (DEPRECATED, use FileCallbackInterface)
* @param bool $seekable Whether the callable can be called out of order * @param bool $seekable Whether the callable can be called out of order
@ -4581,9 +4632,9 @@ class InternalDoc extends APIFactory
* *
* @return \Generator<bool> * @return \Generator<bool>
*/ */
public function downloadToCallable($message_media, $callable, $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, ?int $part_size = null, array $extra = []) public function downloadToCallable($messageMedia, callable $callable, $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, ?int $part_size = null, array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$message_media, $callable, $cb, $seekable, $offset, $end, $part_size, $extra]); return $this->__call(__FUNCTION__, [$messageMedia, $callable, $cb, $seekable, $offset, $end, $part_size, $extra]);
} }
/** /**
* Accept secret chat. * Accept secret chat.
@ -4701,15 +4752,13 @@ class InternalDoc extends APIFactory
/** /**
* Convert MTProto parameters to bot API parameters. * Convert MTProto parameters to bot API parameters.
* *
* @param array $data Data * @param array $data Data
* @param array $sent_arguments Sent arguments
* *
* @return \Generator<array> * @return \Generator<array>
*/ */
public function MTProtoToBotAPI(array $data, array $sent_arguments = [ public function MTProtoToBotAPI(array $data, array $extra = [])
], array $extra = [])
{ {
return $this->__call(__FUNCTION__, [$data, $sent_arguments, $extra]); return $this->__call(__FUNCTION__, [$data, $extra]);
} }
/** /**
* Convert bot API parameters to MTProto parameters. * Convert bot API parameters to MTProto parameters.
@ -5109,18 +5158,6 @@ class InternalDoc extends APIFactory
{ {
return $this->__call(__FUNCTION__, [$a, $b]); return $this->__call(__FUNCTION__, [$a, $b]);
} }
/**
* Asynchronously send noCache headers.
*
* @param integer $status HTTP status code to send
* @param string $message Message to print
*
* @return Promise
*/
public function noCache(int $status, string $message)
{
return $this->__call(__FUNCTION__, [$status, $message]);
}
/** /**
* Asynchronously lock a file * Asynchronously lock a file
* Resolves with a callbable that MUST eventually be called in order to release the lock. * Resolves with a callbable that MUST eventually be called in order to release the lock.

View File

@ -40,16 +40,16 @@ class MsgIdHandler64 extends MsgIdHandlerAbstract
*/ */
private $maxOutgoingId = 0; private $maxOutgoingId = 0;
/** /**
* Check validity of given message ID * Check validity of given message ID.
* *
* @param string $newMessageId New message ID * @param string $newMessageId New message ID
* @param array $aargs Params * @param array $aargs Params
* *
* @return void * @return void
*/ */
public function checkMessageId($newMessageId, array $aargs): void public function checkMessageId($newMessageId, array $aargs): void
{ {
$newMessageId = is_integer($newMessageId) ? $newMessageId : Tools::unpackSignedLong($newMessageId); $newMessageId = \is_integer($newMessageId) ? $newMessageId : Tools::unpackSignedLong($newMessageId);
$minMessageId = (\time() + $this->session->time_delta - 300) << 32; $minMessageId = (\time() + $this->session->time_delta - 300) << 32;
if ($newMessageId < $minMessageId) { if ($newMessageId < $minMessageId) {
$this->session->API->logger->logger('Given message id ('.$newMessageId.') is too old compared to the min value ('.$minMessageId.').', \danog\MadelineProto\Logger::WARNING); $this->session->API->logger->logger('Given message id ('.$newMessageId.') is too old compared to the min value ('.$minMessageId.').', \danog\MadelineProto\Logger::WARNING);
@ -124,4 +124,4 @@ class MsgIdHandler64 extends MsgIdHandlerAbstract
{ {
return $this->{$incoming ? 'maxIncomingId' : 'maxOutgoingId'}; return $this->{$incoming ? 'maxIncomingId' : 'maxOutgoingId'};
} }
} }

View File

@ -42,6 +42,9 @@ use danog\MadelineProto\Stream\Common\SimpleBufferedRawStream;
use danog\MadelineProto\Stream\ConnectionContext; use danog\MadelineProto\Stream\ConnectionContext;
use danog\MadelineProto\Stream\Transport\PremadeStream; use danog\MadelineProto\Stream\Transport\PremadeStream;
use danog\MadelineProto\Tools; use danog\MadelineProto\Tools;
use const danog\Decoder\TYPES;
use function Amp\File\exists; use function Amp\File\exists;
use function Amp\File\open; use function Amp\File\open;
use function Amp\File\stat as statAsync; use function Amp\File\stat as statAsync;
@ -549,7 +552,7 @@ trait Files
$constructor = $constructor['MessageMedia']; $constructor = $constructor['MessageMedia'];
} elseif (isset($constructor['InputMedia'])) { } elseif (isset($constructor['InputMedia'])) {
return $constructor; return $constructor;
} else if (isset($constructor['Chat']) || isset($constructor['User'])) { } elseif (isset($constructor['Chat']) || isset($constructor['User'])) {
throw new Exception("Chat photo file IDs can't be reused to resend chat photos, please use getPwrChat()['photo'], instead"); throw new Exception("Chat photo file IDs can't be reused to resend chat photos, please use getPwrChat()['photo'], instead");
} }
} }
@ -582,6 +585,31 @@ trait Files
{ {
return yield from $this->getDownloadInfo($this->chats[(yield from $this->getInfo($data))['bot_api_id']]); return yield from $this->getDownloadInfo($this->chats[(yield from $this->getInfo($data))['bot_api_id']]);
} }
/**
* Extract file info from bot API message.
*
* @param array $info Bot API message object
*
* @return ?array
*/
public static function extractBotAPIFile(array $info): ?array
{
foreach (TYPES as $type) {
if (isset($info[$type]) && \is_array($info[$type])) {
$method = $type;
break;
}
}
if (!isset($method)) {
return null;
}
$info = $info[$method];
if ($method === 'photo') {
$info = $info[0];
}
$info['file_type'] = $method;
return $info;
}
/** /**
* Get download info of file * Get download info of file
* Returns an array with the following structure:. * Returns an array with the following structure:.
@ -605,6 +633,21 @@ trait Files
$messageMedia = $messageMedia['MessageMedia'] ?? $messageMedia['User'] ?? $messageMedia['Chat']; $messageMedia = $messageMedia['MessageMedia'] ?? $messageMedia['User'] ?? $messageMedia['Chat'];
} }
if (!isset($messageMedia['_'])) { if (!isset($messageMedia['_'])) {
if (!isset($messageMedia['InputFileLocation']) && !isset($messageMedia['file_id'])) {
$messageMedia = self::extractBotAPIFile($messageMedia) ?? $messageMedia;
}
if (isset($messageMedia['file_id'])) {
$res = yield from $this->getDownloadInfo($messageMedia['file_id']);
$res['size'] = $messageMedia['file_size'] ?? 0;
$res['mime'] = $messageMedia['mime_type'] ?? 'application/octet-stream';
$pathinfo = \pathinfo($messageMedia['file_name']);
if (isset($pathinfo['extension'])) {
$res['ext'] = '.'.$pathinfo['extension'];
}
$res['name'] = $pathinfo['filename'];
return $res;
}
return $messageMedia; return $messageMedia;
} }
$res = []; $res = [];
@ -916,6 +959,8 @@ trait Files
* @param array $headers HTTP headers * @param array $headers HTTP headers
* @param array $messageMedia Media info * @param array $messageMedia Media info
* *
* @internal
*
* @return array Info about headers * @return array Info about headers
*/ */
private static function parseHeaders(string $method, array $headers, array $messageMedia): array private static function parseHeaders(string $method, array $headers, array $messageMedia): array

View File

@ -23,7 +23,6 @@ use Amp\Http\Client\Request;
use danog\Decoder\FileId; use danog\Decoder\FileId;
use danog\Decoder\PhotoSizeSource\PhotoSizeSourceDialogPhoto; use danog\Decoder\PhotoSizeSource\PhotoSizeSourceDialogPhoto;
use const danog\Decoder\PHOTO;
use const danog\Decoder\PROFILE_PHOTO; use const danog\Decoder\PROFILE_PHOTO;
/** /**
@ -846,7 +845,7 @@ trait PeerHandler
$photo = []; $photo = [];
foreach ([ foreach ([
'small' => $res['photo']['sizes'][0], 'small' => $res['photo']['sizes'][0],
'big' => end($res['photo']['sizes']), 'big' => \end($res['photo']['sizes']),
] as $type => $size) { ] as $type => $size) {
$fileId = new FileId; $fileId = new FileId;
$fileId->setId($res['photo']['id'] ?? 0); $fileId->setId($res['photo']['id'] ?? 0);

View File

@ -206,7 +206,8 @@ trait BotAPI
} }
return $newd; return $newd;
case 'updates': case 'updates':
$data = array_values(array_filter($data['updates'], fn(array $update) => $update['_'] !== 'updateMessageID'))[0]; $data = \array_values(\array_filter($data['updates'], fn (array $update) => $update['_'] !== 'updateMessageID'))[0];
// no break
case 'updateNewChannelMessage': case 'updateNewChannelMessage':
case 'updateNewMessage': case 'updateNewMessage':
return yield from $this->MTProtoToBotAPI($data['message']); return yield from $this->MTProtoToBotAPI($data['message']);

View File

@ -65,10 +65,10 @@ trait BotAPIFiles
return [ return [
'file_id' => (string) $fileId, 'file_id' => (string) $fileId,
'file_unique_id' => $fileId->getUniqueBotAPI(), 'file_unique_id' => $fileId->getUniqueBotAPI(),
'width' => $photoSize['w'], 'width' => $photoSize['w'],
'height' => $photoSize['h'], 'height' => $photoSize['h'],
'file_size' => $photoSize['size'] ?? \strlen($photoSize['bytes']), 'file_size' => $photoSize['size'] ?? \strlen($photoSize['bytes']),
'mime_type' => 'image/jpeg', 'mime_type' => 'image/jpeg',
'file_name' => $photoSize['location']['volume_id'].'_'.$photoSize['location']['local_id'].'.jpg' 'file_name' => $photoSize['location']['volume_id'].'_'.$photoSize['location']['local_id'].'.jpg'
]; ];
} }

View File

@ -59,6 +59,7 @@ echo '{
composer config platform.php "7.4" composer config platform.php "7.4"
composer clearcache composer clearcache
composer update composer update
composer require amphp/mysql
[ $PHP_MAJOR_VERSION -eq 5 ] && composer require dstuecken/php7ify [ $PHP_MAJOR_VERSION -eq 5 ] && composer require dstuecken/php7ify
composer dumpautoload --optimize composer dumpautoload --optimize
cp -a $madelinePath/src vendor/danog/madelineproto cp -a $madelinePath/src vendor/danog/madelineproto

View File

@ -2,7 +2,6 @@
use danog\MadelineProto\Logger; use danog\MadelineProto\Logger;
use danog\MadelineProto\TON\API; use danog\MadelineProto\TON\API;
use danog\MadelineProto\Tools;
require 'vendor/autoload.php'; require 'vendor/autoload.php';