Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package com.github.stickerifier.stickerify.telegram.model;

public record TelegramFile(String id, long size) {
import org.jspecify.annotations.Nullable;

public record TelegramFile(String id, @Nullable Long size) {
private static final String INVALID_ID = "";
private static final long INVALID_SIZE = -1L;
private static final long MAX_DOWNLOADABLE_FILE_SIZE_IN_BYTES = 20_000_000L;

public static final TelegramFile NOT_SUPPORTED = new TelegramFile(INVALID_ID);
public static final TelegramFile NOT_SUPPORTED = new TelegramFile(INVALID_ID, null);
public static final TelegramFile TOO_LARGE = new TelegramFile(INVALID_ID, MAX_DOWNLOADABLE_FILE_SIZE_IN_BYTES + 1);

public TelegramFile(String id) {
this(id, INVALID_SIZE);
public boolean canBeDownloaded() {
return size != null && size > 0 && size <= MAX_DOWNLOADABLE_FILE_SIZE_IN_BYTES;
}

public boolean canBeDownloaded() {
return size <= MAX_DOWNLOADABLE_FILE_SIZE_IN_BYTES;
public long sizeValue() {
return size == null ? -1L : size;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.stickerifier.stickerify.telegram.Answer;
import com.pengrad.telegrambot.model.Document;
import com.pengrad.telegrambot.model.LivePhoto;
import com.pengrad.telegrambot.model.Message;
import com.pengrad.telegrambot.model.PhotoSize;
import com.pengrad.telegrambot.model.Sticker;
Expand All @@ -34,18 +35,19 @@ public record TelegramRequest(Message message) {
public @Nullable TelegramFile getFile() {
return getMessageMedia()
.map(media -> switch (media) {
case LivePhoto livePhoto -> new TelegramFile(livePhoto.fileId(), livePhoto.fileSize());
case PhotoSize[] photos when photos.length > 0 -> getBestPhoto(photos);
case Document document -> new TelegramFile(document.fileId(), document.fileSize());
case Sticker sticker -> new TelegramFile(sticker.fileId(), sticker.fileSize());
case Video video -> getVideo(video);
case Video video -> new TelegramFile(video.fileId(), video.fileSize());
case VideoNote videoNote -> new TelegramFile(videoNote.fileId(), videoNote.fileSize());
default -> TelegramFile.NOT_SUPPORTED;
})
.orElse(null);
}

private Optional<?> getMessageMedia() {
return Stream.of(message.photo(), message.document(), message.sticker(),
return Stream.of(message.livePhoto(), message.photo(), message.document(), message.sticker(),
message.video(), message.videoNote(),
message.audio(), message.voice())
.filter(Objects::nonNull)
Expand All @@ -56,20 +58,10 @@ private TelegramFile getBestPhoto(PhotoSize[] photos) {
return Arrays.stream(photos)
.map(photo -> new TelegramFile(photo.fileId(), photo.fileSize()))
.filter(TelegramFile::canBeDownloaded)
.max(comparing(TelegramFile::size))
.max(comparing(TelegramFile::sizeValue))
.orElse(TelegramFile.TOO_LARGE);
}

private TelegramFile getVideo(Video video) {
var id = video.fileId();
var fileSize = video.fileSize();
if (fileSize == null) {
return new TelegramFile(id);
} else {
return new TelegramFile(id, fileSize);
}
}

public long getChatId() {
return message.chat().id();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ public final class MockResponses {
chat: {
id: 1
},
sticker: {
document: {
file_id: "valid.gif",
file_size: 200000
}
Expand All @@ -271,6 +271,42 @@ public final class MockResponses {
}
""").build();

static final MockResponse LIVE_PHOTO_FILE = new MockResponse.Builder().body("""
{
ok: true,
result: [
{
update_id: 1,
message: {
message_id: 1,
from: {
id: 123456
},
chat: {
id: 1
},
photo: [
{
file_id: "first_frame",
file_size: 200000
}
],
live_photo: {
file_id: "valid_live_photo",
file_size: 200000,
photo: [
{
file_id: "first_frame",
file_size: 200000
}
]
}
}
}
]
}
""").build();

static final MockResponse DOCUMENT = new MockResponse.Builder().body("""
{
ok: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,31 @@ void convertedGif() throws Exception {
}
}

@Test
void convertedLivePhoto() throws Exception {
server.enqueue(MockResponses.LIVE_PHOTO_FILE);
server.enqueue(MockResponses.fileInfo("valid_live_photo"));
server.enqueue(MockResponses.fileDownload("valid_live_photo"));

try (var _ = runBot()) {
var getUpdates = server.takeRequest();
assertEquals("/api/token/getUpdates", getUpdates.getTarget());

var getFile = server.takeRequest();
assertEquals("/api/token/getFile", getFile.getTarget());
assertNotNull(getFile.getBody());
assertEquals("file_id=valid_live_photo", getFile.getBody().utf8());

var download = server.takeRequest();
assertEquals("/files/token/valid_live_photo", download.getTarget());

var sendDocument = server.takeRequest();
assertEquals("/api/token/sendDocument", sendDocument.getTarget());
assertNotNull(sendDocument.getBody());
assertThat(sendDocument.getBody().utf8(), containsString(Answer.FILE_READY.getText()));
}
}

@Test
void documentNotSupported() throws Exception {
server.enqueue(MockResponses.DOCUMENT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@ void convertAviVideo() throws Exception {
assertVideoConsistency(result, 512, 512, 30F, 2.966F);
}

@Test
@Tag(Tags.VIDEO)
void convertLivePhoto() throws Exception {
var livePhoto = loadResource("valid_live_photo");
var result = MediaHelper.convert(livePhoto);

assertVideoConsistency(result, 384, 512, 30F, 2.966F);
}

@Test
@Tag(Tags.VIDEO)
void noVideoConversionNeeded() throws Exception {
Expand Down
Binary file added src/test/resources/valid_live_photo
Binary file not shown.
Loading