bep40 commited on
Commit
5190f38
·
verified ·
1 Parent(s): 9387935

fix: expand all_parts into separate slides in TikTok feed

Browse files
Files changed (1) hide show
  1. app_wrapper.py +21 -32
app_wrapper.py CHANGED
@@ -53,12 +53,7 @@ _orig_render_video_slider = getattr(app, 'render_video_slider_html', None)
53
  if _orig_render_video_slider:
54
  def _patched_render_video_slider(videos):
55
  html = _orig_render_video_slider(videos)
56
- # Replace bdpOpenTikTok('url','aid') with bdpOpen('url','aid','')
57
- # The original has: window.bdpOpenTikTok('url','aid')
58
- # We need: window.bdpOpen('url','aid','')
59
  html = html.replace("window.bdpOpenTikTok(", "window.bdpOpen(")
60
- # Now fix: bdpOpen('url','aid') needs third param → add ,'')
61
- # Pattern: bdpOpen('...','...') → bdpOpen('...','...','')
62
  html = _re.sub(
63
  r"window\.bdpOpen\('([^']+)','([^']+)'\)",
64
  r"window.bdpOpen('\1','\2','')",
@@ -101,66 +96,51 @@ _orig_read_article = app.read_article
101
  def _patched_read_article(url):
102
  if not url or url == "#" or len(url) < 10:
103
  return "<p>Không tìm thấy bài viết.</p>"
104
-
105
- # 24h URLs → TikTok feed with all 24h highlight videos
106
  if "24h.com.vn" in url:
107
  result = _render_24h_tiktok_feed(url)
108
  if result:
109
  return result
110
-
111
- # BDP video URLs → BDP TikTok feed
112
  if "bongdaplus.vn/video/" in url:
113
  result = _render_bdp_tiktok_feed(url)
114
  if result:
115
  return result
116
-
117
  return _orig_read_article(url)
118
 
119
  def _render_bdp_tiktok_feed(current_url):
120
- """Render BDP video in TikTok feed style."""
121
  from concurrent.futures import ThreadPoolExecutor, as_completed
122
-
123
  try:
124
  bdp_list = app.scrape_bdp_video_list()[:15]
125
  except:
126
  return None
127
-
128
  if not bdp_list:
129
  return None
130
-
131
  def _fetch_bdp(art):
132
  vid_id = app._extract_bdp_video_id(art["link"])
133
  if not vid_id: return None
134
  embed = app.fetch_bdp_embed_data(vid_id)
135
  if not embed or not embed.get("mp4"): return None
136
- return {"title": art["title"], "link": art["link"], "img": art.get("img",""),
137
- "src": embed["mp4"], "poster": embed.get("poster",""), "vtype": "mp4"}
138
-
139
  videos = []
140
  with ThreadPoolExecutor(max_workers=6) as ex:
141
  futures = {ex.submit(_fetch_bdp, a): a for a in bdp_list}
142
  for f in as_completed(futures):
143
  try:
144
  r = f.result()
145
- if r: videos.append(r)
146
  except: pass
147
-
148
  if not videos:
149
  return None
150
-
151
  return _build_tiktok_html(videos, current_url, "BDP")
152
 
153
  def _render_24h_tiktok_feed(current_url):
154
- """Render 24h video in TikTok feed style using highlight list (more videos)."""
155
  from concurrent.futures import ThreadPoolExecutor, as_completed
156
 
157
- # Use highlight list (has more video content than shorts)
158
  try:
159
  all_articles = app.scrape_24h_video_list()[:20]
160
  except:
161
  all_articles = []
162
-
163
- # Also add shorts if highlight list is short
164
  if len(all_articles) < 10:
165
  try:
166
  shorts = scrape_24h_news_shorts()[:10]
@@ -169,16 +149,27 @@ def _render_24h_tiktok_feed(current_url):
169
  if s["link"] not in seen:
170
  all_articles.append(s)
171
  except: pass
172
-
173
  if not all_articles:
174
  return None
175
 
176
  def _fetch_video(art):
 
177
  vid = _extract_24h_video_url(art["link"])
178
- if vid:
179
- return {"title": art["title"], "link": art["link"], "img": art.get("img",""),
180
- "src": vid["src"], "poster": vid["poster"], "vtype": vid["vtype"]}
181
- return None
 
 
 
 
 
 
 
 
 
 
 
182
 
183
  videos = []
184
  with ThreadPoolExecutor(max_workers=8) as ex:
@@ -186,12 +177,11 @@ def _render_24h_tiktok_feed(current_url):
186
  for f in as_completed(futures):
187
  try:
188
  r = f.result()
189
- if r: videos.append(r)
190
  except: pass
191
 
192
  if not videos:
193
  return None
194
-
195
  return _build_tiktok_html(videos, current_url, "24h")
196
 
197
  def _build_tiktok_html(videos, current_url, source_label):
@@ -246,7 +236,6 @@ def _build_tiktok_html(videos, current_url, source_label):
246
  <span class="tiktok-counter">{vi+1}/{len(ordered)}</span>
247
  </div>''')
248
 
249
- # Video list cards below
250
  list_cards = []
251
  for v in ordered:
252
  img = app.safe_url(v.get("img") or v.get("poster",""))
 
53
  if _orig_render_video_slider:
54
  def _patched_render_video_slider(videos):
55
  html = _orig_render_video_slider(videos)
 
 
 
56
  html = html.replace("window.bdpOpenTikTok(", "window.bdpOpen(")
 
 
57
  html = _re.sub(
58
  r"window\.bdpOpen\('([^']+)','([^']+)'\)",
59
  r"window.bdpOpen('\1','\2','')",
 
96
  def _patched_read_article(url):
97
  if not url or url == "#" or len(url) < 10:
98
  return "<p>Không tìm thấy bài viết.</p>"
 
 
99
  if "24h.com.vn" in url:
100
  result = _render_24h_tiktok_feed(url)
101
  if result:
102
  return result
 
 
103
  if "bongdaplus.vn/video/" in url:
104
  result = _render_bdp_tiktok_feed(url)
105
  if result:
106
  return result
 
107
  return _orig_read_article(url)
108
 
109
  def _render_bdp_tiktok_feed(current_url):
 
110
  from concurrent.futures import ThreadPoolExecutor, as_completed
 
111
  try:
112
  bdp_list = app.scrape_bdp_video_list()[:15]
113
  except:
114
  return None
 
115
  if not bdp_list:
116
  return None
 
117
  def _fetch_bdp(art):
118
  vid_id = app._extract_bdp_video_id(art["link"])
119
  if not vid_id: return None
120
  embed = app.fetch_bdp_embed_data(vid_id)
121
  if not embed or not embed.get("mp4"): return None
122
+ return [{"title": art["title"], "link": art["link"], "img": art.get("img",""),
123
+ "src": embed["mp4"], "poster": embed.get("poster",""), "vtype": "mp4"}]
 
124
  videos = []
125
  with ThreadPoolExecutor(max_workers=6) as ex:
126
  futures = {ex.submit(_fetch_bdp, a): a for a in bdp_list}
127
  for f in as_completed(futures):
128
  try:
129
  r = f.result()
130
+ if r: videos.extend(r)
131
  except: pass
 
132
  if not videos:
133
  return None
 
134
  return _build_tiktok_html(videos, current_url, "BDP")
135
 
136
  def _render_24h_tiktok_feed(current_url):
137
+ """Render 24h video in TikTok feed. Expands multi-part videos into separate slides."""
138
  from concurrent.futures import ThreadPoolExecutor, as_completed
139
 
 
140
  try:
141
  all_articles = app.scrape_24h_video_list()[:20]
142
  except:
143
  all_articles = []
 
 
144
  if len(all_articles) < 10:
145
  try:
146
  shorts = scrape_24h_news_shorts()[:10]
 
149
  if s["link"] not in seen:
150
  all_articles.append(s)
151
  except: pass
 
152
  if not all_articles:
153
  return None
154
 
155
  def _fetch_video(art):
156
+ """Fetch video - returns LIST of dicts (multiple parts if found)."""
157
  vid = _extract_24h_video_url(art["link"])
158
+ if not vid:
159
+ return []
160
+ results = []
161
+ all_parts = vid.get("all_parts", [vid["src"]])
162
+ for pi, part_url in enumerate(all_parts):
163
+ label = f" (Phần {pi+1})" if len(all_parts) > 1 else ""
164
+ results.append({
165
+ "title": art["title"] + label,
166
+ "link": art["link"],
167
+ "img": art.get("img", ""),
168
+ "src": part_url,
169
+ "poster": vid["poster"],
170
+ "vtype": vid["vtype"]
171
+ })
172
+ return results
173
 
174
  videos = []
175
  with ThreadPoolExecutor(max_workers=8) as ex:
 
177
  for f in as_completed(futures):
178
  try:
179
  r = f.result()
180
+ if r: videos.extend(r)
181
  except: pass
182
 
183
  if not videos:
184
  return None
 
185
  return _build_tiktok_html(videos, current_url, "24h")
186
 
187
  def _build_tiktok_html(videos, current_url, source_label):
 
236
  <span class="tiktok-counter">{vi+1}/{len(ordered)}</span>
237
  </div>''')
238
 
 
239
  list_cards = []
240
  for v in ordered:
241
  img = app.safe_url(v.get("img") or v.get("poster",""))