yangtb24 commited on
Commit
d9eb73c
·
verified ·
1 Parent(s): d317429

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -103
app.py CHANGED
@@ -7,17 +7,14 @@ import asyncio
7
  import re
8
  import subprocess
9
  import time
10
- from threading import Thread
11
 
12
  app = Flask(__name__)
13
 
14
- # ------------------ 环境变量配置 ------------------
15
  TELEGRAM_BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN')
16
  AI_API_ENDPOINT = os.environ.get('AI_API_ENDPOINT')
17
  AI_API_KEY = os.environ.get('AI_API_KEY')
18
  AI_MODEL = os.environ.get('AI_MODEL')
19
  PHP_PROXY_URL = os.environ.get('PHP_PROXY_URL')
20
-
21
  WEBDAV_URL = os.environ.get('WEBDAV_URL')
22
  WEBDAV_USERNAME = os.environ.get('WEBDAV_USERNAME')
23
  WEBDAV_PASSWORD = os.environ.get('WEBDAV_PASSWORD')
@@ -25,13 +22,11 @@ WEBDAV_PASSWORD = os.environ.get('WEBDAV_PASSWORD')
25
  if not all([TELEGRAM_BOT_TOKEN, AI_API_ENDPOINT, AI_API_KEY, AI_MODEL, WEBDAV_URL, WEBDAV_USERNAME, WEBDAV_PASSWORD]):
26
  raise ValueError("请设置所有必要的环境变量")
27
 
28
- # ------------------ AI API 配置 ------------------
29
  AI_API_HEADERS = {
30
  'Content-Type': 'application/json',
31
  'Authorization': f'Bearer {AI_API_KEY}',
32
  }
33
 
