"""Entry point: shorts carousel + TikTok-style video playback for ALL video sources.""" import sys, os, re as _re sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from shorts_carousel import scrape_24h_news_shorts, render_shorts_carousel, SHORTS_CSS, _extract_24h_video_url import app # ══ CSS Patches ══ SHORTS_EXTRA_CSS = """ /* Shorts feed: video 9:16 crop center */ .shorts-feed-mode .tiktok-video{object-fit:cover!important} /* TikTok feed fullwidth */ .tiktok-fullscreen-container{width:100%!important;max-width:100%!important;border-radius:0!important} /* Fullheight toggle for highlight */ .tiktok-fullscreen-container.fullheight-mode .tiktok-video{object-fit:cover!important} .tiktok-fullheight-btn{position:absolute;bottom:70px;right:12px;background:rgba(255,255,255,.15);color:#fff;border:none;padding:6px 12px;border-radius:16px;font-size:11px;cursor:pointer;z-index:8;backdrop-filter:blur(6px)} .tiktok-fullheight-btn.active{background:rgba(92,184,122,.5)} """ FULLWIDTH_CSS = """ /* ══ FULLWIDTH: kill all Gradio padding ══ */ body,.gradio-container,.main,.contain{margin:0!important;padding:0!important;max-width:100%!important;width:100%!important} .gradio-container>.main{padding:0!important} .gradio-container>.main>.contain{padding:0!important} .gradio-container>.main>.contain>div{padding:0!important;margin:0!important} .gradio-container>.main>.contain>div>div{padding:0!important} #component-0,#component-1,#component-2,#component-3,#component-4,#component-5{padding:0!important;margin:0!important} .gap{gap:0!important} .panel,.form,.block{padding:0!important} div[class*="svelte"]{padding-left:0!important;padding-right:0!important} .bdp-wrap{padding:6px 4px!important} .bdp-article{padding:12px 8px 30px!important;max-width:100%!important} .controls-row{padding:0 4px!important} .vslide-wrap{margin:4px 2px!important;border-radius:8px!important} .bdp-header{padding:12px 8px!important} @media(min-width:768px){ .bdp-wrap{padding:8px!important} .bdp-article{padding:16px 12px 40px!important;max-width:720px!important} .vslide-wrap{margin:8px!important;border-radius:12px!important} } """ if "vslide-shorts-item" not in app.CSS: app.CSS += SHORTS_CSS if "shorts-feed-mode" not in app.CSS: app.CSS += SHORTS_EXTRA_CSS if "FULLWIDTH: kill all Gradio padding" not in app.CSS: app.CSS += FULLWIDTH_CSS # ══ Override app._extract_24h_video_urls with fixed multi-part version ══ def _fixed_extract_24h_video_urls(article_url): vid = _extract_24h_video_url(article_url) if not vid: return [] all_parts = vid.get("all_parts", [vid["src"]]) poster = vid.get("poster", "") return [{"src": p, "poster": poster, "vtype": "hls"} for p in all_parts] app._extract_24h_video_urls = _fixed_extract_24h_video_urls # ══ Fix homepage slider: bdpOpenTikTok → bdpOpen with 3 params ══ _orig_render_video_slider = getattr(app, 'render_video_slider_html', None) if _orig_render_video_slider: def _patched_render_video_slider(videos): html = _orig_render_video_slider(videos) html = html.replace("window.bdpOpenTikTok(", "window.bdpOpen(") html = _re.sub( r"window\.bdpOpen\('([^']+)','([^']+)'\)", r"window.bdpOpen('\1','\2','')", html ) return html app.render_video_slider_html = _patched_render_video_slider # ══ Patch render_homepage_html: add shorts carousel ══ _orig_render_homepage = app.render_homepage_html def _patched_render_homepage(articles, *args, **kwargs): html = _orig_render_homepage(articles, *args, **kwargs) try: shorts = scrape_24h_news_shorts()[:15] shorts_html = render_shorts_carousel(shorts, app.esc, app.safe_url, app.make_id, app.slug) if shorts_html: insert_point = html.find('