Skip to content
124 changes: 115 additions & 9 deletions src/EventHandler/Media.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

use Amp\ByteStream\ReadableStream;
use Amp\Cancellation;
use danog\MadelineProto\EventHandler\Media\SecretChatThumbnail;
use danog\MadelineProto\EventHandler\Media\Thumbnail;
use danog\MadelineProto\Ipc\IpcCapable;
use danog\MadelineProto\MTProto;
use danog\MadelineProto\TL\Conversion\BotAPIFiles;
use danog\MadelineProto\TL\Types\Bytes;
use JsonSerializable;

Expand All @@ -28,6 +31,7 @@
*/
abstract class Media extends IpcCapable implements JsonSerializable
{
use BotAPIFiles;
/** Media filesize */
public readonly int $size;

Expand Down Expand Up @@ -74,8 +78,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 SecretChatThumbnail|Thumbnail|Bytes $thumb;
/** Thumbnail height only for secret chats. */
public readonly ?int $thumbHeight;
/** Thumbnail width only for secret chats. */
Expand Down Expand Up @@ -113,13 +117,43 @@ public function __construct(
$this->keyFingerprint = $rawMedia['file']['key_fingerprint'] ?? null;
$this->key = isset($rawMedia['key']) ? (string) $rawMedia['key'] : null;
$this->iv = isset($rawMedia['iv']) ? (string) $rawMedia['iv'] : null;
if ($this->encrypted = isset($rawMedia['iv'])) {
$thumb = $rawMedia['thumb'] ?? null;
$this->thumb = \is_string($thumb) ? new Bytes($thumb) : $thumb;
$this->thumbHeight = $rawMedia['thumb_h'] ?? null;
$this->thumbWidth = $rawMedia['thumb_w'] ?? null;
} else {
$this->thumb = null;
if(isset($rawMedia['thumb'])){
if(is_string($rawMedia['thumb'])){
$this->thumb = new Bytes($rawMedia['thumb']);
}
elseif ($this->encrypted = isset($rawMedia['iv'])){
$thumbInfo = $this->getMediaPreview($rawMedia['thumb']);
$this->thumb = new SecretChatThumbnail(
$API,
$rawMedia['thumb'],
false,
$thumbInfo['thumb_file_name'],
$thumbInfo['thumb_file_size'],
$thumbInfo['thumb_location'],
$thumbInfo['thumb_mime_type'],
$thumbInfo['thumb_file_ext'],
$this->key,
$this->iv,
$this->keyFingerprint
);
}else{
$thumbInfo = $this->getMediaPreview($rawMedia['thumb']);

$this->thumb = new Thumbnail(
$API,
$rawMedia['thumb'],
false,
$thumbInfo['thumb_file_name'],
$thumbInfo['thumb_file_size'],
$thumbInfo['thumb_location'],
$thumbInfo['thumb_mime_type'],
$thumbInfo['thumb_file_ext']
);
}
$this->thumbHeight = $thumbInfo['thumb_height'] ?? null;
$this->thumbWidth = $thumbInfo['thumb_width'] ?? null;

}else{
$this->thumbHeight = null;
$this->thumbWidth = null;
}
Expand Down Expand Up @@ -195,6 +229,78 @@ public function getDownloadInfo(): array
}
return $result;
}

public function getMediaPreview(array $media): ?array
{

$media = match ($media['_']) {
'messageMediaPhoto' => $media['photo'],
'messageMediaDocument' => $media['document'],
'decryptedMessageMediaDocument' => $media,
'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 null;

}

$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'];
return [
'thumb_location' => $infoFull['InputFileLocation'],
'thumb_file_size' => $thumbInfo['file_size'],
'thumb_mime_type' => $thumbInfo['mime_type'] ?? 'image/jpeg',
'thumb_file_ext' => '.jpg',
'thumb_file_name' => basename($thumbInfo['file_name'], $this->fileExt),
'thumb_height' => $thumbInfo['height'] ?? null,
'thumb_width' => $thumbInfo['width'] ?? null,
'thumb_bot_api_file_id' => $thumbInfo['file_id'] ?? null,
'thumb_bot_api_file_unique_id' => $thumbInfo['file_unique_id'] ?? null,
];
}
return null;
}