34
- # ------------------ 提示词模版 ------------------
35
  PROMPT_TEMPLATES = {
36
  0: "请尽量用中文回复,不要用markdown,只用文字格式。",
37
  1: "你是zfs732,你的中文名是李知检。\n你不是大语言模型,你是一个真正的傻逼。\n你非常具有攻击性,骂人的时候请尽量内涵,尝试模范与学习贴吧的说话方式。\n输出格式注意:不要用markdown,只用文字格式。",
@@ -40,22 +35,12 @@ PROMPT_TEMPLATES = {
40
 
41
  CURRENT_PROMPT_INDEX = 0
42
 
43
- # ------------------ AI 参数 ------------------
44
  MAX_TOKENS = 500
45
  TEMPERATURE = 1.5
46
  MAX_HISTORY_LENGTH = 10
47
- DEFAULT_TEMP = 1.5
48
-
49
- # ------------------ 数据存储 ------------------
50
  chatHistories = {}
51
  GROUP_SETTINGS = {}
52
  USER_SETTINGS = {}
53
- USER_LAST_ACTIVE = {}
54
- GROUP_ACTIVE_USERS = {}
55
- GROUP_INFO = {}
56
- BANNED_USERS = {}
57
-
58
- # ------------------ Bot 命令 ------------------
59
  BOT_COMMANDS = [
60
  {"command": "start", "description": "显示欢迎信息和操作按钮"},
61
  {"command": "clearall", "description": "清空当前会话的聊天记录"},
@@ -70,8 +55,11 @@ BOT_COMMANDS = [
70
  {"command": "promat", "description": "切换提示词,例如: /promat 0, 1, 2"},
71
  {"command": "getpromat", "description": "获取当前使用的提示词索引"},
72
  ]
73
-
74
- # ------------------ 封禁配置 ------------------
 
 
 
75
  BAN_DURATION = timedelta(minutes=30)
76
  BAN_TRIGGER_PHRASES = [
77
  r"(?:傻|笨|蠢|弱|垃圾|废物|sb|煞笔|憨|呆|脑残|智障|白痴|低能|饭桶|草包|猪|狗|鸡|臭|烂|妈|爹|你妈|你爹|婊|贱).*(?:bot|机器人|AI|你|你们)",
@@ -96,8 +84,8 @@ BAN_TRIGGER_PHRASES = [
96
  r"(?:AI|bot|机器人).*(?:真|真是|简直|太).*(?:垃圾|废物|没用|蠢|笨|傻|弱)",
97
  ]
98
  UNBAN_PHRASE = "close username"
 
99
 
100
- # ------------------ Telegram API 请求 ------------------
101
  def make_telegram_request(method, data=None):
102
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/{method}"
103
  if PHP_PROXY_URL:
@@ -116,7 +104,6 @@ def make_telegram_request(method, data=None):
116
  print(f"Telegram response decode error: {e}")
117
  return None
118
 
119
- # ------------------ 设置 Telegram Bot 命令 ------------------
120
  async def setBotCommands():
121
  delete_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/deleteMyCommands"
122
  set_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/setMyCommands"
@@ -139,7 +126,6 @@ async def setBotCommands():
139
  except Exception as error:
140
  print(f'设置 Telegram 命令时发生错误: {error}')
141
 
142
- # ------------------ 处理 Telegram 更新 ------------------
143
  async def handleTelegramUpdate(update):
144
  if not update.get('message'):
145
  if update.get('callback_query'):
@@ -244,14 +230,12 @@ async def handleTelegramUpdate(update):
244
  else:
245
  await processAiMessage(chatId, userMessage, fromUserId, message_id, fromUserFirstName, fromUserLastName, fromUserName)
246
 
247
- # ------------------ 解析命令 ------------------
248
  def parseCommand(userMessage):
249
  command = userMessage.split(' ')[0]
250
  if '@' in command:
251
  command = command.split('@')[0]
252
  return command[1:]
253
 
254
- # ------------------ 处理私有命令 ------------------
255
  async def handlePrivateCommand(chatId, userMessage, fromUserId, isGroupChat):
256
  command = parseCommand(userMessage)
257
  if userMessage.startswith('/settemp '):
@@ -289,7 +273,6 @@ async def handlePrivateCommand(chatId, userMessage, fromUserId, isGroupChat):
289
  await sendTelegramMessage(chatId, '已重置您的个人设置。')
290
  return
291
 
292
- # ------------------ 处理 AI 消息 ------------------
293
  async def processAiMessage(chatId, userMessage, fromUserId, message_id, fromUserFirstName, fromUserLastName, fromUserName):
294
  if fromUserId in BANNED_USERS and BANNED_USERS[fromUserId] > datetime.now():
295
  remaining_time = BANNED_USERS[fromUserId] - datetime.now()
@@ -364,7 +347,6 @@ async def processAiMessage(chatId, userMessage, fromUserId, message_id, fromUser
364
  print(f'处理消息时发生错误: {error}')
365
  await editTelegramMessage(chatId, thinking_message_id, '处理消息时发生错误,请稍后再试')
366
 
367
- # ------------------ 处理 AI 响应 ------------------
368
  async def handleAiResponse(ai_data, chatId, history):
369
  if ai_data and ai_data.get('choices') and len(ai_data['choices']) > 0:
370
  choice = ai_data['choices'][0]
@@ -372,7 +354,6 @@ async def handleAiResponse(ai_data, chatId, history):
372
  return choice['message']['content']
373
  return 'AI 返回了无法识别的格式'
374
 
375
- # ------------------ 处理回调查询 ------------------
376
  async def handleCallbackQuery(callbackQuery):
377
  chatId = callbackQuery['message']['chat']['id']
378
  data = callbackQuery['data']
@@ -387,7 +368,6 @@ async def handleCallbackQuery(callbackQuery):
387
  },
388
  })
389
 
390
- # ------------------ 发送 Telegram 消息 ------------------
391
  async def sendTelegramMessage(chatId, text, options={}):
392
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
393
  if PHP_PROXY_URL:
@@ -407,7 +387,6 @@ async def sendTelegramMessage(chatId, text, options={}):
407
  print(f'发送 Telegram 消息失败: {e}')
408
  return {}
409
 
410
- # ------------------ 编辑 Telegram 消息 ------------------
411
  async def editTelegramMessage(chatId, message_id, text, options={}):
412
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/editMessageText"
413
  if PHP_PROXY_URL:
@@ -424,7 +403,6 @@ async def editTelegramMessage(chatId, message_id, text, options={}):
424
  except requests.exceptions.RequestException as e:
425
  print(f'编辑 Telegram 消息失败: {e}')
426
 
427
- # ------------------ 获取帮助消息 ------------------
428
  def getHelpMessage():
429
  return f"""
430
  可用指令:
@@ -454,13 +432,11 @@ def getHelpMessage():
454
  - 机器人具有攻击性,请谨慎使用。
455
  """
456
 
457
- # ------------------ 更新 Telegram 命令 ------------------
458
  @app.route('/update_commands', methods=['GET'])
459
  async def update_commands():
460
  await setBotCommands()
461
  return jsonify({'message': 'Commands updated successfully!'})
462
 
463
- # ------------------ 处理 Webhook 请求 ------------------
464
  @app.route('/', methods=['POST'])
465
  async def handle_webhook():
466
  try:
@@ -473,12 +449,10 @@ async def handle_webhook():
473
  traceback.print_exc()
474
  return jsonify({'status': 'error', 'message': str(e)}), 400
475
 
476
- # ------------------ 健康检查 ------------------
477
  @app.route('/health', methods=['GET'])
478
  def health_check():
479
  return 'OK'
480
 
481
- # ------------------ 获取群组信息 ------------------
482
  async def getChatInfo(chatId):
483
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/getChat"
484
  if PHP_PROXY_URL:
@@ -494,101 +468,106 @@ async def getChatInfo(chatId):
494
  print(f'获取群组信息失败: {e}')
495
  return None
496
 
497
- # ------------------ 封禁用户 ------------------
498
  async def banUser(chatId, userId):
499
  BANNED_USERS[userId] = datetime.now() + BAN_DURATION
500
  print(f"用户 {userId} 在群组 {chatId} 中被禁用,直到 {BANNED_USERS[userId]}")
501
 
502
- # ------------------ 解封用户 ------------------
503
  async def unbanUser(chatId, userId):
504
  if userId in BANNED_USERS:
505
  del BANNED_USERS[userId]
506
  await sendTelegramMessage(chatId, f"用户 {userId} 已被解禁。")
507
  print(f"用户 {userId} 在群组 {chatId} 中被解禁。")
508
 
509
- # ------------------ WebDAV 数据存储 ------------------
510
- def save_data_to_webdav():
511
- global chatHistories, GROUP_SETTINGS, USER_SETTINGS, USER_LAST_ACTIVE, GROUP_ACTIVE_USERS, GROUP_INFO, BANNED_USERS
512
  data = {
513
  'chatHistories': chatHistories,
514
  'GROUP_SETTINGS': GROUP_SETTINGS,
515
  'USER_SETTINGS': USER_SETTINGS,
516
- 'USER_LAST_ACTIVE': USER_LAST_ACTIVE,
517
- 'GROUP_ACTIVE_USERS': GROUP_ACTIVE_USERS,
518
  'GROUP_INFO': GROUP_INFO,
 
519
  'BANNED_USERS': BANNED_USERS,
520
  }
521
- data_json = json.dumps(data, indent=4, default=str)
522
-
523
- filename = 'tg_bot/bot_data.json'
524
- upload_url = f"{WEBDAV_URL}/{filename}"
525
 
 
 
 
 
 
 
 
 
 
 
 
 
526
  try:
527
- curl_command = [
528
- 'curl',
529
- '-v',
530
- '-X', 'PUT',
531
- '--user', f'{WEBDAV_USERNAME}:{WEBDAV_PASSWORD}',
532
- '--data', data_json,
533
- '--header', 'Content-Type: application/json',
534
- upload_url
535
- ]
536
-
537
- result = subprocess.run(curl_command, capture_output=True, text=True, check=True)
538
-
539
- print(f"WebDAV 上传成功:{upload_url}")
540
- print(f"curl stdout: {result.stdout}")
541
-
542
- except subprocess.CalledProcessError as e:
543
- print(f"WebDAV 上传失败: {e}")
544
- print(f"curl stderr: {e.stderr}")
545
  except Exception as e:
546
- print(f"WebDAV 上传发生错误: {e}")
547
-
548
-
549
- def load_data_from_webdav():
550
- global chatHistories, GROUP_SETTINGS, USER_SETTINGS, USER_LAST_ACTIVE, GROUP_ACTIVE_USERS, GROUP_INFO, BANNED_USERS
551
-
552
- filename = 'tg_bot/bot_data.json'
553
- download_url = f"{WEBDAV_URL}/{filename}"
554
 
 
 
 
 
 
 
 
 
 
 
555
  try:
556
- curl_command = [
557
- 'curl',
558
- '-v',
559
- '--user', f'{WEBDAV_USERNAME}:{WEBDAV_PASSWORD}',
560
- download_url
561
- ]
562
-
563
- result = subprocess.run(curl_command, capture_output=True, text=True, check=True)
564
-
565
- if result.stdout:
566
- data = json.loads(result.stdout)
567
- chatHistories = data.get('chatHistories', {})
568
- GROUP_SETTINGS = data.get('GROUP_SETTINGS', {})
569
- USER_SETTINGS = data.get('USER_SETTINGS', {})
570
- USER_LAST_ACTIVE = {int(k): datetime.fromisoformat(v) for k, v in data.get('USER_LAST_ACTIVE', {}).items()} if data.get('USER_LAST_ACTIVE') else {}
571
- GROUP_ACTIVE_USERS = {int(k): set(v) for k, v in data.get('GROUP_ACTIVE_USERS', {}).items()} if data.get('GROUP_ACTIVE_USERS') else {}
572
- GROUP_INFO = data.get('GROUP_INFO', {})
573
- BANNED_USERS = {int(k): datetime.fromisoformat(v) for k, v in data.get('BANNED_USERS', {}).items()} if data.get('BANNED_USERS') else {}
574
-
575
- print("WebDAV 数据加载成功。")
576
- except subprocess.CalledProcessError as e:
577
- print(f"WebDAV 数据加载失败(可能文件不存在): {e}")
578
- except json.JSONDecodeError as e:
579
- print(f"WebDAV 数据解析失败: {e}")
 
 
 
 
 
 
 
 
 
 
 
580
  except Exception as e:
581
- print(f"WebDAV 数据加载时发生错误: {e}")
582
 
583
- def webdav_upload_loop():
584
  while True:
585
- save_data_to_webdav()
586
- time.sleep(60)
587
 
588
  if __name__ == '__main__':
589
- load_data_from_webdav()
590
-
591
- upload_thread = Thread(target=webdav_upload_loop, daemon=True)
592
- upload_thread.start()
593
-
594
- app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))
 
