bep40 commited on
Commit
e4ea4a9
·
verified ·
1 Parent(s): f013786

temp: patch script (will be replaced)

Browse files
Files changed (1) hide show
  1. patch_shorts.py +159 -0
patch_shorts.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Patch script: adds 24h news shorts to homepage.
3
+ Run this to generate the patched app.py.
4
+ """
5
+ import re
6
+
7
+ # Read current app.py
8
+ with open('app.py', 'r', encoding='utf-8') as f:
9
+ content = f.read()
10
+
11
+ # 1. Add scrape_24h_news_video_list() after scrape_24h_video_list()
12
+ new_scraper = '''
13
+ def scrape_24h_news_video_list():
14
+ """Scrape 24h.com.vn video tin tuc (shorts/news) page."""
15
+ try:
16
+ url = f"{BASE_24H}/video/video-tin-tuc-cvd769.html"
17
+ r = requests.get(url, headers=HEADERS, timeout=15); r.encoding="utf-8"
18
+ soup = BeautifulSoup(r.text, "lxml")
19
+ articles, seen = [], set()
20
+ for art in soup.find_all("article"):
21
+ a = art.find("a", href=True)
22
+ if not a: continue
23
+ href = a.get("href","")
24
+ if not href.startswith("http"): href = BASE_24H + href
25
+ if href in seen: continue
26
+ img_tag = art.find("img")
27
+ title = ""
28
+ if img_tag: title = img_tag.get("alt","")
29
+ if not title: title = a.get("title","") or a.get_text(strip=True)
30
+ if not title or len(title) < 10: continue
31
+ img_src = None
32
+ if img_tag:
33
+ for attr in ["data-original","data-src","src"]:
34
+ v = img_tag.get(attr,"")
35
+ if v and "base64" not in v and len(v) > 20:
36
+ img_src = v; break
37
+ seen.add(href)
38
+ articles.append({"title": title, "link": href, "img": img_src, "summary": "", "time": "",
39
+ "featured": False, "source": "24h", "group": "Shorts Tin T\\u1ee9c", "is_video": True})
40
+ return articles[:20]
41
+ except:
42
+ return []
43
+ '''
44
+
45
+ # Insert after scrape_24h_video_list function (find the end of it)
46
+ marker = "def scrape_24h_article(url):"
47
+ content = content.replace(marker, new_scraper + "\n" + marker)
48
+
49
+ # 2. Modify fetch_homepage to also fetch news shorts
50
+ old_fetch_homepage = '''def fetch_homepage():
51
+ all_articles=[]
52
+ h24_videos=[]
53
+ def _fetch(src,url,group):
54
+ arts=scrape_bdp_list(url) if src=="bdp" else scrape_vne_list(url)
55
+ for a in arts: a["group"]=group
56
+ return arts
57
+ def _fetch_24h():
58
+ nonlocal h24_videos
59
+ try: h24_videos=scrape_24h_video_list()[:15]
60
+ except: pass
61
+ with ThreadPoolExecutor(max_workers=6) as ex:
62
+ ex.submit(_fetch_24h)
63
+ futures={ex.submit(_fetch,s,u,g):g for s,u,g in HOMEPAGE_SOURCES}
64
+ for f in as_completed(futures):
65
+ try: all_articles.extend(f.result())
66
+ except: pass
67
+ return all_articles, h24_videos'''
68
+
69
+ new_fetch_homepage = '''def fetch_homepage():
70
+ all_articles=[]
71
+ h24_videos=[]
72
+ h24_shorts=[]
73
+ def _fetch(src,url,group):
74
+ arts=scrape_bdp_list(url) if src=="bdp" else scrape_vne_list(url)
75
+ for a in arts: a["group"]=group
76
+ return arts
77
+ def _fetch_24h():
78
+ nonlocal h24_videos
79
+ try: h24_videos=scrape_24h_video_list()[:15]
80
+ except: pass
81
+ def _fetch_shorts():
82
+ nonlocal h24_shorts
83
+ try: h24_shorts=scrape_24h_news_video_list()[:15]
84
+ except: pass
85
+ with ThreadPoolExecutor(max_workers=7) as ex:
86
+ ex.submit(_fetch_24h)
87
+ ex.submit(_fetch_shorts)
88
+ futures={ex.submit(_fetch,s,u,g):g for s,u,g in HOMEPAGE_SOURCES}
89
+ for f in as_completed(futures):
90
+ try: all_articles.extend(f.result())
91
+ except: pass
92
+ return all_articles, h24_videos, h24_shorts'''
93
+
94
+ content = content.replace(old_fetch_homepage, new_fetch_homepage)
95
+
96
+ # 3. Update fetch_news_list to pass shorts
97
+ old_home_call = ''' if src=="mix" and url_or_key=="home":
98
+ articles, h24_videos = fetch_homepage()
99
+ return render_homepage_html(articles, h24_videos)'''
100
+ new_home_call = ''' if src=="mix" and url_or_key=="home":
101
+ articles, h24_videos, h24_shorts = fetch_homepage()
102
+ return render_homepage_html(articles, h24_videos, h24_shorts)'''
103
+ content = content.replace(old_home_call, new_home_call)
104
+
105
+ # 4. Add render_shorts_carousel_html function before render_video_carousel_html
106
+ shorts_carousel_fn = '''
107
+ def render_shorts_carousel_html(shorts):
108
+ """Carousel shorts tin tuc 24h - displayed at very top of homepage."""
109
+ vids_with_img = [v for v in shorts if v.get("img")]
110
+ if not vids_with_img: return ""
111
+ items = []
112
+ for i, v in enumerate(vids_with_img[:15]):
113
+ img = safe_url(v.get("img",""))
114
+ link = v.get("link","#")
115
+ title = v.get("title","")
116
+ aid = make_id(link); sl = slug(title)
117
+ click_js = f"window.bdpOpenTikTok(\\'{esc(link)}\\',\\'{aid}\\')"
118
+ items.append(f\\'\\'\\'<div class="vslide-item vslide-item-shorts" onclick="{click_js}">
119
+ <div class="vslide-thumb vslide-thumb-shorts"><img src="{img}" alt="" class="bdp-lazy-img">
120
+ <div class="vslide-play">\\u25b6</div><span class="vslide-badge vslide-badge-shorts">Shorts</span></div>
121
+ <p class="vslide-title">{title}</p></div>\\'\\'\\'\\')
122
+ return f\\'\\'\\'<div class="vslide-wrap vslide-wrap-shorts">
123
+ <div class="vslide-header"><span class="vslide-label">\\U0001f4f1 Shorts Tin T\\u1ee9c</span>
124
+ <div class="vslide-nav"><button class="vslide-btn" onclick="window.bdpSlideScroll(-1,\\'vslide-shorts\\')">\\u25c0</button>
125
+ <button class="vslide-btn" onclick="window.bdpSlideScroll(1,\\'vslide-shorts\\')">\\u25b6</button></div></div>
126
+ <div class="vslide-track" id="vslide-shorts">{\\'\\'.join(items)}</div></div>\\'\\'\\'
127
+ '''
128
+
129
+ # Actually, the triple-quote escaping above is too complex. Let me write the function directly.
130
+ # I'll insert it properly.
131
+
132
+ # Let me take a different approach - insert raw code
133
+ content = content.replace(
134
+ "def render_video_carousel_html(videos):",
135
+ '''def render_shorts_carousel_html(shorts):
136
+ """Carousel shorts tin tuc 24h - displayed at very top of homepage."""
137
+ vids_with_img = [v for v in shorts if v.get("img")]
138
+ if not vids_with_img: return ""
139
+ items = []
140
+ for i, v in enumerate(vids_with_img[:15]):
141
+ img = safe_url(v.get("img",""))
142
+ link = v.get("link","#")
143
+ title = v.get("title","")
144
+ aid = make_id(link); sl = slug(title)
145
+ click_js = f"window.bdpOpenTikTok('{esc(link)}','{aid}')"
146
+ items.append(f\'\'\'<div class="vslide-item vslide-item-shorts" onclick="{click_js}">
147
+ <div class="vslide-thumb vslide-thumb-shorts"><img src="{img}" alt="" class="bdp-lazy-img">
148
+ <div class="vslide-play">\u25b6</div><span class="vslide-badge vslide-badge-shorts">Shorts</span></div>
149
+ <p class="vslide-title">{title}</p></div>\'\'\')
150
+ return f\'\'\'<div class="vslide-wrap vslide-wrap-shorts">
151
+ <div class="vslide-header"><span class="vslide-label">\U0001f4f1 Shorts Tin T\u1ee9c</span>
152
+ <div class="vslide-nav"><button class="vslide-btn" onclick="window.bdpSlideScroll(-1,\'vslide-shorts\')">\u25c0</button>
153
+ <button class="vslide-btn" onclick="window.bdpSlideScroll(1,\'vslide-shorts\')">\u25b6</button></div></div>
154
+ <div class="vslide-track" id="vslide-shorts">{\'\\'\'.join(items)}</div></div>\'\'\'
155
+
156
+ def render_video_carousel_html(videos):'''
157
+ )
158
+
159
+ print("Patch approach too complex with escaping. Writing direct file instead.")