143 lines
5.0 KiB
Python
143 lines
5.0 KiB
Python
"""
|
|
Exporte chaque page Django en HTML autonome (CSS + JS inline).
|
|
Usage : python3 export_pages.py
|
|
"""
|
|
import os, re, base64, mimetypes
|
|
from pathlib import Path
|
|
import requests
|
|
from bs4 import BeautifulSoup
|
|
from urllib.parse import urljoin, urlparse
|
|
|
|
BASE_URL = 'http://127.0.0.1:8000'
|
|
OUT_DIR = Path(__file__).parent / 'figma_export'
|
|
OUT_DIR.mkdir(exist_ok=True)
|
|
|
|
PAGES = [
|
|
('home', '/'),
|
|
('a-propos', '/a-propos/'),
|
|
('kiriq', '/produits/kiriq/'),
|
|
('monitor', '/produits/monitor/'),
|
|
('joolid', '/produits/joolid/'),
|
|
('carrieres','/carrieres/'),
|
|
]
|
|
|
|
session = requests.Session()
|
|
|
|
def fetch(url):
|
|
r = session.get(urljoin(BASE_URL, url), timeout=10)
|
|
r.raise_for_status()
|
|
return r
|
|
|
|
def to_data_uri(url_or_path):
|
|
"""Convertit une URL de ressource en data URI base64."""
|
|
try:
|
|
r = fetch(url_or_path)
|
|
mime = r.headers.get('Content-Type', 'application/octet-stream').split(';')[0]
|
|
b64 = base64.b64encode(r.content).decode()
|
|
return f"data:{mime};base64,{b64}"
|
|
except Exception as e:
|
|
print(f" ⚠️ Impossible de charger {url_or_path}: {e}")
|
|
return url_or_path
|
|
|
|
def inline_css(soup, base_url):
|
|
"""Remplace les <link rel=stylesheet> par des <style> inline."""
|
|
for link in soup.find_all('link', rel='stylesheet'):
|
|
href = link.get('href', '')
|
|
if not href:
|
|
continue
|
|
try:
|
|
css_text = fetch(href).text
|
|
# Inline les url() dans le CSS (fonts, images)
|
|
def replace_url(m):
|
|
raw = m.group(1).strip('"\'')
|
|
if raw.startswith('data:') or raw.startswith('http'):
|
|
return m.group(0)
|
|
full = urljoin(BASE_URL + href, raw)
|
|
path = urlparse(full).path
|
|
return f"url('{to_data_uri(path)}')"
|
|
css_text = re.sub(r'url\(([^)]+)\)', replace_url, css_text)
|
|
style_tag = soup.new_tag('style')
|
|
style_tag.string = css_text
|
|
link.replace_with(style_tag)
|
|
print(f" ✅ CSS inline : {href}")
|
|
except Exception as e:
|
|
print(f" ⚠️ CSS ignoré {href}: {e}")
|
|
|
|
def inline_images(soup):
|
|
"""Remplace les src d'images par des data URI."""
|
|
for img in soup.find_all('img'):
|
|
src = img.get('src', '')
|
|
if src and not src.startswith('data:') and not src.startswith('http'):
|
|
img['src'] = to_data_uri(src)
|
|
print(f" 🖼️ Image inline : {src}")
|
|
|
|
def inline_js(soup):
|
|
"""Remplace les <script src=...> par du JS inline."""
|
|
for script in soup.find_all('script', src=True):
|
|
src = script.get('src', '')
|
|
if not src or src.startswith('http'):
|
|
continue
|
|
try:
|
|
js_text = fetch(src).text
|
|
new_script = soup.new_tag('script')
|
|
new_script.string = js_text
|
|
script.replace_with(new_script)
|
|
print(f" ⚡ JS inline : {src}")
|
|
except Exception as e:
|
|
print(f" ⚠️ JS ignoré {src}: {e}")
|
|
|
|
def fix_google_fonts(soup):
|
|
"""Garde les liens Google Fonts (ils fonctionnent sans serveur)."""
|
|
# On ne touche pas aux fonts Google — elles chargent via CDN
|
|
pass
|
|
|
|
def export_page(name, path):
|
|
print(f"\n📄 Export : {name} ({path})")
|
|
try:
|
|
html = fetch(path).text
|
|
except Exception as e:
|
|
print(f" ❌ Erreur : {e}")
|
|
return
|
|
|
|
soup = BeautifulSoup(html, 'html.parser')
|
|
|
|
# Supprimer les balises CSRF et admin (inutiles en statique)
|
|
for tag in soup.find_all('input', {'name': 'csrfmiddlewaretoken'}):
|
|
tag.decompose()
|
|
|
|
fix_google_fonts(soup)
|
|
inline_css(soup, path)
|
|
inline_images(soup)
|
|
inline_js(soup)
|
|
|
|
# Fixer les liens internes pour qu'ils pointent vers les fichiers exportés
|
|
page_map = {
|
|
'/': 'home.html',
|
|
'/a-propos/': 'a-propos.html',
|
|
'/produits/kiriq/': 'kiriq.html',
|
|
'/produits/monitor/': 'monitor.html',
|
|
'/produits/joolid/': 'joolid.html',
|
|
'/carrieres/': 'carrieres.html',
|
|
}
|
|
for a in soup.find_all('a', href=True):
|
|
href = a['href']
|
|
# Supprimer les ancres avec fragment pour les pages principales
|
|
clean = href.split('#')[0]
|
|
if clean in page_map:
|
|
a['href'] = page_map[clean] + (('#' + href.split('#')[1]) if '#' in href else '')
|
|
|
|
out_file = OUT_DIR / f"{name}.html"
|
|
out_file.write_text(str(soup), encoding='utf-8')
|
|
size_kb = out_file.stat().st_size / 1024
|
|
print(f" ✅ Sauvegardé : {out_file.name} ({size_kb:.0f} KB)")
|
|
|
|
if __name__ == '__main__':
|
|
print("🚀 Export HTML autonome — Jool International\n")
|
|
for name, path in PAGES:
|
|
export_page(name, path)
|
|
print(f"\n🎉 Terminé ! Fichiers dans : {OUT_DIR}")
|
|
print("\n📌 Étapes suivantes :")
|
|
print(" 1. Ouvrez Figma Desktop")
|
|
print(" 2. Installez le plugin 'html.to.design' depuis la communauté Figma")
|
|
print(" 3. Dans le plugin : Local File → sélectionnez chaque .html dans figma_export/")
|