#1 temporary store fileId in RAM
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2021-09-12 21:04:55 +03:00
parent 2103d03611
commit 02c5ef32fa
5 changed files with 245 additions and 24 deletions

View File

@@ -4,6 +4,7 @@ import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@Getter @Getter
@@ -25,4 +26,6 @@ public class Media {
private Integer height; private Integer height;
private Consumer<String> fileIdConsumer;
} }

View File

@@ -0,0 +1,85 @@
package ru.penkrat.stbf.common.screen;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ru.penkrat.stbf.api.Keyboard;
import ru.penkrat.stbf.api.Media;
import ru.penkrat.stbf.api.Screen;
import ru.penkrat.stbf.api.ScreenProperties;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Supplier;
@Slf4j
@RequiredArgsConstructor
public class RamFileIdStorageMediaScreen implements Screen {
private static final Map<String, String> STORAGE = new ConcurrentHashMap<>();
private final Screen wrapped;
private Media wrappedMedia;
@Override
public Media getMedia() {
if (wrapped.getMedia() == null) {
return null;
}
if (wrappedMedia != null) {
return wrappedMedia;
}
final String url = wrapped.getMedia().getUrl();
wrappedMedia = Media.builder()
.data(getData(url))
.url(getUrl(url))
.fileId(STORAGE.get(url))
.fileIdConsumer(saveFileId(url))
.mediaType(wrapped.getMedia().getMediaType())
.duration(wrapped.getMedia().getDuration())
.height(wrapped.getMedia().getHeight())
.width(wrapped.getMedia().getWidth())
.duration(wrapped.getMedia().getDuration())
.build();
return wrappedMedia;
}
protected String getUrl(String url) {
return STORAGE.containsKey(url) ? null : url;
}
protected Supplier<byte[]> getData(String url) {
return null;
}
@Override
public String getText() {
return wrapped.getText();
}
@Override
public Keyboard getKeyboard() {
return wrapped.getKeyboard();
}
@Override
public ScreenProperties getScreenProperties() {
return wrapped.getScreenProperties();
}
private Consumer<String> saveFileId(String srcUrl) {
return fileId -> {
if (STORAGE.containsKey(srcUrl)) {
return;
}
log.debug("Store {} as {}", srcUrl, fileId);
STORAGE.put(srcUrl, fileId);
wrappedMedia = null;
};
}
}

View File

@@ -11,6 +11,7 @@ import com.pengrad.telegrambot.request.AbstractSendRequest;
import com.pengrad.telegrambot.request.DeleteMessage; import com.pengrad.telegrambot.request.DeleteMessage;
import com.pengrad.telegrambot.request.EditMessageText; import com.pengrad.telegrambot.request.EditMessageText;
import com.pengrad.telegrambot.request.SendDocument; import com.pengrad.telegrambot.request.SendDocument;
import com.pengrad.telegrambot.response.SendResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import ru.penkrat.stbf.api.BotResponse; import ru.penkrat.stbf.api.BotResponse;
@@ -48,7 +49,8 @@ public class BotResponseImpl implements BotResponse {
} }
} }
telegramBot.execute(sendMessage); final SendResponse sendResponse = telegramBot.execute(sendMessage);
SendMethodUtils.processResponse(screen, sendResponse);
} }
@Override @Override

View File

