V.AISTUDIO / app /generate_all_stubs.py
bep40's picture
Upload app/generate_all_stubs.py
1c3caa0 verified
Raw
History Blame
3.69 kB
#!/usr/bin/env python3
"""Generate SEO stubs for ALL products in index.html - run during build.sh"""
import json, re, unicodedata, os, time, urllib.request
from huggingface_hub import HfApi
SPACE_ID = "bep40/V.AISTUDIO"
BASE_URL = "https://bep40-v-aistudio.static.hf.space"
def download_index():
print("Downloading index.html...")
api = HfApi()
path = api.hf_hub_download(SPACE_ID, "index.html", repo_type="space")
with open(path, 'r') as f:
return f.read()
def extract_products(html):
print("Extracting products...")
idx = html.find('var products = ')
if idx == -1:
idx = html.find('products = [')
if idx == -1:
raise ValueError("Products not found")
start = html.find('[', idx)
# Parse JSON array
bracket = 0
end = start
in_str = False
for i in range(start, len(html)):
c = html[i]
if c == '"' and html[i-1] != '\\':
in_str = not in_str
elif not in_str:
if c == '[': bracket += 1
elif c == ']':
bracket -= 1
if bracket == 0:
end = i + 1
break
products = json.loads(html[start:end])
print(f"Found {len(products)} products")
return products
def slugify(name):
s = unicodedata.normalize('NFKD', name).lower()
s = re.sub(r'[^a-z0-9]+', '-', s).strip('-')
s = re.sub(r'-+', '-', s)
return s
def create_stub(p):
slug = p.get('slug') or slugify(p.get('name', 'p'))
name = p.get('name', 'Product')[:200]
brand = p.get('brand', '')
price = p.get('price', '')
img = p.get('image', BASE_URL + '/logo/logo_600.png')
desc = re.sub(r'<[^>]+>', '', str(p.get('description', '')))[:160]
title = f"{name} | {brand} - V.AISTUDIO" if brand else f"{name} - V.AISTUDIO"
return f'''<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex,follow">
<link rel="canonical" href="{BASE_URL}/san-pham/{slug}/">
<meta property="og:type" content="product">
<meta property="og:title" content="{title}">
<meta property="og:description" content="{desc}">
<meta property="og:image" content="{img}">
<meta property="og:url" content="{BASE_URL}/san-pham/{slug}/">
<meta property="og:site_name" content="V.AISTUDIO">
<meta name="twitter:card" content="summary_large_image">
<script>window.location.replace("/?product={slug}");</script>
</head>
<body><h1><a href="/?product={slug}">{title}</a></h1></body>
</html>'''
def main():
html = download_index()
products = extract_products(html)
api = HfApi()
seen = {}
uploaded = 0
for p in products:
slug = p.get('slug') or slugify(p.get('name', 'p'))
if slug in seen:
seen[slug] += 1
slug = f"{slug}-{seen[slug]}"
else:
seen[slug] = 0
stub = create_stub(p)
try:
api.upload_file(
path_or_fileobj=stub.encode(),
path_in_repo=f"san-pham/{slug}/index.html",
repo_id=SPACE_ID, repo_type="space",
commit_message=f"SEO stub: {p.get('name', 'product')[:50]}"
)
uploaded += 1
if uploaded % 100 == 0:
print(f" {uploaded} uploaded...")
except Exception as e:
print(f" Error: {e}")
print(f"Done! {uploaded} stubs")
# Update .rebuild to trigger next build
api.upload_file(
path_or_fileobj=f"# rebuild {time.time()}".encode(),
path_in_repo=".rebuild",
repo_id=SPACE_ID, repo_type="space",
commit_message="Trigger rebuild complete"
)
if __name__ == "__main__":
main()