diff --git a/src/main/java/com/github/stickerifier/stickerify/telegram/model/TelegramFile.java b/src/main/java/com/github/stickerifier/stickerify/telegram/model/TelegramFile.java index bff1d84e..1d07c10b 100644 --- a/src/main/java/com/github/stickerifier/stickerify/telegram/model/TelegramFile.java +++ b/src/main/java/com/github/stickerifier/stickerify/telegram/model/TelegramFile.java @@ -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; } } diff --git a/src/main/java/com/github/stickerifier/stickerify/telegram/model/TelegramRequest.java b/src/main/java/com/github/stickerifier/stickerify/telegram/model/TelegramRequest.java index 85b8a268..432607c4 100644 --- a/src/main/java/com/github/stickerifier/stickerify/telegram/model/TelegramRequest.java +++ b/src/main/java/com/github/stickerifier/stickerify/telegram/model/TelegramRequest.java @@ -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; @@ -34,10 +35,11 @@ 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; }) @@ -45,7 +47,7 @@ public record TelegramRequest(Message message) { } 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) @@ -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(); } diff --git a/src/test/java/com/github/stickerifier/stickerify/bot/MockResponses.java b/src/test/java/com/github/stickerifier/stickerify/bot/MockResponses.java index 88d6d4d3..bd6ab1b9 100644 --- a/src/test/java/com/github/stickerifier/stickerify/bot/MockResponses.java +++ b/src/test/java/com/github/stickerifier/stickerify/bot/MockResponses.java @@ -261,7 +261,7 @@ public final class MockResponses { chat: { id: 1 }, - sticker: { + document: { file_id: "valid.gif", file_size: 200000 } @@ -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, diff --git a/src/test/java/com/github/stickerifier/stickerify/bot/StickerifyTest.java b/src/test/java/com/github/stickerifier/stickerify/bot/StickerifyTest.java index 0a58d1f4..83471ff9 100644 --- a/src/test/java/com/github/stickerifier/stickerify/bot/StickerifyTest.java +++ b/src/test/java/com/github/stickerifier/stickerify/bot/StickerifyTest.java @@ -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); diff --git a/src/test/java/com/github/stickerifier/stickerify/media/MediaHelperTest.java b/src/test/java/com/github/stickerifier/stickerify/media/MediaHelperTest.java index 174ad277..ebc53930 100644 --- a/src/test/java/com/github/stickerifier/stickerify/media/MediaHelperTest.java +++ b/src/test/java/com/github/stickerifier/stickerify/media/MediaHelperTest.java @@ -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 { diff --git a/src/test/resources/valid_live_photo b/src/test/resources/valid_live_photo new file mode 100644 index 00000000..fa99bd28 Binary files /dev/null and b/src/test/resources/valid_live_photo differ