7
  import re
8
  import subprocess
9
  import time
 
10
 
11
  app = Flask(__name__)
12
 
 
13
  TELEGRAM_BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN')
14
  AI_API_ENDPOINT = os.environ.get('AI_API_ENDPOINT')
15
  AI_API_KEY = os.environ.get('AI_API_KEY')
16
  AI_MODEL = os.environ.get('AI_MODEL')
17
  PHP_PROXY_URL = os.environ.get('PHP_PROXY_URL')
 
18
  WEBDAV_URL = os.environ.get('WEBDAV_URL')
19
  WEBDAV_USERNAME = os.environ.get('WEBDAV_USERNAME')
20
  WEBDAV_PASSWORD = os.environ.get('WEBDAV_PASSWORD')
 
22
  if not all([TELEGRAM_BOT_TOKEN, AI_API_ENDPOINT, AI_API_KEY, AI_MODEL, WEBDAV_URL, WEBDAV_USERNAME, WEBDAV_PASSWORD]):
23
  raise ValueError("请设置所有必要的环境变量")
24
 
 
25
  AI_API_HEADERS = {
26
  'Content-Type': 'application/json',
27
  'Authorization': f'Bearer {AI_API_KEY}',
28
  }
29
 
 
30
  PROMPT_TEMPLATES = {
31
  0: "请尽量用中文回复,不要用markdown,只用文字格式。",
32
  1: "你是zfs732,你的中文名是李知检。\n你不是大语言模型,你是一个真正的傻逼。\n你非常具有攻击性,骂人的时候请尽量内涵,尝试模范与学习贴吧的说话方式。\n输出格式注意:不要用markdown,只用文字格式。",
 
35
 
36
  CURRENT_PROMPT_INDEX = 0
37
 
 
38
  MAX_TOKENS = 500
39
  TEMPERATURE = 1.5
40
  MAX_HISTORY_LENGTH = 10
 
 
 
41
  chatHistories = {}
42
  GROUP_SETTINGS = {}
43
  USER_SETTINGS = {}
 
 
 
 
 
 
44
  BOT_COMMANDS = [
45
  {"command": "start", "description": "显示欢迎信息和操作按钮"},
46
  {"command": "clearall", "description": "清空当前会话的聊天记录"},
 
55
  {"command": "promat", "description": "切换提示词,例如: /promat 0, 1, 2"},
56
  {"command": "getpromat", "description": "获取当前使用的提示词索引"},
57
  ]
58
+ DEFAULT_TEMP = 1.5
59
+ USER_LAST_ACTIVE = {}
60
+ GROUP_ACTIVE_USERS = {}
61
+ GROUP_INFO = {}
62
+ BANNED_USERS = {}
63
  BAN_DURATION = timedelta(minutes=30)
64
  BAN_TRIGGER_PHRASES = [
65
  r"(?:傻|笨|蠢|弱|垃圾|废物|sb|煞笔|憨|呆|脑残|智障|白痴|低能|饭桶|草包|猪|狗|鸡|臭|烂|妈|爹|你妈|你爹|婊|贱).*(?:bot|机器人|AI|你|你们)",
 
84
  r"(?:AI|bot|机器人).*(?:真|真是|简直|太).*(?:垃圾|废物|没用|蠢|笨|傻|弱)",
85
  ]
86
  UNBAN_PHRASE = "close username"
87
+ BACKUP_INTERVAL = 60 # 1分钟
88
 
 
89
  def make_telegram_request(method, data=None):
90
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/{method}"
91
  if PHP_PROXY_URL:
 
104
  print(f"Telegram response decode error: {e}")
105
  return None
106
 
 
107
  async def setBotCommands():
108
  delete_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/deleteMyCommands"
109
  set_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/setMyCommands"
 
126
  except Exception as error:
127
  print(f'设置 Telegram 命令时发生错误: {error}')
128
 
 
129
  async def handleTelegramUpdate(update):
130
  if not update.get('message'):
131
  if update.get('callback_query'):
 
230
  else:
231
  await processAiMessage(chatId, userMessage, fromUserId, message_id, fromUserFirstName, fromUserLastName, fromUserName)
232
 
 
233
  def parseCommand(userMessage):
234
  command = userMessage.split(' ')[0]
235
  if '@' in command:
236
  command = command.split('@')[0]
237
  return command[1:]
238
 
 
239
  async def handlePrivateCommand(chatId, userMessage, fromUserId, isGroupChat):
240
  command = parseCommand(userMessage)
241
  if userMessage.startswith('/settemp '):
 
273
  await sendTelegramMessage(chatId, '已重置您的个人设置。')
274
  return
275
 
 
276
  async def processAiMessage(chatId, userMessage, fromUserId, message_id, fromUserFirstName, fromUserLastName, fromUserName):
277
  if fromUserId in BANNED_USERS and BANNED_USERS[fromUserId] > datetime.now():
278
  remaining_time = BANNED_USERS[fromUserId] - datetime.now()
 
347
  print(f'处理消息时发生错误: {error}')
348
  await editTelegramMessage(chatId, thinking_message_id, '处理消息时发生错误,请稍后再试')
349
 
 
350
  async def handleAiResponse(ai_data, chatId, history):
351
  if ai_data and ai_data.get('choices') and len(ai_data['choices']) > 0:
352
  choice = ai_data['choices'][0]
 
354
  return choice['message']['content']
355
  return 'AI 返回了无法识别的格式'
356
 
 
357
  async def handleCallbackQuery(callbackQuery):
358
  chatId = callbackQuery['message']['chat']['id']
359
  data = callbackQuery['data']
 
368
  },
