Update app.py
Browse files
app.py
CHANGED
|
@@ -1169,7 +1169,7 @@ def start_telethon_worker():
|
|
| 1169 |
if data_changed: await asyncio.to_thread(save_data)
|
| 1170 |
|
| 1171 |
# ===== 🌟 重写:多目标目录更新 =====
|
| 1172 |
-
|
| 1173 |
current_time = int(time.time())
|
| 1174 |
data_changed = False
|
| 1175 |
for uid, u_data in DATA.get("users", {}).items():
|
|
@@ -1218,85 +1218,108 @@ def start_telethon_worker():
|
|
| 1218 |
if msg_id_str in tags_map:
|
| 1219 |
del tags_map[msg_id_str]
|
| 1220 |
new_tags_found = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1221 |
|
| 1222 |
-
|
| 1223 |
-
|
| 1224 |
-
|
| 1225 |
-
|
| 1226 |
-
|
| 1227 |
-
|
| 1228 |
-
|
| 1229 |
-
|
| 1230 |
-
|
| 1231 |
-
|
| 1232 |
-
|
| 1233 |
-
|
| 1234 |
-
|
| 1235 |
-
|
| 1236 |
-
|
| 1237 |
-
|
| 1238 |
-
|
| 1239 |
-
|
| 1240 |
-
|
| 1241 |
-
|
| 1242 |
-
if py and len(py[0])>0: key = py[0][0].upper()
|
| 1243 |
-
except NameError: key = "中文"
|
| 1244 |
-
if key not in directory_map: directory_map[key] = []
|
| 1245 |
-
directory_map[key].append(tag)
|
| 1246 |
-
|
| 1247 |
-
# ===== 🔧 修复:不再嵌套 blockquote =====
|
| 1248 |
-
dir_lines = []
|
| 1249 |
-
keys = sorted(directory_map.keys())
|
| 1250 |
-
if "0-9" in keys: keys.remove("0-9"); keys.insert(0, "0-9")
|
| 1251 |
-
for key in keys:
|
| 1252 |
-
tags_line = " ".join([html.escape(t) for t in sorted(directory_map[key])])
|
| 1253 |
-
dir_lines.append(f"{key}: {tags_line}")
|
| 1254 |
|
| 1255 |
-
|
| 1256 |
-
now_str = datetime.now(beijing_tz).strftime("%m-%d %H:%M")
|
| 1257 |
|
| 1258 |
-
|
| 1259 |
-
|
| 1260 |
-
dir_text = f"<blockquote expandable>{dir_body}</blockquote>\n⏳ <code>最后更新: {now_str} (北京时间)</code>"
|
| 1261 |
|
| 1262 |
-
|
| 1263 |
-
safe_title_with_count = f"{html.escape(task_name)} ({len(active_tags)})"
|
| 1264 |
|
| 1265 |
-
|
| 1266 |
-
|
| 1267 |
-
|
| 1268 |
-
|
| 1269 |
-
tgt_key = f"{tgt_ch}_{tgt_msg}"
|
| 1270 |
|
| 1271 |
-
|
| 1272 |
-
|
| 1273 |
-
|
| 1274 |
-
|
|
|
|
|
|
|
| 1275 |
|
| 1276 |
-
try:
|
| 1277 |
-
original_msg = await TL_CLIENT.get_messages(tgt_ch, ids=tgt_msg)
|
| 1278 |
-
if not original_msg:
|
| 1279 |
-
print(f"⚠️ [目录] 无法获取消息 {tgt_ch}/{tgt_msg}")
|
| 1280 |
-
continue
|
| 1281 |
-
if original_msg.raw_text:
|
| 1282 |
-
raw_html = tl_html.unparse(original_msg.raw_text, original_msg.entities)
|
| 1283 |
-
base_html = raw_html.split("➖➖➖➖➖➖")[0].rstrip() if "➖➖➖➖➖➖" in raw_html else raw_html.rstrip()
|
| 1284 |
-
else: base_html = ""
|
| 1285 |
-
new_message_text = f"{base_html}{SEPARATOR_MARK}<b>{safe_title_with_count}</b>\n{dir_text}"
|
| 1286 |
-
if len(new_message_text) > 4000: new_message_text = new_message_text[:3900] + "\n</blockquote>\n⚠️ 目录过长已截断"
|
| 1287 |
-
|
| 1288 |
-
if original_msg.photo or original_msg.video or original_msg.document:
|
| 1289 |
-
bot.edit_message_caption(caption=new_message_text, chat_id=tgt_ch, message_id=tgt_msg, parse_mode="HTML")
|
| 1290 |
-
else:
|
| 1291 |
-
bot.edit_message_text(text=new_message_text, chat_id=tgt_ch, message_id=tgt_msg, parse_mode="HTML")
|
| 1292 |
-
last_html_per_target[tgt_key] = content_hash
|
| 1293 |
-
data_changed = True
|
| 1294 |
-
print(f"✅ [目录] 已更新 {tgt_ch}/{tgt_msg},标签数: {len(active_tags)}")
|
| 1295 |
-
except Exception as e:
|
| 1296 |
-
print(f"❌ [目录] 更新失败 {tgt_ch}/{tgt_msg}: {e}")
|
| 1297 |
-
await asyncio.sleep(2)
|
| 1298 |
-
except Exception as e:
|
| 1299 |
-
print(f"❌ [目录] 扫描异常 scan={scan_id}: {e}")
|
| 1300 |
if data_changed: await asyncio.to_thread(save_data)
|
| 1301 |
|
| 1302 |
TL_CLIENT.start()
|
|
|
|
| 1169 |
if data_changed: await asyncio.to_thread(save_data)
|
| 1170 |
|
| 1171 |
# ===== 🌟 重写:多目标目录更新 =====
|
| 1172 |
+
async def update_channel_dirs():
|
| 1173 |
current_time = int(time.time())
|
| 1174 |
data_changed = False
|
| 1175 |
for uid, u_data in DATA.get("users", {}).items():
|
|
|
|
| 1218 |
if msg_id_str in tags_map:
|
| 1219 |
del tags_map[msg_id_str]
|
| 1220 |
new_tags_found = True
|
| 1221 |
+
except Exception as e:
|
| 1222 |
+
print(f"❌ [目录] 扫描异常 scan={scan_id}: {e}")
|
| 1223 |
+
continue
|
| 1224 |
+
|
| 1225 |
+
task['last_run'] = current_time
|
| 1226 |
+
|
| 1227 |
+
# ===== 🔧 修复核心:标签变化时重建缓存 =====
|
| 1228 |
+
if new_tags_found or is_first_run:
|
| 1229 |
+
task['tags_map'] = tags_map
|
| 1230 |
+
task['scanned_msgs'] = scanned_msgs
|
| 1231 |
+
data_changed = True
|
| 1232 |
+
all_tags = set()
|
| 1233 |
+
for t_list in tags_map.values(): all_tags.update(t_list)
|
| 1234 |
+
active_tags = [t for t in all_tags if t not in blacklist]
|
| 1235 |
+
task['tags_cache'] = active_tags
|
| 1236 |
+
|
| 1237 |
+
# 构建目录文本
|
| 1238 |
+
directory_map = {}
|
| 1239 |
+
for tag in active_tags:
|
| 1240 |
+
clean_str = tag[1:]
|
| 1241 |
+
if not clean_str: continue
|
| 1242 |
+
fc = clean_str[0]
|
| 1243 |
+
key = "#"
|
| 1244 |
+
if fc.isalpha() and fc.isascii(): key = fc.upper()
|
| 1245 |
+
elif fc.isdigit(): key = "0-9"
|
| 1246 |
+
elif '\u4e00' <= fc <= '\u9fff':
|
| 1247 |
+
try:
|
| 1248 |
+
py = lazy_pinyin(fc)
|
| 1249 |
+
if py and len(py[0]) > 0: key = py[0][0].upper()
|
| 1250 |
+
except NameError: key = "中文"
|
| 1251 |
+
if key not in directory_map: directory_map[key] = []
|
| 1252 |
+
directory_map[key].append(tag)
|
| 1253 |
+
|
| 1254 |
+
dir_lines = []
|
| 1255 |
+
keys = sorted(directory_map.keys())
|
| 1256 |
+
if "0-9" in keys: keys.remove("0-9"); keys.insert(0, "0-9")
|
| 1257 |
+
for key in keys:
|
| 1258 |
+
tags_line = " ".join([html.escape(t) for t in sorted(directory_map[key])])
|
| 1259 |
+
dir_lines.append(f"{key}: {tags_line}")
|
| 1260 |
+
|
| 1261 |
+
# 🔧 关键修复:只用一层 blockquote,不嵌套
|
| 1262 |
+
dir_body = "\n".join(dir_lines)
|
| 1263 |
+
task['_dir_body_cache'] = dir_body
|
| 1264 |
+
task['_dir_count_cache'] = len(active_tags)
|
| 1265 |
+
print(f"📂 [目录] 重建缓存: {len(active_tags)} 个标签")
|
| 1266 |
+
|
| 1267 |
+
# ===== 🔧 修复核心2:每轮都检查目标是否需要推送 =====
|
| 1268 |
+
dir_body = task.get('_dir_body_cache', '')
|
| 1269 |
+
tag_count = task.get('_dir_count_cache', 0)
|
| 1270 |
+
if not dir_body and not tag_count:
|
| 1271 |
+
continue
|
| 1272 |
+
|
| 1273 |
+
beijing_tz = timezone(timedelta(hours=8))
|
| 1274 |
+
now_str = datetime.now(beijing_tz).strftime("%m-%d %H:%M")
|
| 1275 |
+
task_name = task.get('task_name', '标签目录')
|
| 1276 |
+
safe_title = f"{html.escape(task_name)} ({tag_count})"
|
| 1277 |
+
dir_text = f"<blockquote expandable>{dir_body}</blockquote>\n⏳ <code>最后更新: {now_str} (北京时间)</code>"
|
| 1278 |
+
|
| 1279 |
+
# 用标签数量+内容做指纹,不含时间戳
|
| 1280 |
+
content_fingerprint = f"{tag_count}|{dir_body}"
|
| 1281 |
+
last_html_per_target = task.setdefault('last_html_per_target', {})
|
| 1282 |
|
| 1283 |
+
for tgt in targets:
|
| 1284 |
+
tgt_ch = int(tgt['channel_id'])
|
| 1285 |
+
tgt_msg = int(tgt['msg_id'])
|
| 1286 |
+
tgt_key = f"{tgt_ch}_{tgt_msg}"
|
| 1287 |
+
|
| 1288 |
+
if last_html_per_target.get(tgt_key) == content_fingerprint:
|
| 1289 |
+
continue
|
| 1290 |
+
|
| 1291 |
+
print(f"📝 [目录] 正在推送到 {tgt_ch}/{tgt_msg}...")
|
| 1292 |
+
try:
|
| 1293 |
+
original_msg = await TL_CLIENT.get_messages(tgt_ch, ids=tgt_msg)
|
| 1294 |
+
if not original_msg:
|
| 1295 |
+
print(f"⚠️ [目录] 消息 {tgt_ch}/{tgt_msg} 不存在")
|
| 1296 |
+
continue
|
| 1297 |
+
|
| 1298 |
+
if original_msg.raw_text:
|
| 1299 |
+
raw_html = tl_html.unparse(original_msg.raw_text, original_msg.entities)
|
| 1300 |
+
base_html = raw_html.split("➖➖➖➖➖➖")[0].rstrip() if "➖➖➖➖➖➖" in raw_html else raw_html.rstrip()
|
| 1301 |
+
else:
|
| 1302 |
+
base_html = ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1303 |
|
| 1304 |
+
new_message_text = f"{base_html}{SEPARATOR_MARK}<b>{safe_title}</b>\n{dir_text}"
|
|
|
|
| 1305 |
|
| 1306 |
+
if len(new_message_text) > 4000:
|
| 1307 |
+
new_message_text = new_message_text[:3900] + "\n</blockquote>\n⚠️ 目录过长已截断"
|
|
|
|
| 1308 |
|
| 1309 |
+
print(f"📏 [目录] 消息长度: {len(new_message_text)} 字符")
|
|
|
|
| 1310 |
|
| 1311 |
+
if original_msg.photo or original_msg.video or original_msg.document:
|
| 1312 |
+
bot.edit_message_caption(caption=new_message_text, chat_id=tgt_ch, message_id=tgt_msg, parse_mode="HTML")
|
| 1313 |
+
else:
|
| 1314 |
+
bot.edit_message_text(text=new_message_text, chat_id=tgt_ch, message_id=tgt_msg, parse_mode="HTML")
|
|
|
|
| 1315 |
|
| 1316 |
+
last_html_per_target[tgt_key] = content_fingerprint
|
| 1317 |
+
data_changed = True
|
| 1318 |
+
print(f"✅ [目录] 成功更新 {tgt_ch}/{tgt_msg},标签数: {tag_count}")
|
| 1319 |
+
except Exception as e:
|
| 1320 |
+
print(f"❌ [目录] 推送失败 {tgt_ch}/{tgt_msg}: {e}")
|
| 1321 |
+
await asyncio.sleep(2)
|
| 1322 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1323 |
if data_changed: await asyncio.to_thread(save_data)
|
| 1324 |
|
| 1325 |
TL_CLIENT.start()
|