Fix upload by URL

This commit is contained in:
Daniil Gentili 2019-06-25 15:11:37 +00:00
parent cd5cd8611c
commit 6f5d1b16fa
7 changed files with 113 additions and 27 deletions

13
bot.php
View File

@ -46,19 +46,6 @@ class EventHandler extends \danog\MadelineProto\EventHandler
yield $this->messages->sendMessage(['peer' => $update, 'message' => "<code>$res</code>", 'reply_to_msg_id' => isset($update['message']['id']) ? $update['message']['id'] : null, 'parse_mode' => 'HTML']); //'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json']]]);
if (isset($update['message']['media']) && $update['message']['media']['_'] !== 'messageMediaGame') {
yield $this->messages->sendMedia(['peer' => $update, 'message' => $update['message']['message'], 'media' => $update]);
yield $this->messages->sendMedia([
'peer' => '@danogentili',
'media' => [
'_' => 'inputMediaUploadedDocument',
'file' => 'https://google.com',
'attributes' => [
['_' => 'documentAttributeFilename', 'file_name' => 'document.txt']
]
],
'message' => '[This is the caption](https://t.me/MadelineProto)',
'parse_mode' => 'Markdown'
]);
//yield $this->download_to_dir($update, '/tmp');
}
} catch (\danog\MadelineProto\RPCErrorException $e) {

2
docs

@ -1 +1 @@
Subproject commit cbd913fba2249a0055bb732452a67f911119c40a
Subproject commit dc05dc5cebfcec90ac7851928c522a4d635dbab6

View File

@ -34,7 +34,7 @@ use danog\MadelineProto\Exception;
use danog\MadelineProto\FileCallbackInterface;
use danog\MadelineProto\Logger;
use danog\MadelineProto\RPCErrorException;
use danog\MadelineProto\Stream\Common\BufferedRawStream;
use danog\MadelineProto\Stream\Common\SimpleBufferedRawStream;
use danog\MadelineProto\Stream\ConnectionContext;
use danog\MadelineProto\Stream\Transport\PremadeStream;
use function Amp\File\exists;
@ -43,6 +43,7 @@ use function Amp\File\stat;
use function Amp\File\touch;
use function Amp\Promise\all;
use Amp\File\BlockingHandle;
use Amp\Artax\Client;
/**
* Manages upload and download of files.
@ -94,7 +95,7 @@ trait Files
$url = $url->getFile();
}
/** @var $response \Amp\Artax\Response */
$response = yield $this->datacenter->getHTTPClient()->request($url);
$response = yield $this->datacenter->getHTTPClient()->request($url, [Client::OP_MAX_BODY_BYTES => 512 * 1024 * 3000, Client::OP_TRANSFER_TIMEOUT => 10*1000*3600]);
if (200 !== $status = $response->getStatus()) {
throw new Exception("Wrong status code: $status ".$response->getReason());
}
@ -103,6 +104,8 @@ trait Files
$stream = $response->getBody();
if (!$size) {
$this->logger->logger("No content length for $url, caching first");
$body = $stream;
$stream = new BlockingHandle(fopen('php://temp', 'r+b'), 'php://temp', 'r+b');
@ -141,7 +144,9 @@ trait Files
}
}
if ($stream instanceof Handle || $stream instanceof BufferedRawStream) {
$created = false;
if ($stream instanceof Handle) {
$callable = static function (int $offset, int $size) use ($stream, $seekable) {
if ($seekable) {
while ($stream->tell() !== $offset) {
@ -151,18 +156,30 @@ trait Files
return yield $stream->read($size);
};
} else {
$ctx = (new ConnectionContext)
->addStream(PremadeStream::getName(), $stream)
->addStream(BufferedRawStream::getName());
$stream = yield $ctx->getStream();
if (!$stream instanceof BufferedRawStream) {
$ctx = (new ConnectionContext)
->addStream(PremadeStream::getName(), $stream)
->addStream(SimpleBufferedRawStream::getName());
$stream = yield $ctx->getStream();
$created = true;
}
$callable = static function (int $offset, int $size) use ($stream) {
return yield $stream->read($size);
$reader = yield $stream->getReadBuffer($l);
try {
return yield $reader->bufferRead($size);
} catch (\danog\MadelineProto\NothingInTheSocketException $e) {
$reader = yield $stream->getReadBuffer($size);
return yield $reader->bufferRead($size);
}
};
$seekable = false;
}
return yield $this->upload_from_callable_async($callable, $size, $mime, $file_name, $cb, $seekable, $encrypted);
$res = yield $this->upload_from_callable_async($callable, $size, $mime, $file_name, $cb, $seekable, $encrypted);
if ($created) {
$stream->disconnect();
}
return $res;
}
public function upload_from_callable_async($callable, int $size, string $mime, string $file_name = '', $cb = null, bool $refetchable = true, bool $encrypted = false)
{

View File

@ -368,6 +368,10 @@ trait ResponseHandler
return;
}
if (in_array($response['error_message'], ['MSGID_DECREASE_RETRY', 'RPC_CALL_FAIL', 'RPC_MCGET_FAIL', 'no workers running'])) {
Loop::delay(1 * 1000, [$this, 'method_recall'], ['message_id' => $request_id, 'datacenter' => $datacenter]);
return;
}
$this->got_response_for_outgoing_message_id($request_id, $datacenter);
$this->handle_reject($datacenter, $request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : ''));

View File

@ -0,0 +1,77 @@
<?php
/**
* Buffered raw stream.
*
* This file is part of MadelineProto.
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
* You should have received a copy of the GNU General Public License along with MadelineProto.
* If not, see <http://www.gnu.org/licenses/>.
*
* @author Daniil Gentili <daniil@daniil.it>
* @copyright 2016-2019 Daniil Gentili <daniil@daniil.it>
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
*
* @link https://docs.madelineproto.xyz MadelineProto documentation
*/
namespace danog\MadelineProto\Stream\Common;
use Amp\Promise;
use Amp\Success;
use danog\MadelineProto\Exception;
use danog\MadelineProto\Stream\Async\RawStream;
use danog\MadelineProto\Stream\ConnectionContext;
use function Amp\Socket\connect;
use danog\MadelineProto\Stream\BufferedStreamInterface;
use danog\MadelineProto\Stream\BufferInterface;
use danog\MadelineProto\Stream\RawStreamInterface;
/**
* Buffered raw stream.
*
* @author Daniil Gentili <daniil@daniil.it>
*/
class SimpleBufferedRawStream extends BufferedRawStream implements BufferedStreamInterface, BufferInterface, RawStreamInterface
{
/**
* Read data asynchronously.
*
* @param int $length Amount of data to read
*
* @return \Generator
*/
public function bufferReadAsync(int $length): \Generator
{
$size = fstat($this->memory_stream)['size'];
$offset = ftell($this->memory_stream);
$buffer_length = $size - $offset;
if ($buffer_length < $length && $buffer_length) {
fseek($this->memory_stream, $offset + $buffer_length);
}
while ($buffer_length < $length) {
$chunk = yield $this->read();
if ($chunk === null) {
fseek($this->memory_stream, $offset);
break;
}
fwrite($this->memory_stream, $chunk);
$buffer_length += strlen($chunk);
}
fseek($this->memory_stream, $offset);
return fread($this->memory_stream, $length);
}
/**
* Get class name.
*
* @return string
*/
public static function getName(): string
{
return __CLASS__;
}
}

View File

@ -95,7 +95,9 @@ class PremadeStream extends Socket implements RawStreamInterface, ProxyStreamInt
{
try {
if ($this->stream) {
$this->stream->close();
if (method_exists($this->stream, 'close')) {
$this->stream->close();
}
$this->stream = null;
}
} catch (\Throwable $e) {

View File

@ -191,7 +191,6 @@ trait AuthKeyHandler
$visualization[] = \danog\MadelineProto\Magic::$emojis[(int) (new \phpseclib\Math\BigInteger($number, 256))->divide($length)[1]->toString()];
}
$this->calls[$params['id']]->setVisualization($visualization);
var_dump($params);
$this->calls[$params['id']]->configuration['endpoints'] = array_merge($params['connections'], $this->calls[$params['id']]->configuration['endpoints']);
$this->calls[$params['id']]->configuration = array_merge(['recv_timeout' => $this->config['call_receive_timeout_ms'] / 1000, 'init_timeout' => $this->config['call_connect_timeout_ms'] / 1000, 'data_saving' => \danog\MadelineProto\VoIP::DATA_SAVING_NEVER, 'enable_NS' => true, 'enable_AEC' => true, 'enable_AGC' => true, 'auth_key' => $key, 'auth_key_id' => substr(sha1($key, true), -8), 'call_id' => substr(hash('sha256', $key, true), -16), 'network_type' => \danog\MadelineProto\VoIP::NET_TYPE_ETHERNET], $this->calls[$params['id']]->configuration);
$this->calls[$params['id']]->parseConfig();