Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for thumbnail to media class #1594

Open
wants to merge 8 commits into
base: v8
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/EventHandler/Media.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

use Amp\ByteStream\ReadableStream;
use Amp\Cancellation;
use danog\MadelineProto\EventHandler\Media\Thumbnail;
use danog\MadelineProto\Ipc\IpcCapable;
use danog\MadelineProto\MTProto;
use danog\MadelineProto\TL\Types\Bytes;
Expand Down Expand Up @@ -74,8 +75,8 @@ abstract class Media extends IpcCapable implements JsonSerializable
/** Whether this media originates from a secret chat. */
public readonly bool $encrypted;

/** Content of thumbnail file (JPEGfile, quality 55, set in a square 90x90) only for secret chats. */
public readonly ?Bytes $thumb;
/** Content of thumbnail file (JPEGfile, quality 55, set in a square 90x90). */
public readonly Bytes|Thumbnail|null $thumb;
/** Thumbnail height only for secret chats. */
public readonly ?int $thumbHeight;
/** Thumbnail width only for secret chats. */
Expand Down Expand Up @@ -119,9 +120,9 @@ public function __construct(
$this->thumbHeight = $rawMedia['thumb_h'] ?? null;
$this->thumbWidth = $rawMedia['thumb_w'] ?? null;
} else {
$this->thumb = null;
$this->thumbHeight = null;
$this->thumbWidth = null;
$this->thumb = new Thumbnail($API, $rawMedia);
$this->thumbHeight = $this->thumb->height ?? null;
$this->thumbWidth = $this->thumb->width ?? null;
}
}

Expand Down
200 changes: 200 additions & 0 deletions src/EventHandler/Media/Thumbnail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
<?php declare(strict_types=1);

/**
* 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 Mahdi <[email protected]>
* @copyright 2016-2023 Mahdi <[email protected]>
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
* @link https://docs.madelineproto.xyz MadelineProto documentation
*/

namespace danog\MadelineProto\EventHandler\Media;

use Amp\ByteStream\ReadableStream;
use Amp\Cancellation;
use danog\MadelineProto\Ipc\IpcCapable;
use danog\MadelineProto\MTProto;
use danog\MadelineProto\TL\Conversion\BotAPIFiles;
use JsonSerializable;

