fix(telegram): show scan and current file status
Edit the manual channel download status message with scan totals before queuing downloads. Force-refresh the batch status when each file starts so comment-thread media shows the active file name.
This commit is contained in:
1 parent
b9297e4db3
commit
e20d354e7e
5 files changed
+119
-2
No files matched your search
Vendored
+46
-2
@@ -2573,6 +2573,9 @@ async function buildConsolidatedStatus(singleFiles, batches) {
|
||||
if (!isDone) {
|
||||
const progress = generateProgressBar(batch.completed, batch.totalFiles);
|
||||
lines.push(` ${progress} (${batch.completed}/${batch.totalFiles})`);
|
||||
if (batch.currentFileName) {
|
||||
lines.push(` \u{1F4C4} \u5F53\u524D: ${batch.currentFileName}`);
|
||||
}
|
||||
} else {
|
||||
lines.push(` \u2705 ${batch.successful} \u274C ${batch.failed}`);
|
||||
}
|
||||
@@ -4790,6 +4793,7 @@ async function downloadTelegramChannelRange(botClient, requestMessage, source, s
|
||||
updateBatch(chatIdStr, batchId, { folderPath: resolved || void 0 });
|
||||
}
|
||||
uploadItem.folderOverride = taskResolvedStorageFolder !== void 0 ? taskResolvedStorageFolder : taskFolderOverride;
|
||||
await refreshSegmentStatus(true, fileName);
|
||||
await processFileUpload(userClient2, uploadItem);
|
||||
if (uploadItem.status === "success") {
|
||||
successful += 1;
|
||||
@@ -5384,6 +5388,7 @@ async function buildDownloadScanResult(userClient2, source, messages, options =
|
||||
return {
|
||||
messages,
|
||||
refs,
|
||||
channelMediaFound: refs.length,
|
||||
commentMessagesScanned: commentScan.scanned,
|
||||
commentMediaFound: commentScan.mediaFound
|
||||
};
|
||||
@@ -5491,6 +5496,18 @@ async function enqueueTelegramDateDownload(botClient, requestMessage, userId, so
|
||||
const baseMessages = await getMessagesByDateRange(userClient2, source, startDate, endDate);
|
||||
const messages = await expandMessagesWithMediaGroups(userClient2, source, baseMessages);
|
||||
const scan = await buildDownloadScanResult(userClient2, source, messages, { ...options, startDate, endDate });
|
||||
const commentLimit = options.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST;
|
||||
await options.onScanComplete?.({
|
||||
source,
|
||||
mode: "date",
|
||||
channelMessagesScanned: messages.length,
|
||||
channelMediaFound: scan.channelMediaFound,
|
||||
commentMessagesScanned: scan.commentMessagesScanned,
|
||||
commentMediaFound: scan.commentMediaFound,
|
||||
totalMediaFound: scan.refs.length,
|
||||
commentsEnabled: Boolean(options.includeComments),
|
||||
commentsMaxPerPost: commentLimit
|
||||
});
|
||||
const messageIds = scan.refs.map((ref) => ref.id);
|
||||
const jobId = await createJob(userId, requestMessage.chatId?.toString(), "date_range", source, {
|
||||
startDate: startDateText,
|
||||
@@ -5550,6 +5567,18 @@ async function enqueueTelegramTagDownload(botClient, requestMessage, userId, sou
|
||||
const baseMessages = await getMessagesByHashtag(userClient2, source, tag);
|
||||
const messages = await expandMessagesWithMediaGroups(userClient2, source, baseMessages);
|
||||
const scan = await buildDownloadScanResult(userClient2, source, messages, { ...options, tag });
|
||||
const commentLimit = options.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST;
|
||||
await options.onScanComplete?.({
|
||||
source,
|
||||
mode: "tag",
|
||||
channelMessagesScanned: messages.length,
|
||||
channelMediaFound: scan.channelMediaFound,
|
||||
commentMessagesScanned: scan.commentMessagesScanned,
|
||||
commentMediaFound: scan.commentMediaFound,
|
||||
totalMediaFound: scan.refs.length,
|
||||
commentsEnabled: Boolean(options.includeComments),
|
||||
commentsMaxPerPost: commentLimit
|
||||
});
|
||||
const messageIds = scan.refs.map((ref) => ref.id);
|
||||
const jobId = await createJob(userId, requestMessage.chatId?.toString(), "tag_download", source, {
|
||||
tag,
|
||||
@@ -7151,6 +7180,19 @@ function buildTelegramWizardPrompt(state) {
|
||||
function isDateOnly(text) {
|
||||
return /^\d{4}-\d{2}-\d{2}$/.test(text.trim());
|
||||
}
|
||||
async function updateScanStatusMessage(statusMessage, summary) {
|
||||
const lines = [
|
||||
`\u{1F50E} **\u626B\u63CF\u5B8C\u6210\uFF0C\u5F00\u59CB\u4E0B\u8F7D**`,
|
||||
`\u{1F4CD} \u9891\u9053\uFF1A${summary.source}`,
|
||||
``,
|
||||
`\u{1F4C4} \u9891\u9053\u6B63\u6587\uFF1A\u626B\u63CF ${summary.channelMessagesScanned} \u6761\uFF0C\u53D1\u73B0 ${summary.channelMediaFound} \u4E2A\u6587\u4EF6`,
|
||||
summary.commentsEnabled ? `\u{1F4AC} \u8BC4\u8BBA\u533A\uFF1A\u626B\u63CF ${summary.commentMessagesScanned} \u6761\uFF0C\u53D1\u73B0 ${summary.commentMediaFound} \u4E2A\u6587\u4EF6\uFF08\u6BCF\u5E16\u6700\u591A ${summary.commentsMaxPerPost} \u6761\uFF09` : `\u{1F4AC} \u8BC4\u8BBA\u533A\uFF1A\u672A\u542F\u7528`,
|
||||
`\u{1F4E6} \u5F85\u4E0B\u8F7D\uFF1A${summary.totalMediaFound} \u4E2A\u6587\u4EF6`,
|
||||
``,
|
||||
`\u23F3 \u6B63\u5728\u52A0\u5165\u4E0B\u8F7D\u961F\u5217\uFF0C\u53EF\u7528 /tasks \u67E5\u770B\u540E\u53F0\u4EFB\u52A1\u3002`
|
||||
];
|
||||
await statusMessage.edit({ text: lines.join("\n") }).catch(() => void 0);
|
||||
}
|
||||
async function replyWithJobResult(statusMessage, fallbackMessage, promise, kind) {
|
||||
promise.then((result) => {
|
||||
const commentLine = result.commentMediaFound || result.commentMessagesScanned ? `
|
||||
@@ -7329,7 +7371,8 @@ ${buildPathPreviewLine(state.customFolder)}` : "\u{1F4C1} \u672C\u8BA2\u9605\u4F
|
||||
\u5B8C\u6210\u540E\u4F1A\u81EA\u52A8\u66F4\u65B0\u7ED3\u679C\uFF0C\u53EF\u7528 /tasks \u67E5\u770B\u540E\u53F0\u4EFB\u52A1\u3002` });
|
||||
await replyWithJobResult(queuedMsg, message, enqueueTelegramTagDownload(client, message, senderId, state.source, input, state.customFolder, {
|
||||
includeComments: Boolean(state.includeComments),
|
||||
commentsMaxPerPost: state.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST
|
||||
commentsMaxPerPost: state.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST,
|
||||
onScanComplete: (summary) => updateScanStatusMessage(queuedMsg, summary)
|
||||
}), "tag");
|
||||
} catch (error) {
|
||||
await message.reply({ message: `\u274C \u6807\u7B7E\u4E0B\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}` });
|
||||
@@ -7356,7 +7399,8 @@ ${buildPathPreviewLine(state.customFolder)}` : "\u{1F4C1} \u672C\u8BA2\u9605\u4F
|
||||
\u5B8C\u6210\u540E\u4F1A\u81EA\u52A8\u66F4\u65B0\u7ED3\u679C\uFF0C\u53EF\u7528 /tasks \u67E5\u770B\u540E\u53F0\u4EFB\u52A1\u3002` });
|
||||
await replyWithJobResult(queuedMsg, message, enqueueTelegramDateDownload(client, message, senderId, state.source, state.startDate, input, state.customFolder, {
|
||||
includeComments: Boolean(state.includeComments),
|
||||
commentsMaxPerPost: state.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST
|
||||
commentsMaxPerPost: state.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST,
|
||||
onScanComplete: (summary) => updateScanStatusMessage(queuedMsg, summary)
|
||||
}), "date");
|
||||
} catch (error) {
|
||||
await message.reply({ message: `\u274C \u65E5\u671F\u4E0B\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}` });
|
||||
|
||||
@@ -285,6 +285,34 @@ function isDateOnly(text: string): boolean {
|
||||
}
|
||||
|
||||
|
||||
interface TelegramDownloadScanSummary {
|
||||
source: string;
|
||||
mode: 'date' | 'tag';
|
||||
channelMessagesScanned: number;
|
||||
channelMediaFound: number;
|
||||
commentMessagesScanned: number;
|
||||
commentMediaFound: number;
|
||||
totalMediaFound: number;
|
||||
commentsEnabled: boolean;
|
||||
commentsMaxPerPost: number;
|
||||
}
|
||||
|
||||
async function updateScanStatusMessage(statusMessage: Api.Message, summary: TelegramDownloadScanSummary): Promise<void> {
|
||||
const lines = [
|
||||
`🔎 **扫描完成,开始下载**`,
|
||||
`📍 频道:${summary.source}`,
|
||||
``,
|
||||
`📄 频道正文:扫描 ${summary.channelMessagesScanned} 条,发现 ${summary.channelMediaFound} 个文件`,
|
||||
summary.commentsEnabled
|
||||
? `💬 评论区:扫描 ${summary.commentMessagesScanned} 条,发现 ${summary.commentMediaFound} 个文件(每帖最多 ${summary.commentsMaxPerPost} 条)`
|
||||
: `💬 评论区:未启用`,
|
||||
`📦 待下载:${summary.totalMediaFound} 个文件`,
|
||||
``,
|
||||
`⏳ 正在加入下载队列,可用 /tasks 查看后台任务。`,
|
||||
];
|
||||
await statusMessage.edit({ text: lines.join('\n') }).catch(() => undefined);
|
||||
}
|
||||
|
||||
async function replyWithJobResult(statusMessage: Api.Message, fallbackMessage: Api.Message, promise: Promise<any>, kind: 'date' | 'tag'): Promise<void> {
|
||||
promise
|
||||
.then(result => {
|
||||
@@ -469,6 +497,7 @@ async function handleTelegramWizardMessage(message: Api.Message, senderId: numbe
|
||||
await replyWithJobResult(queuedMsg as Api.Message, message, enqueueTelegramTagDownload(client!, message, senderId, state.source!, input, state.customFolder, {
|
||||
includeComments: Boolean(state.includeComments),
|
||||
commentsMaxPerPost: state.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST,
|
||||
onScanComplete: summary => updateScanStatusMessage(queuedMsg as Api.Message, summary),
|
||||
}), 'tag');
|
||||
} catch (error) {
|
||||
await message.reply({ message: `❌ 标签下载失败: ${error instanceof Error ? error.message : String(error)}` });
|
||||
@@ -499,6 +528,7 @@ async function handleTelegramWizardMessage(message: Api.Message, senderId: numbe
|
||||
await replyWithJobResult(queuedMsg as Api.Message, message, enqueueTelegramDateDownload(client!, message, senderId, state.source!, state.startDate!, input, state.customFolder, {
|
||||
includeComments: Boolean(state.includeComments),
|
||||
commentsMaxPerPost: state.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST,
|
||||
onScanComplete: summary => updateScanStatusMessage(queuedMsg as Api.Message, summary),
|
||||
}), 'date');
|
||||
} catch (error) {
|
||||
await message.reply({ message: `❌ 日期下载失败: ${error instanceof Error ? error.message : String(error)}` });
|
||||
|
||||
@@ -160,14 +160,28 @@ async function persistDownloadItems(jobId: string, source: string, messages: Api
|
||||
}
|
||||
}
|
||||
|
||||
interface TelegramDownloadScanSummary {
|
||||
source: string;
|
||||
mode: 'date' | 'tag';
|
||||
channelMessagesScanned: number;
|
||||
channelMediaFound: number;
|
||||
commentMessagesScanned: number;
|
||||
commentMediaFound: number;
|
||||
totalMediaFound: number;
|
||||
commentsEnabled: boolean;
|
||||
commentsMaxPerPost: number;
|
||||
}
|
||||
|
||||
interface TelegramCommentScanOptions {
|
||||
includeComments?: boolean;
|
||||
commentsMaxPerPost?: number;
|
||||
onScanComplete?: (summary: TelegramDownloadScanSummary) => Promise<void> | void;
|
||||
}
|
||||
|
||||
interface TelegramDownloadScanResult {
|
||||
messages: Api.Message[];
|
||||
refs: TelegramDownloadMessageRef[];
|
||||
channelMediaFound: number;
|
||||
commentMessagesScanned: number;
|
||||
commentMediaFound: number;
|
||||
}
|
||||
@@ -266,6 +280,7 @@ async function buildDownloadScanResult(
|
||||
return {
|
||||
messages,
|
||||
refs,
|
||||
channelMediaFound: refs.length,
|
||||
commentMessagesScanned: commentScan.scanned,
|
||||
commentMediaFound: commentScan.mediaFound,
|
||||
};
|
||||
@@ -387,6 +402,18 @@ export async function enqueueTelegramDateDownload(botClient: TelegramClient, req
|
||||
const baseMessages = await getMessagesByDateRange(userClient, source, startDate, endDate);
|
||||
const messages = await expandMessagesWithMediaGroups(userClient, source, baseMessages);
|
||||
const scan = await buildDownloadScanResult(userClient, source, messages, { ...options, startDate, endDate });
|
||||
const commentLimit = options.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST;
|
||||
await options.onScanComplete?.({
|
||||
source,
|
||||
mode: 'date',
|
||||
channelMessagesScanned: messages.length,
|
||||
channelMediaFound: scan.channelMediaFound,
|
||||
commentMessagesScanned: scan.commentMessagesScanned,
|
||||
commentMediaFound: scan.commentMediaFound,
|
||||
totalMediaFound: scan.refs.length,
|
||||
commentsEnabled: Boolean(options.includeComments),
|
||||
commentsMaxPerPost: commentLimit,
|
||||
});
|
||||
const messageIds = scan.refs.map(ref => ref.id);
|
||||
const jobId = await createJob(userId, requestMessage.chatId?.toString(), 'date_range', source, {
|
||||
startDate: startDateText,
|
||||
@@ -453,6 +480,18 @@ export async function enqueueTelegramTagDownload(botClient: TelegramClient, requ
|
||||
const baseMessages = await getMessagesByHashtag(userClient, source, tag);
|
||||
const messages = await expandMessagesWithMediaGroups(userClient, source, baseMessages);
|
||||
const scan = await buildDownloadScanResult(userClient, source, messages, { ...options, tag });
|
||||
const commentLimit = options.commentsMaxPerPost || TELEGRAM_COMMENTS_MAX_PER_POST;
|
||||
await options.onScanComplete?.({
|
||||
source,
|
||||
mode: 'tag',
|
||||
channelMessagesScanned: messages.length,
|
||||
channelMediaFound: scan.channelMediaFound,
|
||||
commentMessagesScanned: scan.commentMessagesScanned,
|
||||
commentMediaFound: scan.commentMediaFound,
|
||||
totalMediaFound: scan.refs.length,
|
||||
commentsEnabled: Boolean(options.includeComments),
|
||||
commentsMaxPerPost: commentLimit,
|
||||
});
|
||||
const messageIds = scan.refs.map(ref => ref.id);
|
||||
const jobId = await createJob(userId, requestMessage.chatId?.toString(), 'tag_download', source, {
|
||||
tag,
|
||||
|
||||
@@ -2028,6 +2028,7 @@ export async function downloadTelegramChannelRange(
|
||||
updateBatch(chatIdStr, batchId, { folderPath: resolved || undefined });
|
||||
}
|
||||
uploadItem.folderOverride = taskResolvedStorageFolder !== undefined ? taskResolvedStorageFolder : taskFolderOverride;
|
||||
await refreshSegmentStatus(true, fileName);
|
||||
await processFileUpload(userClient, uploadItem);
|
||||
if (uploadItem.status === 'success') {
|
||||
successful += 1;
|
||||
|
||||
@@ -823,6 +823,9 @@ export async function buildConsolidatedStatus(
|
||||
if (!isDone) {
|
||||
const progress = generateProgressBar(batch.completed, batch.totalFiles);
|
||||
lines.push(` ${progress} (${batch.completed}/${batch.totalFiles})`);
|
||||
if (batch.currentFileName) {
|
||||
lines.push(` 📄 当前: ${batch.currentFileName}`);
|
||||
}
|
||||
} else {
|
||||
lines.push(` ✅ ${batch.successful} ❌ ${batch.failed}`);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user