✨ feat: Log adjustment, AutoDownloadVerticle runs with VIRTUAL_THREAD.
This commit is contained in:
parent
a111795d64
commit
dd19756efb
13 changed files with 99 additions and 56 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
|
# Telegram files log level, ALL < FINEST < FINER < FINE < CONFIG < INFO < WARNING < SEVERE < OFF
|
||||||
|
LOG_LEVEL=INFO
|
||||||
# The root directory of the application
|
# The root directory of the application
|
||||||
APP_ENV=dev
|
APP_ENV=dev
|
||||||
APP_ROOT=
|
APP_ROOT=
|
||||||
|
|
@ -6,3 +7,5 @@ TDLIB_PATH=
|
||||||
|
|
||||||
TELEGRAM_API_ID=
|
TELEGRAM_API_ID=
|
||||||
TELEGRAM_API_HASH=
|
TELEGRAM_API_HASH=
|
||||||
|
# Value 0 corresponds to fatal errors, value 1 corresponds to errors, value 2 corresponds to warnings and debug warnings, value 3 corresponds to informational, value 4 corresponds to debug, value 5 corresponds to verbose debug, value greater than 5 and up to 1023 can be used to enable even more logging.
|
||||||
|
TELEGRAM_LOG_LEVEL=0
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import io.vertx.core.Promise;
|
||||||
import io.vertx.core.json.Json;
|
import io.vertx.core.json.Json;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import org.drinkless.tdlib.TdApi;
|
import org.drinkless.tdlib.TdApi;
|
||||||
|
import telegram.files.repository.FileRecord;
|
||||||
import telegram.files.repository.SettingAutoRecords;
|
import telegram.files.repository.SettingAutoRecords;
|
||||||
import telegram.files.repository.SettingKey;
|
import telegram.files.repository.SettingKey;
|
||||||
|
|
||||||
|
|
@ -27,7 +28,7 @@ public class AutoDownloadVerticle extends AbstractVerticle {
|
||||||
|
|
||||||
private static final int HISTORY_SCAN_INTERVAL = 2 * 60 * 1000;
|
private static final int HISTORY_SCAN_INTERVAL = 2 * 60 * 1000;
|
||||||
|
|
||||||
private static final int MAX_HISTORY_SCAN_TIME = 20 * 1000;
|
private static final int MAX_HISTORY_SCAN_TIME = 10 * 1000;
|
||||||
|
|
||||||
private static final int MAX_WAITING_LENGTH = 30;
|
private static final int MAX_WAITING_LENGTH = 30;
|
||||||
|
|
||||||
|
|
@ -107,7 +108,7 @@ public class AutoDownloadVerticle extends AbstractVerticle {
|
||||||
this.limit = Convert.toInt(message.body());
|
this.limit = Convert.toInt(message.body());
|
||||||
});
|
});
|
||||||
vertx.eventBus().consumer(EventEnum.MESSAGE_RECEIVED.address(), message -> {
|
vertx.eventBus().consumer(EventEnum.MESSAGE_RECEIVED.address(), message -> {
|
||||||
log.debug("Auto download message received: %s".formatted(message.body()));
|
log.trace("Auto download message received: %s".formatted(message.body()));
|
||||||
this.onNewMessage((JsonObject) message.body());
|
this.onNewMessage((JsonObject) message.body());
|
||||||
});
|
});
|
||||||
return Future.succeededFuture();
|
return Future.succeededFuture();
|
||||||
|
|
@ -128,7 +129,9 @@ public class AutoDownloadVerticle extends AbstractVerticle {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addHistoryMessage(SettingAutoRecords.Item auto, long currentTimeMillis) {
|
private void addHistoryMessage(SettingAutoRecords.Item auto, long currentTimeMillis) {
|
||||||
|
log.debug("Start scan history! TelegramId: %d ChatId: %d FileType: %s".formatted(auto.telegramId, auto.chatId, auto.nextFileType));
|
||||||
if (System.currentTimeMillis() - currentTimeMillis > MAX_HISTORY_SCAN_TIME || isExceedLimit(auto.telegramId)) {
|
if (System.currentTimeMillis() - currentTimeMillis > MAX_HISTORY_SCAN_TIME || isExceedLimit(auto.telegramId)) {
|
||||||
|
log.debug("Scan history end! TelegramId: %d ChatId: %d".formatted(auto.telegramId, auto.chatId));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (StrUtil.isBlank(auto.nextFileType)) {
|
if (StrUtil.isBlank(auto.nextFileType)) {
|
||||||
|
|
@ -140,36 +143,39 @@ public class AutoDownloadVerticle extends AbstractVerticle {
|
||||||
searchChatMessages.fromMessageId = auto.nextFromMessageId;
|
searchChatMessages.fromMessageId = auto.nextFromMessageId;
|
||||||
searchChatMessages.limit = Math.min(MAX_WAITING_LENGTH, 100);
|
searchChatMessages.limit = Math.min(MAX_WAITING_LENGTH, 100);
|
||||||
searchChatMessages.filter = TdApiHelp.getSearchMessagesFilter(auto.nextFileType);
|
searchChatMessages.filter = TdApiHelp.getSearchMessagesFilter(auto.nextFileType);
|
||||||
telegramVerticle.execute(searchChatMessages)
|
TdApi.FoundChatMessages foundChatMessages = Future.await(telegramVerticle.execute(searchChatMessages)
|
||||||
.onSuccess(foundChatMessages -> {
|
.onFailure(r -> log.error("Search chat messages failed! TelegramId: %d ChatId: %d".formatted(auto.telegramId, auto.chatId), r))
|
||||||
if (foundChatMessages.messages.length == 0) {
|
);
|
||||||
int nextTypeIndex = FILE_TYPE_ORDER.indexOf(auto.nextFileType) + 1;
|
if (foundChatMessages == null) {
|
||||||
if (nextTypeIndex < FILE_TYPE_ORDER.size()) {
|
return;
|
||||||
String originalType = auto.nextFileType;
|
}
|
||||||
auto.nextFileType = FILE_TYPE_ORDER.get(nextTypeIndex);
|
if (foundChatMessages.messages.length == 0) {
|
||||||
auto.nextFromMessageId = 0;
|
int nextTypeIndex = FILE_TYPE_ORDER.indexOf(auto.nextFileType) + 1;
|
||||||
log.debug("%s No more %s files found! Switch to %s".formatted(auto.uniqueKey(), originalType, auto.nextFileType));
|
if (nextTypeIndex < FILE_TYPE_ORDER.size()) {
|
||||||
|
String originalType = auto.nextFileType;
|
||||||
|
auto.nextFileType = FILE_TYPE_ORDER.get(nextTypeIndex);
|
||||||
|
auto.nextFromMessageId = 0;
|
||||||
|
log.debug("%s No more %s files found! Switch to %s".formatted(auto.uniqueKey(), originalType, auto.nextFileType));
|
||||||
|
addHistoryMessage(auto, currentTimeMillis);
|
||||||
|
} else {
|
||||||
|
log.debug("%s No more history files found! TelegramId: %d ChatId: %d".formatted(auto.uniqueKey(), auto.telegramId, auto.chatId));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DataVerticle.fileRepository.getFilesByUniqueId(TdApiHelp.getFileUniqueIds(Arrays.asList(foundChatMessages.messages)))
|
||||||
|
.onSuccess(existFiles -> {
|
||||||
|
List<TdApi.Message> messages = Stream.of(foundChatMessages.messages)
|
||||||
|
.filter(message -> !existFiles.containsKey(TdApiHelp.getFileUniqueId(message)))
|
||||||
|
.toList();
|
||||||
|
if (CollUtil.isEmpty(messages)) {
|
||||||
|
auto.nextFromMessageId = foundChatMessages.nextFromMessageId;
|
||||||
addHistoryMessage(auto, currentTimeMillis);
|
addHistoryMessage(auto, currentTimeMillis);
|
||||||
|
} else if (addWaitingDownloadMessages(auto.telegramId, messages, false)) {
|
||||||
|
auto.nextFromMessageId = foundChatMessages.nextFromMessageId;
|
||||||
} else {
|
} else {
|
||||||
log.debug("%s No more history files found! TelegramId: %d ChatId: %d".formatted(auto.uniqueKey(), auto.telegramId, auto.chatId));
|
addHistoryMessage(auto, currentTimeMillis);
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
DataVerticle.fileRepository.getFilesByUniqueId(TdApiHelp.getFileUniqueIds(Arrays.asList(foundChatMessages.messages)))
|
}
|
||||||
.onSuccess(existFiles -> {
|
|
||||||
List<TdApi.Message> messages = Stream.of(foundChatMessages.messages)
|
|
||||||
.filter(message -> !existFiles.containsKey(TdApiHelp.getFileUniqueId(message)))
|
|
||||||
.toList();
|
|
||||||
if (CollUtil.isEmpty(messages)) {
|
|
||||||
auto.nextFromMessageId = foundChatMessages.nextFromMessageId;
|
|
||||||
addHistoryMessage(auto, currentTimeMillis);
|
|
||||||
} else if (addWaitingDownloadMessages(auto.telegramId, messages, false)) {
|
|
||||||
auto.nextFromMessageId = foundChatMessages.nextFromMessageId;
|
|
||||||
} else {
|
|
||||||
addHistoryMessage(auto, currentTimeMillis);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isExceedLimit(long telegramId) {
|
private boolean isExceedLimit(long telegramId) {
|
||||||
|
|
@ -178,11 +184,8 @@ public class AutoDownloadVerticle extends AbstractVerticle {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getSurplusSize(long telegramId) {
|
private int getSurplusSize(long telegramId) {
|
||||||
TelegramVerticle telegramVerticle = this.getTelegramVerticle(telegramId);
|
Integer downloading = Future.await(DataVerticle.fileRepository.countByStatus(telegramId, FileRecord.DownloadStatus.downloading));
|
||||||
Integer downloading = telegramVerticle.getDownloadStatistics()
|
return downloading == null ? limit : Math.max(0, limit - downloading);
|
||||||
.map(statistics -> statistics.getInteger("downloading"))
|
|
||||||
.result();
|
|
||||||
return downloading == null ? limit : Math.min(0, limit - downloading);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addWaitingDownloadMessages(long telegramId, List<TdApi.Message> messages, boolean force) {
|
private boolean addWaitingDownloadMessages(long telegramId, List<TdApi.Message> messages, boolean force) {
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,12 @@ import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class Config {
|
public class Config {
|
||||||
|
public static final String LOG_LEVEL = StrUtil.blankToDefault(System.getenv("LOG_LEVEL"), "INFO");
|
||||||
|
|
||||||
public static final String APP_ENV = StrUtil.blankToDefault(System.getenv("APP_ENV"), "prod");
|
public static final String APP_ENV = StrUtil.blankToDefault(System.getenv("APP_ENV"), "prod");
|
||||||
|
|
||||||
public static final String APP_ROOT = System.getenv("APP_ROOT");
|
public static final String APP_ROOT = System.getenv("APP_ROOT");
|
||||||
|
|
@ -17,6 +21,10 @@ public class Config {
|
||||||
|
|
||||||
public static final String TELEGRAM_API_HASH = System.getenv("TELEGRAM_API_HASH");
|
public static final String TELEGRAM_API_HASH = System.getenv("TELEGRAM_API_HASH");
|
||||||
|
|
||||||
|
public static final int TELEGRAM_LOG_LEVEL = Convert.toInt(System.getenv("TELEGRAM_LOG_LEVEL"), 0);
|
||||||
|
|
||||||
|
private static Level logLevel;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if (APP_ENV == null) {
|
if (APP_ENV == null) {
|
||||||
throw new RuntimeException("APP_ENV is not set");
|
throw new RuntimeException("APP_ENV is not set");
|
||||||
|
|
@ -31,6 +39,15 @@ public class Config {
|
||||||
throw new RuntimeException("TELEGRAM_API_HASH is not set");
|
throw new RuntimeException("TELEGRAM_API_HASH is not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
logLevel = Level.parse(Config.LOG_LEVEL);
|
||||||
|
System.out.println("Setting telegram.files log level to " + logLevel);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
System.err.println("Invalid log level [" + Config.LOG_LEVEL + "], using default INFO.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.getLogger("telegram.files").setLevel(logLevel);
|
||||||
|
|
||||||
if (!FileUtil.exist(APP_ROOT)) {
|
if (!FileUtil.exist(APP_ROOT)) {
|
||||||
FileUtil.mkdir(APP_ROOT);
|
FileUtil.mkdir(APP_ROOT);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,9 @@ public class HttpVerticle extends AbstractVerticle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Void> initAutoDownloadVerticle() {
|
public Future<Void> initAutoDownloadVerticle() {
|
||||||
return vertx.deployVerticle(new AutoDownloadVerticle(), new DeploymentOptions().setThreadingModel(ThreadingModel.WORKER))
|
return vertx.deployVerticle(new AutoDownloadVerticle(), new DeploymentOptions()
|
||||||
|
.setThreadingModel(ThreadingModel.VIRTUAL_THREAD)
|
||||||
|
)
|
||||||
.mapEmpty();
|
.mapEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public class TelegramUpdateHandler implements Client.ResultHandler {
|
||||||
if (onFileUpdated != null)
|
if (onFileUpdated != null)
|
||||||
onFileUpdated.accept((TdApi.UpdateFile) object);
|
onFileUpdated.accept((TdApi.UpdateFile) object);
|
||||||
case TdApi.UpdateFileDownload.CONSTRUCTOR:
|
case TdApi.UpdateFileDownload.CONSTRUCTOR:
|
||||||
log.debug("File download update: %s".formatted(object));
|
log.trace("File download update: %s".formatted(object));
|
||||||
break;
|
break;
|
||||||
case TdApi.UpdateFileDownloads.CONSTRUCTOR:
|
case TdApi.UpdateFileDownloads.CONSTRUCTOR:
|
||||||
if (onFileDownloadsUpdated != null)
|
if (onFileDownloadsUpdated != null)
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ public class TelegramVerticle extends AbstractVerticle {
|
||||||
Client.setLogMessageHandler(0, new LogMessageHandler());
|
Client.setLogMessageHandler(0, new LogMessageHandler());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Client.execute(new TdApi.SetLogVerbosityLevel(0));
|
Client.execute(new TdApi.SetLogVerbosityLevel(Config.TELEGRAM_LOG_LEVEL));
|
||||||
Client.execute(new TdApi.SetLogStream(new TdApi.LogStreamFile("tdlib.log", 1 << 27, false)));
|
Client.execute(new TdApi.SetLogStream(new TdApi.LogStreamFile("tdlib.log", 1 << 27, false)));
|
||||||
} catch (Client.ExecutionException error) {
|
} catch (Client.ExecutionException error) {
|
||||||
throw new IOError(new IOException("Write access to the current directory is required"));
|
throw new IOError(new IOException("Write access to the current directory is required"));
|
||||||
|
|
@ -600,7 +600,7 @@ public class TelegramVerticle extends AbstractVerticle {
|
||||||
request.systemLanguageCode = "en";
|
request.systemLanguageCode = "en";
|
||||||
request.deviceModel = "Telegram Files";
|
request.deviceModel = "Telegram Files";
|
||||||
request.applicationVersion = Start.VERSION;
|
request.applicationVersion = Start.VERSION;
|
||||||
log.debug("[%s] Send SetTdlibParameters: %s".formatted(getRootId(), request));
|
log.trace("[%s] Send SetTdlibParameters: %s".formatted(getRootId(), request));
|
||||||
|
|
||||||
client.send(request, this::handleAuthorizationResult);
|
client.send(request, this::handleAuthorizationResult);
|
||||||
break;
|
break;
|
||||||
|
|
@ -650,7 +650,7 @@ public class TelegramVerticle extends AbstractVerticle {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFileUpdated(TdApi.UpdateFile updateFile) {
|
private void onFileUpdated(TdApi.UpdateFile updateFile) {
|
||||||
log.debug("[%s] Receive file update: %s".formatted(getRootId(), updateFile));
|
log.trace("[%s] Receive file update: %s".formatted(getRootId(), updateFile));
|
||||||
TdApi.File file = updateFile.file;
|
TdApi.File file = updateFile.file;
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
String localPath = null;
|
String localPath = null;
|
||||||
|
|
@ -675,12 +675,12 @@ public class TelegramVerticle extends AbstractVerticle {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFileDownloadsUpdated(TdApi.UpdateFileDownloads updateFileDownloads) {
|
private void onFileDownloadsUpdated(TdApi.UpdateFileDownloads updateFileDownloads) {
|
||||||
log.debug("[%s] Receive file downloads update: %s".formatted(getRootId(), updateFileDownloads));
|
log.trace("[%s] Receive file downloads update: %s".formatted(getRootId(), updateFileDownloads));
|
||||||
sendHttpEvent(EventPayload.build(EventPayload.TYPE_FILE_DOWNLOAD, updateFileDownloads));
|
sendHttpEvent(EventPayload.build(EventPayload.TYPE_FILE_DOWNLOAD, updateFileDownloads));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onMessageReceived(TdApi.Message message) {
|
private void onMessageReceived(TdApi.Message message) {
|
||||||
log.debug("[%s] Receive message: %s".formatted(getRootId(), message));
|
log.trace("[%s] Receive message: %s".formatted(getRootId(), message));
|
||||||
vertx.eventBus().publish(EventEnum.MESSAGE_RECEIVED.address(), JsonObject.of()
|
vertx.eventBus().publish(EventEnum.MESSAGE_RECEIVED.address(), JsonObject.of()
|
||||||
.put("telegramId", telegramRecord.id())
|
.put("telegramId", telegramRecord.id())
|
||||||
.put("chatId", message.chatId)
|
.put("chatId", message.chatId)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ public interface FileRepository {
|
||||||
|
|
||||||
Future<JsonObject> getDownloadStatistics(long telegramId);
|
Future<JsonObject> getDownloadStatistics(long telegramId);
|
||||||
|
|
||||||
|
Future<Integer> countByStatus(long telegramId, FileRecord.DownloadStatus downloadStatus);
|
||||||
|
|
||||||
Future<JsonObject> updateStatus(int fileId,
|
Future<JsonObject> updateStatus(int fileId,
|
||||||
String uniqueId,
|
String uniqueId,
|
||||||
String localPath,
|
String localPath,
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public class FileRepositoryImpl implements FileRepository {
|
||||||
.execute()
|
.execute()
|
||||||
.onComplete(r -> conn.close())
|
.onComplete(r -> conn.close())
|
||||||
.onFailure(err -> log.error("Failed to create table file_record: %s".formatted(err.getMessage())))
|
.onFailure(err -> log.error("Failed to create table file_record: %s".formatted(err.getMessage())))
|
||||||
.onSuccess(ps -> log.debug("Successfully created table: file_record"))
|
.onSuccess(ps -> log.trace("Successfully created table: file_record"))
|
||||||
)
|
)
|
||||||
.mapEmpty();
|
.mapEmpty();
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +61,7 @@ public class FileRepositoryImpl implements FileRepository {
|
||||||
.mapFrom(FileRecord.PARAM_MAPPER)
|
.mapFrom(FileRecord.PARAM_MAPPER)
|
||||||
.execute(fileRecord)
|
.execute(fileRecord)
|
||||||
.map(r -> fileRecord)
|
.map(r -> fileRecord)
|
||||||
.onSuccess(r -> log.debug("Successfully created file record: %s".formatted(fileRecord.id()))
|
.onSuccess(r -> log.trace("Successfully created file record: %s".formatted(fileRecord.id()))
|
||||||
)
|
)
|
||||||
.onFailure(
|
.onFailure(
|
||||||
err -> log.error("Failed to create file record: %s".formatted(err.getMessage()))
|
err -> log.error("Failed to create file record: %s".formatted(err.getMessage()))
|
||||||
|
|
@ -234,6 +234,18 @@ public class FileRepositoryImpl implements FileRepository {
|
||||||
.onFailure(err -> log.error("Failed to get download statistics: %s".formatted(err.getMessage())));
|
.onFailure(err -> log.error("Failed to get download statistics: %s".formatted(err.getMessage())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<Integer> countByStatus(long telegramId, FileRecord.DownloadStatus downloadStatus) {
|
||||||
|
return SqlTemplate
|
||||||
|
.forQuery(pool, """
|
||||||
|
SELECT COUNT(*) FROM file_record WHERE telegram_id = #{telegramId} AND download_status = #{downloadStatus}
|
||||||
|
""")
|
||||||
|
.mapTo(rs -> rs.getInteger(0))
|
||||||
|
.execute(Map.of("telegramId", telegramId, "downloadStatus", downloadStatus.name()))
|
||||||
|
.map(rs -> rs.size() > 0 ? rs.iterator().next() : 0)
|
||||||
|
.onFailure(err -> log.error("Failed to count file record: %s".formatted(err.getMessage())));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<JsonObject> updateStatus(int fileId, String uniqueId, String localPath, FileRecord.DownloadStatus downloadStatus) {
|
public Future<JsonObject> updateStatus(int fileId, String uniqueId, String localPath, FileRecord.DownloadStatus downloadStatus) {
|
||||||
if (StrUtil.isBlank(localPath) && downloadStatus == null) {
|
if (StrUtil.isBlank(localPath) && downloadStatus == null) {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ public class SettingRepositoryImpl implements SettingRepository {
|
||||||
.execute()
|
.execute()
|
||||||
.onComplete(r -> conn.close())
|
.onComplete(r -> conn.close())
|
||||||
.onFailure(err -> log.error("Failed to create table setting_record: %s".formatted(err.getMessage())))
|
.onFailure(err -> log.error("Failed to create table setting_record: %s".formatted(err.getMessage())))
|
||||||
.onSuccess(ps -> log.debug("Successfully created table: setting_record"))
|
.onSuccess(ps -> log.trace("Successfully created table: setting_record"))
|
||||||
)
|
)
|
||||||
.mapEmpty();
|
.mapEmpty();
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ public class SettingRepositoryImpl implements SettingRepository {
|
||||||
.mapFrom(SettingRecord.PARAM_MAPPER)
|
.mapFrom(SettingRecord.PARAM_MAPPER)
|
||||||
.execute(new SettingRecord(key, value))
|
.execute(new SettingRecord(key, value))
|
||||||
.map(r -> new SettingRecord(key, value))
|
.map(r -> new SettingRecord(key, value))
|
||||||
.onSuccess(r -> log.debug("Successfully created or updated setting record: %s".formatted(key)))
|
.onSuccess(r -> log.trace("Successfully created or updated setting record: %s".formatted(key)))
|
||||||
.onFailure(
|
.onFailure(
|
||||||
err -> log.error("Failed to create or update setting record: %s".formatted(err.getMessage()))
|
err -> log.error("Failed to create or update setting record: %s".formatted(err.getMessage()))
|
||||||
);
|
);
|
||||||
|
|
@ -74,7 +74,7 @@ public class SettingRepositoryImpl implements SettingRepository {
|
||||||
.mapTo(SettingRecord.ROW_MAPPER)
|
.mapTo(SettingRecord.ROW_MAPPER)
|
||||||
.execute(Collections.emptyMap())
|
.execute(Collections.emptyMap())
|
||||||
.map(IterUtil::toList)
|
.map(IterUtil::toList)
|
||||||
.onSuccess(r -> log.debug("Successfully fetched setting record for keys: " + keyStr))
|
.onSuccess(r -> log.trace("Successfully fetched setting record for keys: " + keyStr))
|
||||||
.onFailure(
|
.onFailure(
|
||||||
err -> log.error("Failed to fetch setting record: %s".formatted(err.getMessage()))
|
err -> log.error("Failed to fetch setting record: %s".formatted(err.getMessage()))
|
||||||
);
|
);
|
||||||
|
|
@ -95,7 +95,7 @@ public class SettingRepositoryImpl implements SettingRepository {
|
||||||
}
|
}
|
||||||
return key.defaultValue == null ? null : (T) key.defaultValue;
|
return key.defaultValue == null ? null : (T) key.defaultValue;
|
||||||
})
|
})
|
||||||
.onSuccess(r -> log.debug("Successfully fetched setting record for key: " + key))
|
.onSuccess(r -> log.trace("Successfully fetched setting record for key: " + key))
|
||||||
.onFailure(
|
.onFailure(
|
||||||
err -> log.error("Failed to fetch setting record: %s".formatted(err.getMessage()))
|
err -> log.error("Failed to fetch setting record: %s".formatted(err.getMessage()))
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ public class TelegramRepositoryImpl implements TelegramRepository {
|
||||||
.execute()
|
.execute()
|
||||||
.onComplete(r -> conn.close())
|
.onComplete(r -> conn.close())
|
||||||
.onFailure(err -> log.error("Failed to create table telegram_record: %s".formatted(err.getMessage())))
|
.onFailure(err -> log.error("Failed to create table telegram_record: %s".formatted(err.getMessage())))
|
||||||
.onSuccess(ps -> log.debug("Successfully created table: telegram_record"))
|
.onSuccess(ps -> log.trace("Successfully created table: telegram_record"))
|
||||||
)
|
)
|
||||||
.mapEmpty();
|
.mapEmpty();
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ public class TelegramRepositoryImpl implements TelegramRepository {
|
||||||
.mapFrom(TelegramRecord.PARAM_MAPPER)
|
.mapFrom(TelegramRecord.PARAM_MAPPER)
|
||||||
.execute(telegramRecord)
|
.execute(telegramRecord)
|
||||||
.map(r -> telegramRecord)
|
.map(r -> telegramRecord)
|
||||||
.onSuccess(r -> log.debug("Successfully created telegram record: %s".formatted(telegramRecord.id())))
|
.onSuccess(r -> log.trace("Successfully created telegram record: %s".formatted(telegramRecord.id())))
|
||||||
.onFailure(
|
.onFailure(
|
||||||
err -> log.error("Failed to create telegram record: %s".formatted(err.getMessage()))
|
err -> log.error("Failed to create telegram record: %s".formatted(err.getMessage()))
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
|
handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler
|
||||||
|
|
||||||
# \u63A7\u5236\u53F0 Handler \u7684\u65E5\u5FD7\u7EA7\u522B
|
# \u63A7\u5236\u53F0 Handler \u7684\u65E5\u5FD7\u7EA7\u522B
|
||||||
java.util.logging.ConsoleHandler.level = INFO
|
java.util.logging.ConsoleHandler.level = FINE
|
||||||
|
|
||||||
# \u63A7\u5236\u53F0 Handler \u7684\u65E5\u5FD7\u683C\u5F0F\u5316\u5668
|
# \u63A7\u5236\u53F0 Handler \u7684\u65E5\u5FD7\u683C\u5F0F\u5316\u5668
|
||||||
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
|
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public class DataVerticleTest {
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Test Create telegram record")
|
@DisplayName("Test Create telegram record")
|
||||||
void createTelegramRecordTest(Vertx vertx, VertxTestContext testContext) {
|
void createTelegramRecordTest(Vertx vertx, VertxTestContext testContext) {
|
||||||
TelegramRecord telegramRecord = new TelegramRecord(1, "test", "test");
|
TelegramRecord telegramRecord = new TelegramRecord(1, "test", "test", null);
|
||||||
DataVerticle.telegramRepository.create(telegramRecord)
|
DataVerticle.telegramRepository.create(telegramRecord)
|
||||||
.compose(r -> DataVerticle.telegramRepository.getById(r.id()))
|
.compose(r -> DataVerticle.telegramRepository.getById(r.id()))
|
||||||
.onComplete(testContext.succeeding(r -> testContext.verify(() -> {
|
.onComplete(testContext.succeeding(r -> testContext.verify(() -> {
|
||||||
|
|
@ -52,8 +52,8 @@ public class DataVerticleTest {
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Test Get all telegram record")
|
@DisplayName("Test Get all telegram record")
|
||||||
void getAllTelegramRecordTest(Vertx vertx, VertxTestContext testContext) {
|
void getAllTelegramRecordTest(Vertx vertx, VertxTestContext testContext) {
|
||||||
TelegramRecord telegramRecord = new TelegramRecord(1, "test", "test");
|
TelegramRecord telegramRecord = new TelegramRecord(1, "test", "test", null);
|
||||||
TelegramRecord telegramRecord2 = new TelegramRecord(2, "test2", "test2");
|
TelegramRecord telegramRecord2 = new TelegramRecord(2, "test2", "test2", null);
|
||||||
DataVerticle.telegramRepository.create(telegramRecord)
|
DataVerticle.telegramRepository.create(telegramRecord)
|
||||||
.compose(r -> DataVerticle.telegramRepository.create(telegramRecord2))
|
.compose(r -> DataVerticle.telegramRepository.create(telegramRecord2))
|
||||||
.compose(r -> DataVerticle.telegramRepository.getAll())
|
.compose(r -> DataVerticle.telegramRepository.getAll())
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
File,
|
File,
|
||||||
FileText,
|
FileText,
|
||||||
Image,
|
Image,
|
||||||
|
LoaderPinwheel,
|
||||||
Music,
|
Music,
|
||||||
Network,
|
Network,
|
||||||
PauseCircle,
|
PauseCircle,
|
||||||
|
|
@ -76,7 +77,10 @@ const FileStatistics: React.FC<FileStatisticsProps> = ({ telegramId }) => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center space-x-2 rounded-lg bg-white p-4 text-gray-600 shadow-md">
|
<div className="flex items-center space-x-2 rounded-lg bg-white p-4 text-gray-600 shadow-md">
|
||||||
<Download className="h-5 w-5 animate-spin" />
|
<LoaderPinwheel
|
||||||
|
className="h-5 w-5 animate-spin"
|
||||||
|
style={{ strokeWidth: "0.8px" }}
|
||||||
|
/>
|
||||||
<span>Loading...</span>
|
<span>Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
@ -121,7 +125,7 @@ const FileStatistics: React.FC<FileStatisticsProps> = ({ telegramId }) => {
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6 rounded-lg bg-gray-50 p-6">
|
<div className="space-y-6 rounded-lg bg-gray-50 p-2 md:p-6">
|
||||||
<div className="flex-1 rounded-lg bg-white p-4 shadow-md">
|
<div className="flex-1 rounded-lg bg-white p-4 shadow-md">
|
||||||
<div className="flex items-center space-x-3 border-gray-200">
|
<div className="flex items-center space-x-3 border-gray-200">
|
||||||
<h3 className="text-md flex items-center space-x-2 font-semibold text-gray-700">
|
<h3 className="text-md flex items-center space-x-2 font-semibold text-gray-700">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue