ljx77qaq commited on
Commit
c4a8cfb
·
verified ·
1 Parent(s): b2b2590

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -27
app.py CHANGED
@@ -1224,7 +1224,6 @@ def start_telethon_worker():
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
@@ -1234,7 +1233,6 @@ def start_telethon_worker():
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:]
@@ -1251,35 +1249,93 @@ def start_telethon_worker():
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'])
@@ -1301,14 +1357,62 @@ def start_telethon_worker():
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")
 
1224
 
1225
  task['last_run'] = current_time
1226
 
 
1227
  if new_tags_found or is_first_run:
1228
  task['tags_map'] = tags_map
1229
  task['scanned_msgs'] = scanned_msgs
 
1233
  active_tags = [t for t in all_tags if t not in blacklist]
1234
  task['tags_cache'] = active_tags
1235
 
 
1236
  directory_map = {}
1237
  for tag in active_tags:
1238
  clean_str = tag[1:]
 
1249
  if key not in directory_map: directory_map[key] = []
1250
  directory_map[key].append(tag)
1251
 
1252
+ keys_sorted = sorted(directory_map.keys())
1253
+ if "0-9" in keys_sorted: keys_sorted.remove("0-9"); keys_sorted.insert(0, "0-9")
 
 
 
 
1254
 
1255
+ task['_dir_map_cache'] = directory_map
1256
+ task['_dir_keys_cache'] = keys_sorted
 
1257
  task['_dir_count_cache'] = len(active_tags)
1258
  print(f"📂 [目录] 重建缓存: {len(active_tags)} 个标签")
1259
 
1260
+ directory_map = task.get('_dir_map_cache', {})
1261
+ keys_sorted = task.get('_dir_keys_cache', [])
1262
  tag_count = task.get('_dir_count_cache', 0)
1263
+ if not directory_map and not tag_count:
1264
  continue
1265
 
1266
  beijing_tz = timezone(timedelta(hours=8))
1267
  now_str = datetime.now(beijing_tz).strftime("%m-%d %H:%M")
1268
  task_name = task.get('task_name', '标签目录')
1269
+ safe_title = html.escape(task_name)
1270
+ content_fingerprint = f"{tag_count}|{'|'.join(keys_sorted)}"
 
 
 
1271
  last_html_per_target = task.setdefault('last_html_per_target', {})
1272
 
1273
+ # ===== 生成外部网页 HTML =====
1274
+ sections_html = ""
1275
+ for key in keys_sorted:
1276
+ tags_in_group = sorted(directory_map.get(key, []))
1277
+ tags_chips = ""
1278
+ for t in tags_in_group:
1279
+ safe_t = html.escape(t)
1280
+ # tg://search 协议让标签在 Telegram 内可搜索
1281
+ tags_chips += f'<a href="tg://search?query={html.escape(t)}" class="tag">{safe_t}</a>'
1282
+ sections_html += f'<div class="section"><div class="section-title">{html.escape(key)}</div><div class="tags">{tags_chips}</div></div>'
1283
+
1284
+ page_html = f"""<!DOCTYPE html>
1285
+ <html lang="zh-CN">
1286
+ <head>
1287
+ <meta charset="UTF-8">
1288
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1289
+ <title>完整目录 - {safe_title}</title>
1290
+ <style>
1291
+ body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #1a1a2e; color: #eaeaea; padding: 15px; margin: 0; }}
1292
+ .container {{ max-width: 600px; margin: 0 auto; background: #16213e; border-radius: 12px; padding: 15px; box-shadow: 0 4px 15px rgba(0,0,0,0.3); }}
1293
+ h2 {{ text-align: center; color: #fff; margin-bottom: 20px; font-size: 18px; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 10px; line-height: 1.5; }}
1294
+ .search-box {{ width: 100%; padding: 10px 14px; background: #1a1a2e; border: 1px solid rgba(255,255,255,0.1); border-radius: 10px; color: #eaeaea; font-size: 14px; outline: none; margin-bottom: 15px; box-sizing: border-box; }}
1295
+ .search-box:focus {{ border-color: #e94560; }}
1296
+ .search-box::placeholder {{ color: #8a8a9a; }}
1297
+ .section {{ margin-bottom: 16px; }}
1298
+ .section-title {{ font-size: 15px; font-weight: 700; color: #e94560; margin-bottom: 8px; padding-left: 4px; border-left: 3px solid #e94560; padding-left: 8px; }}
1299
+ .tags {{ display: flex; flex-wrap: wrap; gap: 8px; }}
1300
+ .tag {{ display: inline-block; padding: 6px 12px; background: rgba(255,255,255,0.06); border-radius: 20px; font-size: 13px; color: #5dade2; text-decoration: none; transition: all 0.2s; border: 1px solid rgba(255,255,255,0.08); }}
1301
+ .tag:active {{ background: rgba(233,69,96,0.2); border-color: #e94560; }}
1302
+ .tag.hidden {{ display: none; }}
1303
+ .stats {{ text-align: center; color: #8a8a9a; font-size: 12px; margin-top: 15px; padding-top: 10px; border-top: 1px solid rgba(255,255,255,0.06); }}
1304
+ .section.hidden {{ display: none; }}
1305
+ .no-result {{ text-align: center; color: #8a8a9a; padding: 30px; display: none; }}
1306
+ </style>
1307
+ </head>
1308
+ <body>
1309
+ <div class="container">
1310
+ <h2>🗂️ {safe_title}<br><span style="font-size:12px;color:#8a8a9a;font-weight:normal">共 {tag_count} 个标签 | 更新于 {now_str}</span></h2>
1311
+ <input type="text" class="search-box" placeholder="🔍 搜索标签..." oninput="filterTags(this.value)">
1312
+ <div id="noResult" class="no-result">😔 没有找到匹配的标签</div>
1313
+ {sections_html}
1314
+ <div class="stats">💡 点击标签可在 Telegram 内搜索</div>
1315
+ </div>
1316
+ <script>
1317
+ function filterTags(q) {{
1318
+ q = q.toLowerCase().trim();
1319
+ const sections = document.querySelectorAll('.section');
1320
+ const noResult = document.getElementById('noResult');
1321
+ let totalVisible = 0;
1322
+ sections.forEach(sec => {{
1323
+ const tags = sec.querySelectorAll('.tag');
1324
+ let visible = 0;
1325
+ tags.forEach(tag => {{
1326
+ const match = !q || tag.textContent.toLowerCase().includes(q);
1327
+ tag.classList.toggle('hidden', !match);
1328
+ if (match) visible++;
1329
+ }});
1330
+ sec.classList.toggle('hidden', visible === 0);
1331
+ totalVisible += visible;
1332
+ }});
1333
+ noResult.style.display = totalVisible === 0 && q ? 'block' : 'none';
1334
+ }}
1335
+ </script>
1336
+ </body>
1337
+ </html>"""
1338
+
1339
  for tgt in targets:
1340
  tgt_ch = int(tgt['channel_id'])
1341
  tgt_msg = int(tgt['msg_id'])
 
1357
  else:
1358
  base_html = ""
1359
 
1360
+ # 把网页存入缓存
1361
+ cache_key = f"dir_{tgt_ch}_{tgt_msg}"
1362
+ HTML_CACHE[cache_key] = page_html
1363
+
1364
+ space_host = "bangdan.nine7.cc.cd"
1365
+ dir_link = f"https://{space_host}/list/{cache_key}"
1366
+
1367
+ # ===== 构建精简消息(兼容 caption 1024 字符限制)=====
1368
+ # 先尝试放一些热门分类摘要
1369
+ preview_lines = []
1370
+ chars_used = 0
1371
+ max_preview_chars = 600 if not (original_msg.photo or original_msg.video or original_msg.document) else 300
1372
+ for key in keys_sorted:
1373
+ tags_in_group = sorted(directory_map.get(key, []))
1374
+ line = f"{key}: {' '.join(tags_in_group)}"
1375
+ if chars_used + len(line) > max_preview_chars:
1376
+ preview_lines.append(f"... 共 {len(keys_sorted)} 个分类")
1377
+ break
1378
+ preview_lines.append(line)
1379
+ chars_used += len(line)
1380
+
1381
+ preview_text = "\n".join(preview_lines)
1382
+
1383
+ dir_section = (
1384
+ f"<b>{safe_title} ({tag_count}) "
1385
+ f"<a href='{dir_link}'>📖 完整目录</a></b>\n"
1386
+ f"<blockquote expandable>{html.escape(preview_text)}</blockquote>\n"
1387
+ f"⏳ <code>最后更新: {now_str}</code>"
1388
+ )
1389
+
1390
+ new_message_text = f"{base_html}{SEPARATOR_MARK}{dir_section}"
1391
+
1392
+ # 如果是媒体消息,caption 限制 1024
1393
+ is_media = original_msg.photo or original_msg.video or original_msg.document
1394
+ char_limit = 1024 if is_media else 4096
1395
+
1396
+ if len(new_message_text) > char_limit:
1397
+ # 超限就只放标题+链接
1398
+ short_section = (
1399
+ f"<b>{safe_title} ({tag_count}) "
1400
+ f"<a href='{dir_link}'>📖 完整目录</a></b>\n"
1401
+ f"⏳ <code>最后更新: {now_str}</code>"
1402
+ )
1403
+ new_message_text = f"{base_html}{SEPARATOR_MARK}{short_section}"
1404
+
1405
+ # 终极保险:如果 base_html 本身就很长
1406
+ if len(new_message_text) > char_limit:
1407
+ new_message_text = (
1408
+ f"<b>{safe_title} ({tag_count}) "
1409
+ f"<a href='{dir_link}'>📖 完整目录</a></b>\n"
1410
+ f"⏳ <code>最后更新: {now_str}</code>"
1411
+ )
1412
+
1413
+ print(f"📏 [目录] 消息长度: {len(new_message_text)}/{char_limit}")
1414
+
1415
+ if is_media:
1416
  bot.edit_message_caption(caption=new_message_text, chat_id=tgt_ch, message_id=tgt_msg, parse_mode="HTML")
1417
  else:
1418
  bot.edit_message_text(text=new_message_text, chat_id=tgt_ch, message_id=tgt_msg, parse_mode="HTML")