mirror of
https://github.com/aNNiMON/ffmpegbot
synced 2024-09-19 22:54:20 +03:00
Admin command to manage sessions
This commit is contained in:
parent
856cd15358
commit
6e58de0049
@ -40,7 +40,7 @@ public class MainBotHandler extends BotHandler {
|
||||
commands.registerBundle(mediaProcessingBundle);
|
||||
commands.registerBundle(new InputParametersBundle(sessions));
|
||||
commands.registerBundle(new YtDlpCommandBundle(sessions));
|
||||
commands.registerBundle(new AdminCommandBundle());
|
||||
commands.registerBundle(new AdminCommandBundle(sessions));
|
||||
commands.register(new HelpCommand());
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ public class HelpCommand implements TextCommand {
|
||||
<b>yt-dlp</b>
|
||||
/dl link [format] — download a media using yt-dlp
|
||||
<code>link</code> — a link to download (it must be supported by yt-dlp)
|
||||
<code>format</code> — (optional) a download format. Can be "audio", "240", "360", "480", "720" or "1080"
|
||||
<code>format</code> — (optional) a download format. Can be "best", "audio", "240", "360", "480", "720" or "1080"
|
||||
""".stripIndent()).enableHtml().callAsync(ctx.sender);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.annimon.ffmpegbot.commands.admin;
|
||||
|
||||
import com.annimon.ffmpegbot.session.Sessions;
|
||||
import com.annimon.tgbotsmodule.commands.CommandBundle;
|
||||
import com.annimon.tgbotsmodule.commands.CommandRegistry;
|
||||
import com.annimon.tgbotsmodule.commands.authority.For;
|
||||
@ -7,9 +8,17 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class AdminCommandBundle implements CommandBundle<For> {
|
||||
|
||||
private final Sessions sessions;
|
||||
|
||||
public AdminCommandBundle(Sessions sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(@NotNull CommandRegistry commands) {
|
||||
commands.register(new RunCommand());
|
||||
commands.register(new ClearCommand());
|
||||
commands.register(new SessionsCommand(sessions));
|
||||
commands.register(new SessionsClearCommand(sessions));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
package com.annimon.ffmpegbot.commands.admin;
|
||||
|
||||
import com.annimon.ffmpegbot.Permissions;
|
||||
import com.annimon.ffmpegbot.session.Sessions;
|
||||
import com.annimon.tgbotsmodule.commands.CallbackQueryCommand;
|
||||
import com.annimon.tgbotsmodule.commands.authority.For;
|
||||
import com.annimon.tgbotsmodule.commands.context.CallbackQueryContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class SessionsClearCommand implements CallbackQueryCommand {
|
||||
static final String CALLBACK_NAME = "sessions_clear";
|
||||
private final Sessions sessions;
|
||||
|
||||
public SessionsClearCommand(Sessions sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String command() {
|
||||
return CALLBACK_NAME;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public EnumSet<For> authority() {
|
||||
return Permissions.SUPERUSERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull CallbackQueryContext ctx) {
|
||||
final int size = sessions.getSize();
|
||||
sessions.clear();
|
||||
ctx.editMessage("%d sessions cleared".formatted(size))
|
||||
.setReplyMarkup(null)
|
||||
.callAsync(ctx.sender);
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.annimon.ffmpegbot.commands.admin;
|
||||
|
||||
import com.annimon.ffmpegbot.Permissions;
|
||||
import com.annimon.ffmpegbot.TextUtils;
|
||||
import com.annimon.ffmpegbot.session.MediaSession;
|
||||
import com.annimon.ffmpegbot.session.Session;
|
||||
import com.annimon.ffmpegbot.session.Sessions;
|
||||
import com.annimon.ffmpegbot.session.YtDlpSession;
|
||||
import com.annimon.tgbotsmodule.commands.TextCommand;
|
||||
import com.annimon.tgbotsmodule.commands.authority.For;
|
||||
import com.annimon.tgbotsmodule.commands.context.MessageContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SessionsCommand implements TextCommand {
|
||||
private final Sessions sessions;
|
||||
|
||||
public SessionsCommand(Sessions sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String command() {
|
||||
return "/sessions";
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public EnumSet<For> authority() {
|
||||
return Permissions.SUPERUSERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull MessageContext ctx) {
|
||||
final int size = sessions.getSize();
|
||||
if (size == 0) {
|
||||
ctx.replyToMessage("No sessions found").callAsync(ctx.sender);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ctx.argument(1).equals("clear")) {
|
||||
sessions.clear();
|
||||
ctx.replyToMessage("%d sessions cleared".formatted(size)).callAsync(ctx.sender);
|
||||
} else {
|
||||
final var sessionsInfo = sessions.sessions()
|
||||
.sorted(Comparator.comparing(Session::getInstant).reversed())
|
||||
.map(this::formatSession)
|
||||
.limit(30)
|
||||
.collect(Collectors.joining("\n"));
|
||||
ctx.replyToMessage(("%d active sessions:\n%s").formatted(size, sessionsInfo))
|
||||
.disableWebPagePreview()
|
||||
.setSingleRowInlineKeyboard(InlineKeyboardButton.builder()
|
||||
.text("Clear").callbackData(SessionsClearCommand.CALLBACK_NAME)
|
||||
.build())
|
||||
.callAsync(ctx.sender);
|
||||
}
|
||||
}
|
||||
|
||||
private String formatSession(Session session) {
|
||||
long chatId = session.getChatId();
|
||||
if (session instanceof MediaSession ms) {
|
||||
return String.join(" ", str(chatId), str(ms.getOriginalFilename()),
|
||||
str(ms.getFileSize(), TextUtils::readableFileSize),
|
||||
str(ms.getDuration(), TextUtils::readableDuration));
|
||||
} else if (session instanceof YtDlpSession ys) {
|
||||
return String.join(" ", str(chatId), str(ys.getUrl()));
|
||||
}
|
||||
return str(chatId);
|
||||
}
|
||||
|
||||
private String str(Object obj) {
|
||||
return obj == null ? "" : Objects.toString(obj);
|
||||
}
|
||||
|
||||
private <T> String str(T obj, Function<? super T, String> func) {
|
||||
return obj == null ? "" : str(func.apply(obj));
|
||||
}
|
||||
}
|
@ -54,14 +54,26 @@ public final class MediaSession extends Session {
|
||||
this.originalFilename = originalFilename;
|
||||
}
|
||||
|
||||
public String getOriginalFilename() {
|
||||
return originalFilename;
|
||||
}
|
||||
|
||||
public void setFileSize(Long fileSize) {
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
public Long getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
public void setDuration(Integer duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public Integer getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setResolution(Integer width, Integer height) {
|
||||
if (width == null && height == null) {
|
||||
this.resolution = null;
|
||||
|
@ -2,6 +2,7 @@ package com.annimon.ffmpegbot.session;
|
||||
|
||||
import com.annimon.ffmpegbot.parameters.InputParameters;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public abstract sealed class Session permits MediaSession, YtDlpSession {
|
||||
@ -10,6 +11,8 @@ public abstract sealed class Session permits MediaSession, YtDlpSession {
|
||||
protected int messageId;
|
||||
// Parameters
|
||||
protected final InputParameters inputParams = new InputParameters();
|
||||
// Meta
|
||||
private final Instant instant = Instant.now();
|
||||
|
||||
public long getChatId() {
|
||||
return chatId;
|
||||
@ -31,5 +34,9 @@ public abstract sealed class Session permits MediaSession, YtDlpSession {
|
||||
return inputParams;
|
||||
}
|
||||
|
||||
public Instant getInstant() {
|
||||
return instant;
|
||||
}
|
||||
|
||||
abstract StringJoiner describe();
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.annimon.ffmpegbot.session;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Sessions {
|
||||
private final Map<String, Session> sessions;
|
||||
@ -10,6 +11,18 @@ public class Sessions {
|
||||
sessions = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
sessions.clear();
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return sessions.size();
|
||||
}
|
||||
|
||||
public Stream<Session> sessions() {
|
||||
return sessions.values().stream();
|
||||
}
|
||||
|
||||
public Session get(long chatId, long messageId) {
|
||||
return sessions.get(mapKey(chatId, messageId));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user