/**
* This object represents one size of a photo or a file / sticker thumbnail.
*/
class Thumbnail extends IpcCapable implements JsonSerializable
{
use BotAPIFiles;
/** Identifier for this file, which can be used to download or reuse the file */
public readonly string $botApiFileId;
/** Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file. */
public readonly string $botApiFileUniqueId;
/** Photo width */
public readonly ?int $width;
/** Photo height */
public readonly ?int $height;
/** File size in bytes */
public readonly int $size;
/** Thumb file name */
public readonly string $fileName;

/** Thumb file extension */
public readonly string $fileExt;
public readonly ?string $mimeType;

/** @internal Media location */
public readonly array $location;
public function __construct(
MTProto $API,
array $rawThumbnail
) {
parent::__construct($API);
if(!$this->getMediaPreview($rawThumbnail)) {
return null;
}

}

/** @internal */
public function jsonSerialize(): mixed
{
$v = get_object_vars($this);
unset($v['API'], $v['session'],$v['location']);
return !empty($v) ? $v : null;
}

/**
* Gets a download link for any file up to 4GB.
*
* @param string|null $scriptUrl Optional path to custom download script (not needed when running via web)
*/
public function getDownloadLink(?string $scriptUrl = null): string
{
return $this->getClient()->getDownloadLink($this, $scriptUrl);
}

/**
* Get a readable amp stream with the file contents.
*
* @param (callable(float, float, float): void)|null $cb Progress callback
*/
public function getStream(?callable $cb = null, int $offset = 0, int $end = -1, ?Cancellation $cancellation = null): ReadableStream
{
return $this->getClient()->downloadToReturnedStream($this, $cb, $offset, $end, $cancellation);
}

/**
* Download the media to working directory or passed path.
*
* @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, ?Cancellation $cancellation = null): string
{
$dir ??= getcwd();
return $this->getClient()->downloadToDir($this, $dir, $cb, $cancellation);
}
/**
* Download the media to file.
*
* @param string $file Downloaded file path
* @param (callable(float, float, float): void)|null $cb Progress callback
*/
public function downloadToFile(string $file, ?callable $cb = null, ?Cancellation $cancellation = null): string
{
return $this->getClient()->downloadToFile($this, $file, $cb, $cancellation);
}

/**
* @return array{
* ext: string,
* name: string,
* mime: string,
* size: int
* }
*/
public function getDownloadInfo(): array
{
$result = [
'name' => basename($this->fileName, $this->fileExt),
'ext' => $this->fileExt,
'mime' => $this->mimeType,
'size' => $this->size,
'InputFileLocation' => $this->location,
];

return $result;
}

private function getMediaPreview(array $media): bool
{

$media = match ($media['_']) {
'messageMediaPhoto' => $media['photo'],
'messageMediaDocument' => $media['document'],
'messageMediaWebPage' => $media['webpage'],
};

$thumb = null;
$thumbInfo = null;
switch (true) {
case isset($media['sizes']):
foreach ($media['sizes'] as $size) {
if ($size['_'] === 'photoSize') {
$thumb = $size;
$thumbInfo = $this->photosizeToBotAPI($thumb, $media, true);
}
}
break;
case isset($media['thumb']['size']):
$thumb = $media['thumb'];
break;
case !empty($media['thumbs']):
foreach ($media['thumbs'] as $size) {
if ($size['_'] === 'photoSize') {
$thumb = $size;
$thumbInfo = $this->photosizeToBotAPI($thumb, $media, true);
}
}
break;
case isset($media['photo']['sizes']):
foreach ($media['photo']['sizes'] as $size) {
if ($size['_'] === 'photoSize') {
$thumb = $size;
$thumbInfo = $this->photosizeToBotAPI($thumb, $media, true);
}
}
break;
default:
return false;

}

$info = $this->getClient()->getDownloadInfo($thumb);

if ($media['_'] === 'webPage') {
$media = $media['photo'];
}

//Фикс для LAYER 100+
//TODO: Удалить, когда снова станет доступна загрузка photoSize
if (isset($info['thumb_size'])) {
$infoFull = $this->getClient()->getDownloadInfo($media);
$infoFull['InputFileLocation']['thumb_size'] = $info['thumb_size'];
$this->location = $infoFull['InputFileLocation'];
$this->size = $thumbInfo['file_size'];
$this->fileExt = '.jpg';
$this->fileName = basename($thumbInfo['file_name'], $this->fileExt);
$this->mimeType = $thumbInfo['mime_type'] ?? 'image/jpeg';
$this->height = $thumbInfo['height'];
$this->width = $thumbInfo['width'];
$this->botApiFileId = $thumbInfo['file_id'];
$this->botApiFileUniqueId = $thumbInfo['file_unique_id'];
}
return true;
}
}
3 changes: 2 additions & 1 deletion src/MTProtoTools/FileServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use AssertionError;
use danog\MadelineProto\API;
use danog\MadelineProto\EventHandler\Media;
use danog\MadelineProto\EventHandler\Media\Thumbnail;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\Ipc\Runner\WebRunner;
use danog\MadelineProto\Lang;
Expand Down Expand Up @@ -98,7 +99,7 @@ public static function processDownloadServerPing(string $path, string $payload):
/**
* Get download link of media file.
*/
public function getDownloadLink(array|string|Message|Media $media, ?string $scriptUrl = null, ?int $size = null, ?string $name = null, ?string $mime = null): string
public function getDownloadLink(array|string|Message|Media|Thumbnail $media, ?string $scriptUrl = null, ?int $size = null, ?string $name = null, ?string $mime = null): string
{
$scriptUrl ??= $this->getSettings()->getFiles()->getDownloadLink();
if ($scriptUrl === null) {
Expand Down
4 changes: 4 additions & 0 deletions src/MTProtoTools/Files.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
use danog\MadelineProto\EventHandler\Media\Photo;
use danog\MadelineProto\EventHandler\Media\RoundVideo;
use danog\MadelineProto\EventHandler\Media\StaticSticker;
use danog\MadelineProto\EventHandler\Media\Thumbnail;
use danog\MadelineProto\EventHandler\Media\Video;
use danog\MadelineProto\EventHandler\Media\VideoSticker;
use danog\MadelineProto\EventHandler\Media\Voice;
Expand Down Expand Up @@ -755,6 +756,9 @@ public function getDownloadInfo(mixed $messageMedia): array
if ($messageMedia instanceof Media) {
return $messageMedia->getDownloadInfo();
}
if($messageMedia instanceof Thumbnail) {
return $messageMedia->getDownloadInfo();
}
if (\is_string($messageMedia)) {
$messageMedia = $this->unpackFileId($messageMedia);
if (isset($messageMedia['InputFileLocation'])) {
Expand Down