@@ -1,16 +1,24 @@
package ru.penkrat.stbf.impl.pengrad; package ru.penkrat.stbf.impl.pengrad;
import com.pengrad.telegrambot.model.Message;
import com.pengrad.telegrambot.model.request.ParseMode; import com.pengrad.telegrambot.model.request.ParseMode;
import com.pengrad.telegrambot.request.AbstractSendRequest; import com.pengrad.telegrambot.request.AbstractSendRequest;
import com.pengrad.telegrambot.request.SendAnimation;
import com.pengrad.telegrambot.request.SendAudio;
import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.request.SendMessage;
import com.pengrad.telegrambot.request.SendPhoto; import com.pengrad.telegrambot.request.SendPhoto;
import com.pengrad.telegrambot.request.SendVideo; import com.pengrad.telegrambot.request.SendVideo;
import com.pengrad.telegrambot.request.SendVoice;
import com.pengrad.telegrambot.response.SendResponse;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import ru.penkrat.stbf.api.Media; import ru.penkrat.stbf.api.Media;
import ru.penkrat.stbf.api.Screen; import ru.penkrat.stbf.api.Screen;
import java.util.function.Function; import java.util.function.BiFunction;
import java.util.function.Consumer;
@UtilityClass @UtilityClass
class SendMethodUtils { class SendMethodUtils {
@@ -19,23 +27,51 @@ class SendMethodUtils {
if (isMedia(screen)) { if (isMedia(screen)) {
final Media media = screen.getMedia(); final Media media = screen.getMedia();
switch (media.getMediaType()) { switch (media.getMediaType()) {
case ANIMATION:
return Setter.to(createSendAnimation(chatId, media))
.setNotNUll(SendAnimation::caption, screen.getText())
.setNotNUll(SendAnimation::width, media.getWidth())
.setNotNUll(SendAnimation::height, media.getHeight())
.setNotNUll(SendAnimation::duration, media.getDuration())
.set(SendAnimation::parseMode, screen.getScreenProperties().isParseModeHtml()
? ParseMode.HTML
: ParseMode.MarkdownV2)
.get();
case AUDIO:
return Setter.to(createSendAudio(chatId, media))
.setNotNUll(SendAudio::caption, screen.getText())
.setNotNUll(SendAudio::duration, media.getDuration())
.set(SendAudio::parseMode, screen.getScreenProperties().isParseModeHtml()
? ParseMode.HTML
: ParseMode.MarkdownV2)
.get();
case PHOTO: case PHOTO:
final SendPhoto sendPhoto = new SendPhoto(chatId, media.getUrl()); return Setter.to(createSendPhoto(chatId, media))
apply(sendPhoto, sendPhoto::caption, screen.getText()); .setNotNUll(SendPhoto::caption, screen.getText())
sendPhoto.parseMode(screen.getScreenProperties().isParseModeHtml() .set(SendPhoto::parseMode, screen.getScreenProperties().isParseModeHtml()
? ParseMode.HTML ? ParseMode.HTML
: ParseMode.MarkdownV2); : ParseMode.MarkdownV2)
return sendPhoto; .get();
case VIDEO: case VIDEO:
final SendVideo sendVideo = new SendVideo(chatId, media.getUrl()); return Setter.to(createSendVideo(chatId, media))
apply(sendVideo, sendVideo::caption, screen.getText()); .setNotNUll(SendVideo::caption, screen.getText())
apply(sendVideo, sendVideo::width, media.getWidth()); .setNotNUll(SendVideo::width, media.getWidth())
apply(sendVideo, sendVideo::height, media.getHeight()); .setNotNUll(SendVideo::height, media.getHeight())
apply(sendVideo, sendVideo::duration, media.getDuration()); .setNotNUll(SendVideo::duration, media.getDuration())
sendVideo.parseMode(screen.getScreenProperties().isParseModeHtml() .set(SendVideo::parseMode, screen.getScreenProperties().isParseModeHtml()
? ParseMode.HTML ? ParseMode.HTML
: ParseMode.MarkdownV2); : ParseMode.MarkdownV2)
return sendVideo; .get();
case VOICE:
return Setter.to(createSendVoice(chatId, media))
.setNotNUll(SendVoice::caption, screen.getText())
.setNotNUll(SendVoice::duration, media.getDuration())
.set(SendVoice::parseMode, screen.getScreenProperties().isParseModeHtml()
? ParseMode.HTML
: ParseMode.MarkdownV2)
.get();
default:
throw new IllegalStateException("Unsupported media type " + media.getMediaType());
} }
} }
@@ -45,14 +81,106 @@ class SendMethodUtils {
.disableNotification(screen.getScreenProperties().isDisableNotification()); .disableNotification(screen.getScreenProperties().isDisableNotification());
} }
public static void processResponse(Screen screen, SendResponse sendResponse) {
if (isMedia(screen)) {
final Consumer<String> fileIdConsumer = screen.getMedia().getFileIdConsumer();
if (fileIdConsumer != null) {
final Message message = sendResponse.message();
if (message.animation() != null)
fileIdConsumer.accept(message.animation().fileId());
else if (message.audio() != null)
fileIdConsumer.accept(message.audio().fileId());
else if (message.photo() != null && message.photo().length > 0)
fileIdConsumer.accept(message.photo()[0].fileId());
else if (message.video() != null)
fileIdConsumer.accept(message.video().fileId());
else if (message.voice() != null)
fileIdConsumer.accept(message.voice().fileId());
}
}
}
@NotNull
private SendVoice createSendVoice(@NotNull Object chatId, Media media) {
if (media.getData() != null) {
return new SendVoice(chatId, media.getData().get());
}
if (media.getFileId() != null) {
return new SendVoice(chatId, media.getFileId());
}
return new SendVoice(chatId, media.getUrl());
}
@NotNull
private SendVideo createSendVideo(@NotNull Object chatId, Media media) {
if (media.getData() != null) {
return new SendVideo(chatId, media.getData().get());
}
if (media.getFileId() != null) {
return new SendVideo(chatId, media.getFileId());
}
return new SendVideo(chatId, media.getUrl());
}
@NotNull
private SendAudio createSendAudio(@NotNull Object chatId, Media media) {
if (media.getData() != null) {
return new SendAudio(chatId, media.getData().get());
}
if (media.getFileId() != null) {
return new SendAudio(chatId, media.getFileId());
}
return new SendAudio(chatId, media.getUrl());
}
@NotNull
private SendAnimation createSendAnimation(@NotNull Object chatId, Media media) {
if (media.getData() != null) {
return new SendAnimation(chatId, media.getData().get());
}
if (media.getFileId() != null) {
return new SendAnimation(chatId, media.getFileId());
}
return new SendAnimation(chatId, media.getUrl());
}
@NotNull
private SendPhoto createSendPhoto(@NotNull Object chatId, Media media) {
if (media.getData() != null) {
return new SendPhoto(chatId, media.getData().get());
}
if (media.getFileId() != null) {
return new SendPhoto(chatId, media.getFileId());
}
return new SendPhoto(chatId, media.getUrl());
}
private boolean isMedia(Screen screen) { private boolean isMedia(Screen screen) {
return screen.getMedia() != null; return screen.getMedia() != null;
} }
private <T, V> T apply(T target, Function<V, T> setter, V value) {
@RequiredArgsConstructor(staticName = "to")
private static class Setter<T> {
private final T target;
<V> Setter<T> setNotNUll(BiFunction<T, V, T> setter, V value) {
if (value != null) { if (value != null) {
setter.apply(value); setter.apply(target, value);
} }
return this;
}
<V> Setter<T> set(BiFunction<T, V, T> setter, V value) {
setter.apply(target, value);
return this;
}
T get() {
return target; return target;
} }
}
} }

