import os, html, json import gradio as gr from jinja2 import Environment, FileSystemLoader from utils import read_file, get_models_data, get_contacts, img_b64, opis_to_html BASE_DIR = os.path.dirname(os.path.abspath(__file__)) ASSETS_DIR = os.path.join(BASE_DIR, "assets") env = Environment(loader=FileSystemLoader(ASSETS_DIR), autoescape=True) SHOWCASE_EXTRA_CSS = """ footer, footer *, .footer, div[class*="footer"], .built-with, [class*="built-with"], [class*="ApiLink"], [class*="api-link"], .show-api, a[href*="gradio.app"], a[href*="huggingface"], button[title*="API"], button[title*="Setting"], button[aria-label*="Setting"], .top-panel, div.top-panel, [class*="top-panel"] { display: none !important; visibility: hidden !important; height: 0 !important; overflow: hidden !important; } .gradio-container { min-height: unset !important; } """ HIDE_FOOTER_JS = """ () => { const kill = () => { document.querySelectorAll('footer, .footer, [class*="footer"]').forEach(el => el.remove()); document.querySelectorAll('.show-api, [class*="ApiLink"], [class*="api-link"]').forEach(el => el.remove()); document.querySelectorAll('button[title*="Setting"], button[aria-label*="Setting"]').forEach(el => el.remove()); document.querySelectorAll('a[href*="gradio.app"]').forEach(el => { let p = el.closest('div'); if(p) p.remove(); }); }; kill(); setTimeout(kill, 300); setTimeout(kill, 1000); new MutationObserver(kill).observe(document.body, {childList:true, subtree:true}); } """ def build_gallery(images): if not images: return '
Фото відсутні
' imgs_json = json.dumps([img_b64(p) for p in images]) gallery_tpl = env.get_template("gallery.html") gallery_html = gallery_tpl.render(imgs_json=imgs_json, n=len(images)) return f'' def render_showcase(): models_data = get_models_data(BASE_DIR) contacts = get_contacts(BASE_DIR) for m in models_data: m['desc_html'] = opis_to_html(m['opis_raw']) m['gallery_html'] = build_gallery(m['images']) landing_tpl = env.get_template("landing.html") rendered = landing_tpl.render(models=models_data, contacts=contacts) return rendered, models_data shell_css = read_file(os.path.join(ASSETS_DIR, "shell.css")) + SHOWCASE_EXTRA_CSS def build_showcase_app(): # Gradio 4: css= и js= работают в конструкторе with gr.Blocks( title="Unstop Retail", css=shell_css, js=HIDE_FOOTER_JS, analytics_enabled=False, ) as app_showcase: # show_api не используем — несовместим с gr 4.x showcase_html = gr.HTML() def get_current_html(): html_content, _ = render_showcase() return html_content app_showcase.load(fn=get_current_html, inputs=[], outputs=[showcase_html]) return app_showcase