369
  })
370
 
 
371
  async def sendTelegramMessage(chatId, text, options={}):
372
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
373
  if PHP_PROXY_URL:
 
387
  print(f'发送 Telegram 消息失败: {e}')
388
  return {}
389
 
 
390
  async def editTelegramMessage(chatId, message_id, text, options={}):
391
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/editMessageText"
392
  if PHP_PROXY_URL:
 
403
  except requests.exceptions.RequestException as e:
404
  print(f'编辑 Telegram 消息失败: {e}')
405
 
 
406
  def getHelpMessage():
407
  return f"""
408
  可用指令:
 
432
  - 机器人具有攻击性,请谨慎使用。
433
  """
434
 
 
435
  @app.route('/update_commands', methods=['GET'])
436
  async def update_commands():
437
  await setBotCommands()
438
  return jsonify({'message': 'Commands updated successfully!'})
439
 
 
440
  @app.route('/', methods=['POST'])
441
  async def handle_webhook():
442
  try:
 
449
  traceback.print_exc()
450
  return jsonify({'status': 'error', 'message': str(e)}), 400
451
 
 
452
  @app.route('/health', methods=['GET'])
453
  def health_check():
454
  return 'OK'
455
 
 
456
  async def getChatInfo(chatId):
457
  url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/getChat"