View File

@@ -9,6 +9,7 @@ import ru.penkrat.stbf.api.KeyboardBuilder;
import ru.penkrat.stbf.api.Media; import ru.penkrat.stbf.api.Media;
import ru.penkrat.stbf.api.Screen; import ru.penkrat.stbf.api.Screen;
import ru.penkrat.stbf.common.screen.MediaScreen; import ru.penkrat.stbf.common.screen.MediaScreen;
import ru.penkrat.stbf.common.screen.RamFileIdStorageMediaScreen;
import ru.penkrat.stbf.common.screen.TextScreen; import ru.penkrat.stbf.common.screen.TextScreen;
import ru.penkrat.stbf.templates.ActionResolver; import ru.penkrat.stbf.templates.ActionResolver;
import ru.penkrat.stbf.templates.KeyboardProvider; import ru.penkrat.stbf.templates.KeyboardProvider;
@@ -45,7 +46,8 @@ class FlowScreenResolverDelegate implements ScreenResolver {
if (StringUtils.isNotEmpty(item.getMediaRef())) { if (StringUtils.isNotEmpty(item.getMediaRef())) {
final Media media = mediaResolver.getMedia(item.getMediaRef()); final Media media = mediaResolver.getMedia(item.getMediaRef());
return new MediaScreen(item.getText(), media, buildKeyboard(item.getKeyboard(), null)); final MediaScreen mediaScreen = new MediaScreen(item.getText(), media, buildKeyboard(item.getKeyboard(), null));
return new RamFileIdStorageMediaScreen(mediaScreen);
} }
return new TextScreen(item.getText(), buildKeyboard(item.getKeyboard(), null)); return new TextScreen(item.getText(), buildKeyboard(item.getKeyboard(), null));
@@ -57,8 +59,9 @@ class FlowScreenResolverDelegate implements ScreenResolver {
if (StringUtils.isNotEmpty(item.getMediaRef())) { if (StringUtils.isNotEmpty(item.getMediaRef())) {
final Media media = mediaResolver.getMedia(item.getMediaRef()); final Media media = mediaResolver.getMedia(item.getMediaRef());
return new MediaScreen(templateRenderer.render(item.getText(), context), media, final MediaScreen mediaScreen = new MediaScreen(templateRenderer.render(item.getText(), context), media,
resolveKeyboard(item.getKeyboard(), context)); resolveKeyboard(item.getKeyboard(), context));
return new RamFileIdStorageMediaScreen(mediaScreen);
} }
return new TextScreen(templateRenderer.render(item.getText(), context), return new TextScreen(templateRenderer.render(item.getText(), context),