mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-06-28 02:31:34 +08:00
feat: support import files from storages to telegram (#183)
* feat: add import command and batch import functionality - Implemented the `/import` command to allow users to import files from storage to Telegram. - Added support for listing files in storage and filtering based on regex patterns. - Created a batch import task to handle multiple file uploads concurrently. - Introduced progress tracking for batch imports, providing real-time updates to users. - Enhanced storage interfaces to support file listing and reading capabilities. - Updated localization files for the new import command and its usage instructions. - Added utility functions for file size formatting and speed calculation. - Refactored Telegram storage handling to support reading from non-seekable streams. * feat: add i18n for import command * feat: implement ListFiles and OpenFile methods for WebDAV and Alist storage * Update common/i18n/locale/zh-Hans.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update core/tasks/batchimport/progress.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update core/tasks/batchimport/execute.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update storage/alist/alist.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update common/i18n/locale/en.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update pkg/storagetypes/fileinfo.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update common/i18n/locale/en.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update core/tasks/batchimport/execute.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update storage/webdav/webdav.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update storage/telegram/telegram.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update core/tasks/batchimport/execute.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update storage/webdav/webdav.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: missing progress stats i18n * refactor: use strutil to parse args * chore: update generated code files for consistency --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -21,6 +21,7 @@ const (
|
||||
BotMsgCmdDl Key = "bot.msg.cmd.dl"
|
||||
BotMsgCmdFnametmpl Key = "bot.msg.cmd.fnametmpl"
|
||||
BotMsgCmdHelp Key = "bot.msg.cmd.help"
|
||||
BotMsgCmdImport Key = "bot.msg.cmd.import"
|
||||
BotMsgCmdLswatch Key = "bot.msg.cmd.lswatch"
|
||||
BotMsgCmdParser Key = "bot.msg.cmd.parser"
|
||||
BotMsgCmdRule Key = "bot.msg.cmd.rule"
|
||||
@@ -105,6 +106,20 @@ const (
|
||||
BotMsgDlInfoFilesSelectStorage Key = "bot.msg.dl.info_files_select_storage"
|
||||
BotMsgDlUsage Key = "bot.msg.dl.usage"
|
||||
BotMsgHelpTextFmt Key = "bot.msg.help_text_fmt"
|
||||
BotMsgImportErrorAddTaskFailed Key = "bot.msg.import.error_add_task_failed"
|
||||
BotMsgImportErrorInvalidChatId Key = "bot.msg.import.error_invalid_chat_id"
|
||||
BotMsgImportErrorInvalidRegex Key = "bot.msg.import.error_invalid_regex"
|
||||
BotMsgImportErrorListFilesFailed Key = "bot.msg.import.error_list_files_failed"
|
||||
BotMsgImportErrorNoFilesToImport Key = "bot.msg.import.error_no_files_to_import"
|
||||
BotMsgImportErrorNoTargetChatId Key = "bot.msg.import.error_no_target_chat_id"
|
||||
BotMsgImportErrorNoTelegramStorage Key = "bot.msg.import.error_no_telegram_storage"
|
||||
BotMsgImportErrorStorageNotFound Key = "bot.msg.import.error_storage_not_found"
|
||||
BotMsgImportErrorStorageNotListable Key = "bot.msg.import.error_storage_not_listable"
|
||||
BotMsgImportErrorStorageNotReadable Key = "bot.msg.import.error_storage_not_readable"
|
||||
BotMsgImportInfoFetchingFiles Key = "bot.msg.import.info_fetching_files"
|
||||
BotMsgImportInfoTaskAdded Key = "bot.msg.import.info_task_added"
|
||||
BotMsgImportStartStats Key = "bot.msg.import.start_stats"
|
||||
BotMsgImportUsage Key = "bot.msg.import.usage"
|
||||
BotMsgMediaGroupErrorBuildStorageSelectKeyboardFailed Key = "bot.msg.media_group.error_build_storage_select_keyboard_failed"
|
||||
BotMsgMediaGroupInfoGroupFoundFilesSelectStorage Key = "bot.msg.media_group.info_group_found_files_select_storage"
|
||||
BotMsgMediaGroupInfoSavingFiles Key = "bot.msg.media_group.info_saving_files"
|
||||
@@ -149,6 +164,20 @@ const (
|
||||
BotMsgProgressFileProcessingPrefix Key = "bot.msg.progress.file_processing_prefix"
|
||||
BotMsgProgressFileSizePrefix Key = "bot.msg.progress.file_size_prefix"
|
||||
BotMsgProgressFileStartPrefix Key = "bot.msg.progress.file_start_prefix"
|
||||
BotMsgProgressImportAvgSpeedPrefix Key = "bot.msg.progress.import_avg_speed_prefix"
|
||||
BotMsgProgressImportElapsedTimePrefix Key = "bot.msg.progress.import_elapsed_time_prefix"
|
||||
BotMsgProgressImportFailedFilesPrefix Key = "bot.msg.progress.import_failed_files_prefix"
|
||||
BotMsgProgressImportFailedPrefix Key = "bot.msg.progress.import_failed_prefix"
|
||||
BotMsgProgressImportProcessingMore Key = "bot.msg.progress.import_processing_more"
|
||||
BotMsgProgressImportProcessingPrefix Key = "bot.msg.progress.import_processing_prefix"
|
||||
BotMsgProgressImportProgressPrefix Key = "bot.msg.progress.import_progress_prefix"
|
||||
BotMsgProgressImportRemainingTimePrefix Key = "bot.msg.progress.import_remaining_time_prefix"
|
||||
BotMsgProgressImportSpeedPrefix Key = "bot.msg.progress.import_speed_prefix"
|
||||
BotMsgProgressImportStartPrefix Key = "bot.msg.progress.import_start_prefix"
|
||||
BotMsgProgressImportSuccessPrefix Key = "bot.msg.progress.import_success_prefix"
|
||||
BotMsgProgressImportTotalFilesPrefix Key = "bot.msg.progress.import_total_files_prefix"
|
||||
BotMsgProgressImportTotalSizePrefix Key = "bot.msg.progress.import_total_size_prefix"
|
||||
BotMsgProgressImportUploadedPrefix Key = "bot.msg.progress.import_uploaded_prefix"
|
||||
BotMsgProgressParsedDonePrefix Key = "bot.msg.progress.parsed_done_prefix"
|
||||
BotMsgProgressParsedStartPrefix Key = "bot.msg.progress.parsed_start_prefix"
|
||||
BotMsgProgressProcessingListPrefix Key = "bot.msg.progress.processing_list_prefix"
|
||||
|
||||
@@ -29,6 +29,7 @@ bot:
|
||||
/silent - Toggle silent mode
|
||||
/storage - Set default storage
|
||||
/save [custom filename] - Save file
|
||||
/import <storage_name> <dir_path> [channel_id] [filter] - Import files from storage to Telegram
|
||||
/dir - Manage storage directories
|
||||
/rule - Manage rules
|
||||
/config - Modify configuration
|
||||
@@ -52,6 +53,7 @@ bot:
|
||||
dl: "Download files from given links"
|
||||
aria2dl: "Download files using Aria2"
|
||||
ytdlp: "Download video/audio using yt-dlp"
|
||||
import: "Import files from storage to Telegram"
|
||||
task: "Manage task queue"
|
||||
cancel: "Cancel task"
|
||||
watch: "Watch chats (UserBot)"
|
||||
@@ -294,6 +296,20 @@ bot:
|
||||
info_urls_select_storage: "Found {{.Count}} links, please select storage"
|
||||
info_downloading: "Downloading via yt-dlp..."
|
||||
error_download_failed: "yt-dlp download failed: {{.Error}}"
|
||||
import:
|
||||
usage: "Usage: /import <storage_name> <dir_path> [target_chat_id] [filter]\n\nExamples:\n/import local1 /downloads\n/import MyAlist /media/photos -1001234567890\n/import MyLocal /backup \".*[.]mp4$\""
|
||||
error_storage_not_found: "Storage '{{.StorageName}}' not found or access denied: {{.Error}}"
|
||||
error_storage_not_listable: "Storage '{{.StorageName}}' does not support listing files"
|
||||
error_storage_not_readable: "Storage '{{.StorageName}}' does not support reading files"
|
||||
error_no_telegram_storage: "No Telegram storage found: {{.Error}}"
|
||||
info_fetching_files: "Fetching file list..."
|
||||
error_list_files_failed: "Failed to list files: {{.Error}}"
|
||||
error_invalid_regex: "Invalid regular expression: {{.Error}}"
|
||||
error_no_files_to_import: "No files to import in directory"
|
||||
error_invalid_chat_id: "Invalid Chat ID: {{.Error}}"
|
||||
error_no_target_chat_id: "No target channel ID specified and Telegram storage has no default chat_id configured"
|
||||
error_add_task_failed: "Failed to add task: {{.Error}}"
|
||||
info_task_added: "Added {{.Count}} files to import queue\nTotal size: {{.SizeMB}} MB\nTask ID: {{.TaskID}}"
|
||||
cancel:
|
||||
usage: "Usage: /cancel <task_id>"
|
||||
error_cancel_failed: "Failed to cancel task: {{.Error}}"
|
||||
@@ -342,6 +358,20 @@ bot:
|
||||
ytdlp_done: "yt-dlp download completed and transferred ({{.Count}} files)\n"
|
||||
downloaded_prefix: "\nDownloaded: "
|
||||
current_speed_prefix: "\nCurrent speed: "
|
||||
import_start_prefix: "Importing: "
|
||||
import_progress_prefix: "Import progress: "
|
||||
import_uploaded_prefix: "\nUploaded: "
|
||||
import_speed_prefix: "\nSpeed: "
|
||||
import_remaining_time_prefix: "\nRemaining time: "
|
||||
import_processing_prefix: "\nProcessing:\n"
|
||||
import_processing_more: "...and {{.Count}} more files\n"
|
||||
import_failed_prefix: "Import failed\n"
|
||||
import_success_prefix: "Import completed\n"
|
||||
import_total_files_prefix: "\nTotal files: "
|
||||
import_total_size_prefix: "\nTotal size: "
|
||||
import_elapsed_time_prefix: "\nElapsed time: "
|
||||
import_avg_speed_prefix: "\nAverage speed: "
|
||||
import_failed_files_prefix: "\nFailed files: "
|
||||
syncpeers:
|
||||
start: "Starting to sync peers..."
|
||||
done: "Peer sync completed, total {{.Count}} chats synced"
|
||||
|
||||
@@ -30,6 +30,7 @@ bot:
|
||||
/storage - 设置默认存储位置
|
||||
/save [自定义文件名] - 保存文件
|
||||
/dl <链接1> <链接2> ... - 下载给定链接的文件
|
||||
/import <存储名> <目录路径> [频道ID] [过滤器] - 从存储端导入文件到 Telegram
|
||||
/dir - 管理存储目录
|
||||
/rule - 管理规则
|
||||
/config - 修改配置
|
||||
@@ -53,6 +54,7 @@ bot:
|
||||
dl: "下载给定链接的文件"
|
||||
aria2dl: "使用 Aria2 下载给定链接的文件"
|
||||
ytdlp: "使用 yt-dlp 下载视频/音频"
|
||||
import: "从存储端导入文件到 Telegram"
|
||||
task: "管理任务队列"
|
||||
cancel: "取消任务"
|
||||
watch: "监听聊天(UserBot)"
|
||||
@@ -295,6 +297,26 @@ bot:
|
||||
info_urls_select_storage: "共 {{.Count}} 个链接, 请选择存储位置"
|
||||
info_downloading: "正在通过 yt-dlp 下载..."
|
||||
error_download_failed: "yt-dlp 下载失败: {{.Error}}"
|
||||
import:
|
||||
usage: |
|
||||
用法: /import <storage_name> <dir_path> [target_chat_id] [filter]
|
||||
示例:
|
||||
/import 本机1 /downloads
|
||||
/import MyAlist /media/photos -1001234567890
|
||||
/import MyLocal /backup ".*\.mp4$"
|
||||
error_storage_not_found: "存储端 '{{.StorageName}}' 不存在或您无权访问: {{.Error}}"
|
||||
error_storage_not_listable: "存储端 '{{.StorageName}}' 不支持列举文件功能"
|
||||
error_storage_not_readable: "存储端 '{{.StorageName}}' 不支持读取文件功能"
|
||||
error_no_telegram_storage: "未找到可用的 Telegram 存储: {{.Error}}"
|
||||
info_fetching_files: "正在获取文件列表..."
|
||||
error_list_files_failed: "获取文件列表失败: {{.Error}}"
|
||||
error_invalid_regex: "正则表达式无效: {{.Error}}"
|
||||
error_no_files_to_import: "目录中没有可导入的文件"
|
||||
error_invalid_chat_id: "无效的 Chat ID: {{.Error}}"
|
||||
error_no_target_chat_id: "未指定目标频道 ID,且 Telegram 存储未配置默认 chat_id"
|
||||
error_add_task_failed: "添加任务失败: {{.Error}}"
|
||||
info_task_added: "已添加 {{.Count}} 个文件到导入队列\n总大小: {{.SizeMB}} MB\n任务 ID: {{.TaskID}}"
|
||||
start_stats: "总文件数: {{.Count}}\n总大小: {{.SizeMB}} MB"
|
||||
cancel:
|
||||
usage: "用法: /cancel <task_id>"
|
||||
error_cancel_failed: "取消任务失败: {{.Error}}"
|
||||
@@ -343,6 +365,20 @@ bot:
|
||||
ytdlp_done: "yt-dlp 下载完成并已转存 ({{.Count}} 个文件)\n"
|
||||
downloaded_prefix: "\n已下载: "
|
||||
current_speed_prefix: "\n当前速度: "
|
||||
import_start_prefix: "正在导入: "
|
||||
import_progress_prefix: "导入进度: "
|
||||
import_uploaded_prefix: "\n已上传: "
|
||||
import_speed_prefix: "\n速度: "
|
||||
import_remaining_time_prefix: "\n剩余时间: "
|
||||
import_processing_prefix: "\n正在处理:\n"
|
||||
import_processing_more: "...和其他 {{.Count}} 个文件\n"
|
||||
import_failed_prefix: "导入失败\n"
|
||||
import_success_prefix: "导入完成\n"
|
||||
import_total_files_prefix: "\n总文件数: "
|
||||
import_total_size_prefix: "\n总大小: "
|
||||
import_elapsed_time_prefix: "\n耗时: "
|
||||
import_avg_speed_prefix: "\n平均速度: "
|
||||
import_failed_files_prefix: "\n失败文件数: "
|
||||
syncpeers:
|
||||
start: "正在同步对话列表..."
|
||||
success: "对话列表同步完成, 共同步 {{.Count}} 个对话"
|
||||
@@ -353,4 +389,4 @@ bot:
|
||||
info_adding_aria2_download: "正在添加 Aria2 下载任务..."
|
||||
error_adding_aria2_download: "添加 Aria2 下载任务失败: {{.Error}}"
|
||||
info_aria2_download_added: "Aria2 下载任务已添加, GID: {{.GID}}"
|
||||
info_select_storage: "请选择存储位置, 选择后将添加到 Aria2 下载队列"
|
||||
info_select_storage: "请选择存储位置, 选择后将添加到 Aria2 下载队列"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package dlutil
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
var threadsLevels = []struct {
|
||||
threads int
|
||||
@@ -31,3 +34,23 @@ func GetSpeed(downloaded int64, startTime time.Time) float64 {
|
||||
}
|
||||
return float64(downloaded) / elapsed
|
||||
}
|
||||
|
||||
// FormatSize formats a byte size as a human-readable string
|
||||
func FormatSize(bytes int64) string {
|
||||
const (
|
||||
KB = 1024
|
||||
MB = KB * 1024
|
||||
GB = MB * 1024
|
||||
)
|
||||
|
||||
switch {
|
||||
case bytes >= GB:
|
||||
return fmt.Sprintf("%.2f GB", float64(bytes)/float64(GB))
|
||||
case bytes >= MB:
|
||||
return fmt.Sprintf("%.2f MB", float64(bytes)/float64(MB))
|
||||
case bytes >= KB:
|
||||
return fmt.Sprintf("%.2f KB", float64(bytes)/float64(KB))
|
||||
default:
|
||||
return fmt.Sprintf("%d B", bytes)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user