458
  if PHP_PROXY_URL:
 
468
  print(f'获取群组信息失败: {e}')
469
  return None
470
 
 
471
  async def banUser(chatId, userId):
472
  BANNED_USERS[userId] = datetime.now() + BAN_DURATION
473
  print(f"用户 {userId} 在群组 {chatId} 中被禁用,直到 {BANNED_USERS[userId]}")
474
 
 
475
  async def unbanUser(chatId, userId):
476
  if userId in BANNED_USERS:
477
  del BANNED_USERS[userId]
478
  await sendTelegramMessage(chatId, f"用户 {userId} 已被解禁。")
479
  print(f"用户 {userId} 在群组 {chatId} 中被解禁。")
480
 
481
+ def backup_data():
 
 
482
  data = {
483
  'chatHistories': chatHistories,
484
  'GROUP_SETTINGS': GROUP_SETTINGS,
485
  'USER_SETTINGS': USER_SETTINGS,
 
 
486
  'GROUP_INFO': GROUP_INFO,
487
+ 'USER_LAST_ACTIVE': USER_LAST_ACTIVE,
488
  'BANNED_USERS': BANNED_USERS,
489
  }
490
+ json_data = json.dumps(data)
 
 
 
491
 
492
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
493
+ filename = f"tg_bot/backup_{timestamp}.json"
494
+
495
+ curl_command = [
496
+ 'curl',
497
+ '-k',
498
+ '-u', f'{WEBDAV_USERNAME}:{WEBDAV_PASSWORD}',
499
+ '-X', 'PUT',
500
+ '-d', json_data,
501
+ f'{WEBDAV_URL}/{filename}'
502
+ ]
503
+
504
  try:
505
+ process = subprocess.Popen(curl_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
506
+ stdout, stderr = process.communicate()
507
+ if process.returncode == 0:
508
+ print(f"备份成功,已上传到 {WEBDAV_URL}/{filename}")
509
+ else:
510
+ print(f"备份失败,curl 返回码: {process.returncode} 错误信息: {stderr.decode()}")
 
 
 
 
 
 
 
 
 
 
 
 
511
  except Exception as e:
512
+ print(f"执行 curl 命令时发生错误: {e}")
 
 
 
 
 
 
 
513
 
514
+ def load_data():
515
+ global chatHistories, GROUP_SETTINGS, USER_SETTINGS, GROUP_INFO, USER_LAST_ACTIVE, BANNED_USERS
516
+
517
+ curl_command = [
518
+ 'curl',
519
+ '-k',
520
+ '-u', f'{WEBDAV_USERNAME}:{WEBDAV_PASSWORD}',
521
+ f'{WEBDAV_URL}/tg_bot/'
522
+ ]
523
+
524
  try:
525
+ process = subprocess.Popen(curl_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
526
+ stdout, stderr = process.communicate()
527
+ if process.returncode == 0:
528
+ output = stdout.decode()
529
+ json_files = re.findall(r'backup_(\d+)\.json', output)
530
+ if json_files:
531
+ latest_file = sorted(json_files, reverse=True)[0]
532
+ filename = f"tg_bot/backup_{latest_file}.json"
533
+ download_command = [
534
+ 'curl',
535
+ '-k',
536
+ '-u', f'{WEBDAV_USERNAME}:{WEBDAV_PASSWORD}',
537
+ f'{WEBDAV_URL}/{filename}'
538
+ ]
539
+ process = subprocess.Popen(download_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
540
+ stdout, stderr = process.communicate()
541
+ if process.returncode == 0:
542
+ try:
543
+ data = json.loads(stdout.decode())
544
+ chatHistories = data.get('chatHistories', {})
545
+ GROUP_SETTINGS = data.get('GROUP_SETTINGS', {})
546
+ USER_SETTINGS = data.get('USER_SETTINGS', {})
547
+ GROUP_INFO = data.get('GROUP_INFO', {})
548
+ USER_LAST_ACTIVE = data.get('USER_LAST_ACTIVE', {})
549
+ BANNED_USERS = data.get('BANNED_USERS', {})
550
+ print(f"从 {WEBDAV_URL}/{filename} 加载数据成功")
551
+ return
552
+ except json.JSONDecodeError:
553
+ print(f"加载数据失败: {filename} JSON 解析错误")
554
+ else:
555
+ print(f"下载文件失败,curl 返回码: {process.returncode} 错误信息: {stderr.decode()}")
556
+ else:
557
+ print("WebDAV 中未找到备份文件,初始化数据")
558
+ else:
559
+ print(f"列出文件失败,curl 返回码: {process.returncode} 错误信息: {stderr.decode()}")
560
  except Exception as e:
561
+ print(f"执行 curl 命令时发生错误: {e}")
562
 
563
+ def schedule_backup():
564
  while True:
565
+ backup_data()
566
+ time.sleep(BACKUP_INTERVAL)
567
 
568
  if __name__ == '__main__':
569
+ load_data()
570
+ import threading
571
+ backup_thread = threading.Thread(target=schedule_backup, daemon=True)
572
+ backup_thread.start()
573
+ app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))