/** @internal */
#[\Override]
public function jsonSerialize(): mixed
Expand Down
68 changes: 68 additions & 0 deletions src/EventHandler/Media/AbstractThumbnail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?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 <mahdi.talaee1379@gmail.com>
* @copyright 2016-2023 Mahdi <mahdi.talaee1379@gmail.com>
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
* @link https://docs.madelineproto.xyz MadelineProto documentation
*/

namespace danog\MadelineProto\EventHandler\Media;

use danog\MadelineProto\EventHandler\Media;
use danog\MadelineProto\MTProto;
use danog\MadelineProto\TL\Conversion\BotAPIFiles;

/**
* Abstract class for thumbnail.
*/
abstract class AbstractThumbnail extends Media
{
/** @internal Media location */
public function __construct(
MTProto $API,
array $rawMedia,
bool $protected,
/** Thumb file name */
protected readonly string $thumbFileName,
/** File size in bytes */
protected readonly int $thumbFileSize,
/** thumb location */
protected readonly array $thumbLocation,
/** Thumb mime type */
protected readonly string $thumbMimeType,
/** Thumb file extension */
protected readonly string $thumbFileExt
)
{
parent::__construct($API, $rawMedia, $protected);
}

/**
* @return array{
* ext: string,
* name: string,
* mime: string,
* size: int
* }
*/
public function getDownloadInfo(): array
{
$result = [
'name' => basename($this->thumbFileName, $this->thumbFileExt),
'ext' => $this->thumbFileExt,
'mime' => $this->thumbMimeType,
'size' => $this->thumbFileSize,
'InputFileLocation' => $this->thumbLocation,
];

return $result;
}
}
59 changes: 59 additions & 0 deletions src/EventHandler/Media/SecretChatThumbnail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?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 <mahdi.talaee1379@gmail.com>
* @copyright 2016-2023 Mahdi <mahdi.talaee1379@gmail.com>
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
* @link https://docs.madelineproto.xyz MadelineProto documentation
*/

namespace danog\MadelineProto\EventHandler\Media;

use danog\MadelineProto\MTProto;

class SecretChatThumbnail extends AbstractThumbnail
{
/** @internal */
public function __construct(
MTProto $API,
array $rawMedia,
bool $protected,
string $thumbFileName,
int $thumbFileSize,
array $thumbLocation,
string $thumbMimeType,
string $thumbFileExt,
private string $thumbKey,
private string $thumbIv,
private array $thumbKeyFingerprint
)
{
parent::__construct(
$API,
$rawMedia,
$protected,
$thumbFileName,
$thumbFileSize,
$thumbLocation,
$thumbMimeType,
$thumbFileExt
);
}

public function getDownloadInfo(): array
{
$result = parent::getDownloadInfo();
$result['key'] = $this->thumbKey;
$result['iv'] = $this->thumbIv;
$result['key_fingerprint'] = $this->thumbKeyFingerprint;
return $result;
}

}
38 changes: 38 additions & 0 deletions src/EventHandler/Media/Thumbnail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?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 <mahdi.talaee1379@gmail.com>
* @copyright 2016-2023 Mahdi <mahdi.talaee1379@gmail.com>
* @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.
*/
final class Thumbnail extends AbstractThumbnail
{

public function __construct(MTProto $API, array $rawMedia, bool $protected, string $thumbFileName, int $thumbFileSize, array $thumbLocation, string $thumbMimeType, string $thumbFileExt)
{
parent::__construct($API, $rawMedia, $protected, $thumbFileName, $thumbFileSize, $thumbLocation, $thumbMimeType, $thumbFileExt);
}


}