diff --git a/build.py b/build.py index 9950425..e176a3f 100644 --- a/build.py +++ b/build.py @@ -1,187 +1,6 @@ import logging -from datetime import datetime -from pathlib import Path -from shutil import copyfile -from PIL import Image -from src.py.utils import ensure_dir, copy_assets, load_yaml, load_theme_config -from src.py.css_generator import generate_css_variables, generate_fonts_css, generate_google_fonts_link -from src.py.image_processor import process_images, copy_original_images, convert_and_resize_image, generate_favicons_from_logo, generate_favicon_ico -from src.py.html_generator import render_template, render_gallery_images, generate_gallery_json_from_images, generate_robots_txt, generate_sitemap_xml - -# Configure logging to display only the messages -logging.basicConfig(level=logging.INFO, format='%(message)s') - -# Define key directories used throughout the script -SRC_DIR = Path.cwd() -BUILD_DIR = SRC_DIR / "output" -TEMPLATE_DIR = SRC_DIR / "src/templates" -IMG_DIR = SRC_DIR / "config/photos" -JS_DIR = SRC_DIR / "src/public/js" -STYLE_DIR = SRC_DIR / "src/public/style" -GALLERY_FILE = SRC_DIR / "config/gallery.yaml" -SITE_FILE = SRC_DIR / "config/site.yaml" -THEMES_DIR = SRC_DIR / "config/themes" - -def build(): - logging.info("🚀 Starting build...") - ensure_dir(BUILD_DIR) - copy_assets(JS_DIR, STYLE_DIR, BUILD_DIR) - - # Defining build vars - build_date = datetime.now().strftime("%Y%m%d%H%M%S") - build_date_version = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - site_vars = load_yaml(SITE_FILE) - gallery_vars = load_yaml(GALLERY_FILE) - build_section = site_vars.get("build", {}) - theme_name = site_vars.get("build", {}).get("theme", "default") - theme_vars, theme_dir = load_theme_config(theme_name, THEMES_DIR) - fonts_dir = theme_dir / "fonts" - theme_css_path = theme_dir / "theme.css" - canonical_url = site_vars.get("info", {}).get("canonical", "").rstrip("/") - canonical_home = f"{canonical_url}/" - canonical_legals = f"{canonical_url}/legals/" - - # Copying theme.css if existing - if theme_css_path.exists(): - dest_theme_css = BUILD_DIR / "style" / "theme.css" - dest_theme_css.parent.mkdir(parents=True, exist_ok=True) - copyfile(theme_css_path, dest_theme_css) - theme_css = f'' - logging.info(f"[✓] Theme CSS found, copied to build folder: {dest_theme_css}") - else: - theme_css = "" - logging.warning(f"[~] No theme.css found in {theme_css_path}, skipping theme CSS injection.") - - preload_links = generate_fonts_css(fonts_dir, BUILD_DIR / "style" / "fonts.css", fonts_cfg=theme_vars.get("fonts")) - generate_css_variables(theme_vars.get("colors", {}), BUILD_DIR / "style" / "colors.css") - generate_favicons_from_logo(theme_vars, theme_dir, BUILD_DIR / "img" / "favicon") - generate_favicon_ico(theme_vars, theme_dir, BUILD_DIR / "favicon.ico") - - # Converting and resizing images if enabled - convert_images = build_section.get("convert_images", True) - resize_images = build_section.get("resize_images", True) - logging.info(f"[~] convert_images = {convert_images}") - logging.info(f"[~] resize_images = {resize_images}") - - hero_images = gallery_vars.get("hero", {}).get("images", []) - gallery_images = gallery_vars.get("gallery", {}).get("images", []) - - if convert_images: - process_images(hero_images, resize_images, IMG_DIR, BUILD_DIR) - process_images(gallery_images, resize_images, IMG_DIR, BUILD_DIR) - else: - copy_original_images(hero_images, IMG_DIR, BUILD_DIR) - copy_original_images(gallery_images, IMG_DIR, BUILD_DIR) - - if "hero" not in site_vars: - site_vars["hero"] = {} # Initialize an empty hero section - - # Adding menu - menu_html = "\n".join( - f'
{item['paragraph']}
" for item in ip_paragraphs) - legals_context = { - "hoster_name": legals_vars.get("hoster_name", ""), - "hoster_adress": legals_vars.get("hoster_adress", ""), - "hoster_contact": legals_vars.get("hoster_contact", ""), - "intellectual_property": paragraphs_html, - } - legals_body = render_template(TEMPLATE_DIR / "legals.html", legals_context) - legals_html = f"\n{signature}\n\n{head}\n{legals_body}\n{footer}\n" - output_legals = BUILD_DIR / "legals" / "index.html" - output_legals.parent.mkdir(parents=True, exist_ok=True) - with open(output_legals, "w", encoding="utf-8") as f: - f.write(legals_html) - logging.info(f"[✓] Legals page generated: {output_legals}") - else: - logging.warning("[~] No legals section found in site.yaml") - - # Hero carrousel generator - if hero_images: - generate_gallery_json_from_images(hero_images, BUILD_DIR) - else: - logging.warning("[~] No hero images found, skipping JSON generation.") - - # Sitemap and robot.txt generator - site_info = site_vars.get("info", {}) - canonical_url = site_info.get("canonical", "").rstrip("/") - if canonical_url: - allowed_pages = ["/", "/legals/"] - generate_robots_txt(canonical_url, allowed_pages, BUILD_DIR) - generate_sitemap_xml(canonical_url, allowed_pages, BUILD_DIR) - else: - logging.warning("[~] No canonical URL found in site.yaml info section, skipping robots.txt and sitemap.xml generation.") - - logging.info("✅ Build complete.") +from src.py.builder import build if __name__ == "__main__": - build() - \ No newline at end of file + logging.basicConfig(level=logging.INFO, format="%(message)s") + build() \ No newline at end of file diff --git a/src/py/builder.py b/src/py/builder.py new file mode 100644 index 0000000..45da59d --- /dev/null +++ b/src/py/builder.py @@ -0,0 +1,184 @@ +import logging +from datetime import datetime +from pathlib import Path +from shutil import copyfile +from PIL import Image +from .utils import ensure_dir, copy_assets, load_yaml, load_theme_config +from .css_generator import generate_css_variables, generate_fonts_css, generate_google_fonts_link +from .image_processor import process_images, copy_original_images, convert_and_resize_image, generate_favicons_from_logo, generate_favicon_ico +from .html_generator import render_template, render_gallery_images, generate_gallery_json_from_images, generate_robots_txt, generate_sitemap_xml + +# Configure logging to display only the messages +logging.basicConfig(level=logging.INFO, format='%(message)s') + +# Define key directories used throughout the script +SRC_DIR = Path.cwd() +BUILD_DIR = SRC_DIR / "output" +TEMPLATE_DIR = SRC_DIR / "src/templates" +IMG_DIR = SRC_DIR / "config/photos" +JS_DIR = SRC_DIR / "src/public/js" +STYLE_DIR = SRC_DIR / "src/public/style" +GALLERY_FILE = SRC_DIR / "config/gallery.yaml" +SITE_FILE = SRC_DIR / "config/site.yaml" +THEMES_DIR = SRC_DIR / "config/themes" + +def build(): + logging.info("🚀 Starting build...") + ensure_dir(BUILD_DIR) + copy_assets(JS_DIR, STYLE_DIR, BUILD_DIR) + + # Defining build vars + build_date = datetime.now().strftime("%Y%m%d%H%M%S") + build_date_version = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + site_vars = load_yaml(SITE_FILE) + gallery_vars = load_yaml(GALLERY_FILE) + build_section = site_vars.get("build", {}) + theme_name = site_vars.get("build", {}).get("theme", "default") + theme_vars, theme_dir = load_theme_config(theme_name, THEMES_DIR) + fonts_dir = theme_dir / "fonts" + theme_css_path = theme_dir / "theme.css" + canonical_url = site_vars.get("info", {}).get("canonical", "").rstrip("/") + canonical_home = f"{canonical_url}/" + canonical_legals = f"{canonical_url}/legals/" + + # Copying theme.css if existing + if theme_css_path.exists(): + dest_theme_css = BUILD_DIR / "style" / "theme.css" + dest_theme_css.parent.mkdir(parents=True, exist_ok=True) + copyfile(theme_css_path, dest_theme_css) + theme_css = f'' + logging.info(f"[✓] Theme CSS found, copied to build folder: {dest_theme_css}") + else: + theme_css = "" + logging.warning(f"[~] No theme.css found in {theme_css_path}, skipping theme CSS injection.") + + preload_links = generate_fonts_css(fonts_dir, BUILD_DIR / "style" / "fonts.css", fonts_cfg=theme_vars.get("fonts")) + generate_css_variables(theme_vars.get("colors", {}), BUILD_DIR / "style" / "colors.css") + generate_favicons_from_logo(theme_vars, theme_dir, BUILD_DIR / "img" / "favicon") + generate_favicon_ico(theme_vars, theme_dir, BUILD_DIR / "favicon.ico") + + # Converting and resizing images if enabled + convert_images = build_section.get("convert_images", True) + resize_images = build_section.get("resize_images", True) + logging.info(f"[~] convert_images = {convert_images}") + logging.info(f"[~] resize_images = {resize_images}") + + hero_images = gallery_vars.get("hero", {}).get("images", []) + gallery_images = gallery_vars.get("gallery", {}).get("images", []) + + if convert_images: + process_images(hero_images, resize_images, IMG_DIR, BUILD_DIR) + process_images(gallery_images, resize_images, IMG_DIR, BUILD_DIR) + else: + copy_original_images(hero_images, IMG_DIR, BUILD_DIR) + copy_original_images(gallery_images, IMG_DIR, BUILD_DIR) + + if "hero" not in site_vars: + site_vars["hero"] = {} # Initialize an empty hero section + + # Adding menu + menu_html = "\n".join( + f'{item['paragraph']}
" for item in ip_paragraphs) + legals_context = { + "hoster_name": legals_vars.get("hoster_name", ""), + "hoster_adress": legals_vars.get("hoster_adress", ""), + "hoster_contact": legals_vars.get("hoster_contact", ""), + "intellectual_property": paragraphs_html, + } + legals_body = render_template(TEMPLATE_DIR / "legals.html", legals_context) + legals_html = f"\n{signature}\n\n{head}\n{legals_body}\n{footer}\n" + output_legals = BUILD_DIR / "legals" / "index.html" + output_legals.parent.mkdir(parents=True, exist_ok=True) + with open(output_legals, "w", encoding="utf-8") as f: + f.write(legals_html) + logging.info(f"[✓] Legals page generated: {output_legals}") + else: + logging.warning("[~] No legals section found in site.yaml") + + # Hero carrousel generator + if hero_images: + generate_gallery_json_from_images(hero_images, BUILD_DIR) + else: + logging.warning("[~] No hero images found, skipping JSON generation.") + + # Sitemap and robot.txt generator + site_info = site_vars.get("info", {}) + canonical_url = site_info.get("canonical", "").rstrip("/") + if canonical_url: + allowed_pages = ["/", "/legals/"] + generate_robots_txt(canonical_url, allowed_pages, BUILD_DIR) + generate_sitemap_xml(canonical_url, allowed_pages, BUILD_DIR) + else: + logging.warning("[~] No canonical URL found in site.yaml info section, skipping robots.txt and sitemap.xml generation.") + + logging.info("✅ Build complete.") + \ No newline at end of file diff --git a/src/py/html_generator.py b/src/py/html_generator.py index 4eca005..2ac932e 100644 --- a/src/py/html_generator.py +++ b/src/py/html_generator.py @@ -36,16 +36,30 @@ def generate_gallery_json_from_images(images, output_dir): def generate_robots_txt(canonical_url, allowed_paths, output_dir): robots_lines = ["User-agent: *"] - for path in allowed_paths: - robots_lines.append(f"Allow: {path}") + + # Block everything by default robots_lines.append("Disallow: /") + + # Explicitly allow certain paths + for path in allowed_paths: + if not path.startswith("/"): + path = "/" + path + robots_lines.append(f"Allow: {path}") + robots_lines.append("") - robots_lines.append(f"Sitemap: {canonical_url}/sitemap.xml") + robots_lines.append(f"Sitemap: {canonical_url.rstrip('/')}/sitemap.xml") + content = "\n".join(robots_lines) - output_path = output_dir / "robots.txt" - with open(output_path, "w", encoding="utf-8") as f: - f.write(content) - logging.info(f"[✓] robots.txt generated at {output_path}") + output_path = Path(output_dir) / "robots.txt" + + try: + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, "w", encoding="utf-8") as f: + f.write(content) + logging.info(f"[✓] robots.txt generated at {output_path}") + + except Exception as e: + logging.error(f"[✗] Failed to write robots.txt: {e}") def generate_sitemap_xml(canonical_url, allowed_paths, output_dir): urlset_start = '\n