@@ -2,32 +2,58 @@ package bot
2
2
3
3
import (
4
4
"fmt"
5
+ "strconv"
5
6
"strings"
6
7
7
8
"github.com/celestix/gotgproto/dispatcher"
8
9
"github.com/celestix/gotgproto/ext"
9
10
"github.com/gotd/td/tg"
10
11
"github.com/krau/SaveAny-Bot/common"
11
12
"github.com/krau/SaveAny-Bot/dao"
13
+ "github.com/krau/SaveAny-Bot/queue"
12
14
"github.com/krau/SaveAny-Bot/storage"
13
15
"github.com/krau/SaveAny-Bot/types"
14
16
)
15
17
18
+ func sendSaveHelp (ctx * ext.Context , update * ext.Update ) error {
19
+ helpText := `
20
+ 使用方法:
21
+
22
+ 1. 使用该命令回复要保存的文件, 可选文件名参数.
23
+ 示例:
24
+ /save custom_file_name.mp4
25
+
26
+ 2. 设置默认存储后, 发送 /save <频道ID/用户名> <消息ID范围> 来批量保存文件. 遵从存储规则, 若未匹配到任何规则则使用默认存储.
27
+ 示例:
28
+ /save @moreacg 114-514
29
+ `
30
+ ctx .Reply (update , ext .ReplyTextString (helpText ), nil )
31
+ return dispatcher .EndGroups
32
+ }
33
+
16
34
func saveCmd (ctx * ext.Context , update * ext.Update ) error {
17
- res , ok := update .EffectiveMessage .GetReplyTo ()
18
- if ! ok || res == nil {
19
- ctx .Reply (update , ext .ReplyTextString ("请回复要保存的文件" ), nil )
20
- return dispatcher .EndGroups
21
- }
22
- replyHeader , ok := res .(* tg.MessageReplyHeader )
23
- if ! ok {
24
- ctx .Reply (update , ext .ReplyTextString ("请回复要保存的文件" ), nil )
25
- return dispatcher .EndGroups
35
+ args := strings .Split (update .EffectiveMessage .Text , " " )
36
+ if len (args ) >= 3 {
37
+ return handleBatchSave (ctx , update , args [1 :])
26
38
}
27
- replyToMsgID , ok := replyHeader .GetReplyToMsgID ()
28
- if ! ok {
29
- ctx .Reply (update , ext .ReplyTextString ("请回复要保存的文件" ), nil )
30
- return dispatcher .EndGroups
39
+
40
+ replyToMsgID := func () int {
41
+ res , ok := update .EffectiveMessage .GetReplyTo ()
42
+ if ! ok || res == nil {
43
+ return 0
44
+ }
45
+ replyHeader , ok := res .(* tg.MessageReplyHeader )
46
+ if ! ok {
47
+ return 0
48
+ }
49
+ replyToMsgID , ok := replyHeader .GetReplyToMsgID ()
50
+ if ! ok {
51
+ return 0
52
+ }
53
+ return replyToMsgID
54
+ }()
55
+ if replyToMsgID == 0 {
56
+ return sendSaveHelp (ctx , update )
31
57
}
32
58
33
59
user , err := dao .GetUserByChatID (update .GetUserChat ().GetID ())
@@ -113,3 +139,125 @@ func saveCmd(ctx *ext.Context, update *ext.Update) error {
113
139
UserID : user .ChatID ,
114
140
})
115
141
}
142
+
143
+ func handleBatchSave (ctx * ext.Context , update * ext.Update , args []string ) error {
144
+ // args: [0] = @channel, [1] = 114-514
145
+ chatArg := args [0 ]
146
+ var chatID int64
147
+ var err error
148
+ msgIdSlice := strings .Split (args [1 ], "-" )
149
+ if len (msgIdSlice ) != 2 {
150
+ ctx .Reply (update , ext .ReplyTextString ("无效的消息ID范围" ), nil )
151
+ return dispatcher .EndGroups
152
+ }
153
+ minMsgID , minerr := strconv .ParseInt (msgIdSlice [0 ], 10 , 64 )
154
+ maxMsgID , maxerr := strconv .ParseInt (msgIdSlice [1 ], 10 , 64 )
155
+ if minerr != nil || maxerr != nil {
156
+ ctx .Reply (update , ext .ReplyTextString ("无效的消息ID范围" ), nil )
157
+ return dispatcher .EndGroups
158
+ }
159
+ if minMsgID > maxMsgID || minMsgID <= 0 || maxMsgID <= 0 {
160
+ ctx .Reply (update , ext .ReplyTextString ("无效的消息ID范围" ), nil )
161
+ return dispatcher .EndGroups
162
+ }
163
+ user , err := dao .GetUserByChatID (update .GetUserChat ().GetID ())
164
+ if err != nil {
165
+ common .Log .Errorf ("获取用户失败: %s" , err )
166
+ ctx .Reply (update , ext .ReplyTextString ("获取用户失败" ), nil )
167
+ return dispatcher .EndGroups
168
+ }
169
+ if user .DefaultStorage == "" {
170
+ ctx .Reply (update , ext .ReplyTextString ("请先设置默认存储" ), nil )
171
+ return dispatcher .EndGroups
172
+ }
173
+ storages := storage .GetUserStorages (user .ChatID )
174
+ if len (storages ) == 0 {
175
+ ctx .Reply (update , ext .ReplyTextString ("无可用的存储" ), nil )
176
+ return dispatcher .EndGroups
177
+ }
178
+
179
+ if strings .HasPrefix (chatArg , "@" ) {
180
+ chatUsername := strings .TrimPrefix (chatArg , "@" )
181
+ chat , err := ctx .ResolveUsername (chatUsername )
182
+ if err != nil {
183
+ common .Log .Errorf ("解析频道用户名失败: %s" , err )
184
+ ctx .Reply (update , ext .ReplyTextString ("解析频道用户名失败" ), nil )
185
+ return dispatcher .EndGroups
186
+ }
187
+ if chat == nil {
188
+ ctx .Reply (update , ext .ReplyTextString ("无法找到聊天" ), nil )
189
+ return dispatcher .EndGroups
190
+ }
191
+ chatID = chat .GetID ()
192
+ } else {
193
+ chatID , err = strconv .ParseInt (chatArg , 10 , 64 )
194
+ if err != nil {
195
+ ctx .Reply (update , ext .ReplyTextString ("无效的频道ID或用户名" ), nil )
196
+ return dispatcher .EndGroups
197
+ }
198
+ }
199
+ if chatID == 0 {
200
+ ctx .Reply (update , ext .ReplyTextString ("无效的频道ID或用户名" ), nil )
201
+ return dispatcher .EndGroups
202
+ }
203
+
204
+ replied , err := ctx .Reply (update , ext .ReplyTextString ("正在批量保存..." ), nil )
205
+ if err != nil {
206
+ common .Log .Errorf ("回复失败: %s" , err )
207
+ return dispatcher .EndGroups
208
+ }
209
+
210
+ total := maxMsgID - minMsgID + 1
211
+ successadd := 0
212
+ failedGetFile := 0
213
+ failedGetMsg := 0
214
+ failedSaveDB := 0
215
+ for i := minMsgID ; i <= maxMsgID ; i ++ {
216
+ file , err := FileFromMessage (ctx , chatID , int (i ), "" )
217
+ if err != nil {
218
+ common .Log .Errorf ("获取文件失败: %s" , err )
219
+ failedGetFile ++
220
+ continue
221
+ }
222
+ if file .FileName == "" {
223
+ message , err := GetTGMessage (ctx , chatID , int (i ))
224
+ if err != nil {
225
+ common .Log .Errorf ("获取消息失败: %s" , err )
226
+ failedGetMsg ++
227
+ continue
228
+ }
229
+ file .FileName = GenFileNameFromMessage (* message , file )
230
+ }
231
+ receivedFile := & dao.ReceivedFile {
232
+ Processing : false ,
233
+ FileName : file .FileName ,
234
+ ChatID : chatID ,
235
+ MessageID : int (i ),
236
+ ReplyChatID : update .GetUserChat ().GetID (),
237
+ ReplyMessageID : 0 ,
238
+ }
239
+ if err := dao .SaveReceivedFile (receivedFile ); err != nil {
240
+ common .Log .Errorf ("保存接收的文件失败: %s" , err )
241
+ failedSaveDB ++
242
+ continue
243
+ }
244
+ task := & types.Task {
245
+ Ctx : ctx ,
246
+ Status : types .Pending ,
247
+ File : file ,
248
+ StorageName : user .DefaultStorage ,
249
+ FileChatID : chatID ,
250
+ FileMessageID : int (i ),
251
+ UserID : user .ChatID ,
252
+ ReplyMessageID : 0 ,
253
+ ReplyChatID : update .GetUserChat ().GetID (),
254
+ }
255
+ queue .AddTask (task )
256
+ successadd ++
257
+ }
258
+ ctx .EditMessage (update .EffectiveChat ().GetID (), & tg.MessagesEditMessageRequest {
259
+ Message : fmt .Sprintf ("批量保存完成\n 成功添加: %d/%d\n 获取文件失败: %d\n 获取消息失败: %d\n 保存数据库失败: %d" , successadd , total , failedGetFile , failedGetMsg , failedSaveDB ),
260
+ ID : replied .ID ,
261
+ })
262
+ return dispatcher .EndGroups
263
+ }
0 commit comments