feat: refactored the overview

This commit is contained in:
Hazel 2025-04-14 15:12:56 +02:00
parent 523402d3ad
commit ee26af8b35
2 changed files with 136 additions and 124 deletions

View File

@ -1,41 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>STSG</title>
<link rel="stylesheet" href="/static/bulma.min.css" />
</head>
<body>
<!-- Header (Navbar) -->
<nav
class="navbar is-primary"
role="navigation"
aria-label="main navigation"
>
<div class="navbar-brand">
<a class="navbar-item" href="#">
<strong>Static Translated Site Generator</strong>
</a>
</div>
</nav>
<!-- Main Content -->
<section class="section">
<div class="content">
<a href="../">Go Back</a>
</div>
<div class="content">
<content />
</div>
</section>
<!-- Footer -->
<footer class="footer">
<div class="content has-text-centered">
<p><strong>STSG</strong> by Hazel. &copy; 2025</p>
</div>
</footer>
</body>
</html>

View File

@ -1,9 +1,10 @@
from __future__ import annotations
import logging import logging
import shutil import shutil
from pathlib import Path from pathlib import Path
import os import os
import markdown import markdown
from typing import Optional from typing import Optional, Union, Dict, Generator
from .config import SOURCE_DIRECTORY, DIST_DIRECTORY, LANGUAGE_INFORMATION from .config import SOURCE_DIRECTORY, DIST_DIRECTORY, LANGUAGE_INFORMATION
@ -11,87 +12,112 @@ from .config import SOURCE_DIRECTORY, DIST_DIRECTORY, LANGUAGE_INFORMATION
logger = logging.getLogger("stsg.build") logger = logging.getLogger("stsg.build")
def copy_static(src, dst): class CustomPath:
if not os.path.exists(src): def __init__(self, path: Path):
logger.warn("The static folder '%s' wasn't defined.", src) self.path = path
def __repr__(self) -> str:
return str(self.path)
@property
def source_path(self) -> Path:
return Path(SOURCE_DIRECTORY, self.path)
@property
def dist_path(self) -> Path:
return Path(DIST_DIRECTORY, self.path)
@property
def name(self) -> str:
return Path(self.path).name
@property
def parent(self) -> CustomPath:
return CustomPath(Path(self.path).parent)
@property
def stem(self) -> str:
return Path(self.path).stem
def iterdir(self) -> Generator[CustomPath, None, None]:
for p in self.source_path.iterdir():
yield CustomPath(Path(self.path, p.name))
def get_child(self, name: str, force_directory: bool = False, force_file: bool = False) -> Optional[CustomPath]:
child = Path(self.source_path, name)
if not child.exists():
return None
if force_directory and not child.is_dir():
return None
if force_file and not child.is_file():
return None
return CustomPath(Path(self.path, name))
def read_text(self) -> str:
return self.source_path.read_text()
def copy_static(path: CustomPath):
src = path.source_path
dst = path.dist_path
if not src.exists():
logger.warning("The static folder '%s' wasn't defined.", src)
return return
logger.info("copying static files from '%s' to '%r'", src, dst) logger.info("Copying static files from '%s' to '%s'", src, dst)
os.makedirs(dst, exist_ok=True) dst.mkdir(parents=True, exist_ok=True)
for root, dirs, files in os.walk(src): for root, dirs, files in os.walk(src):
if any(p.startswith(".") for p in Path(root).parts): root_path = Path(root)
if any(part.startswith(".") for part in root_path.parts):
continue continue
# Compute relative path from the source root rel_path = root_path.relative_to(src)
rel_path = os.path.relpath(root, src) dest_dir = dst / rel_path
dest_dir = os.path.join(dst, rel_path) dest_dir.mkdir(parents=True, exist_ok=True)
os.makedirs(dest_dir, exist_ok=True)
for file in files: for file in files:
if file.startswith("."): if file.startswith("."):
continue continue
src_file = os.path.join(root, file) src_file = root_path / file
dest_file = os.path.join(dest_dir, file) dest_file = dest_dir / file
shutil.copy2(src_file, dest_file) shutil.copy2(src_file, dest_file)
class Context:
def __init__(self, root: str = SOURCE_DIRECTORY):
self.file = None
current_root = Path(root) class Article(CustomPath):
while current_root.parts and self.file is None: def __init__(self, path: CustomPath):
current_file = Path(current_root, "index.html") super().__init__(path.path)
if current_file.exists() and current_file.is_file:
self.file = current_file
current_root = current_root.parent def get_content(self) -> str:
if self.name.endswith(".md"):
return markdown.markdown(self.read_text())
if self.file is None: return self.read_text()
logger.error("couldn't find context for %s", root)
exit(1)
logger.info("%s found context %r", root, str(self.file))
def get_text(self, **placeholder_values: dict): @property
text = self.file.read_text() def article_directory(self) -> Path:
return self.dist_path.parent / self.stem
for key, value in placeholder_values.items():
text = text.replace(f"<{key}/>", value)
text = text.replace(f"<{key} />", value)
return text
def convert_md(src: Path, dst: Path, context: Optional[Context] = None):
logger.info("converting %s", src)
html_content = markdown.markdown(src.read_text())
context = context or Context(str(src.parent))
full_page = context.get_text(content=html_content)
folder_dst = dst.parent / dst.name.replace(".md", "")
folder_dst.mkdir(parents=True, exist_ok=True)
with Path(folder_dst, "index.html").open("w") as f:
f.write(full_page)
class CustomLanguageCode: class CustomLanguageCode:
def __init__(self, file: Path): def __init__(self, file: CustomPath):
self.file: Path = file self.file = file
@property @property
def language_code(self) -> str: def language_code(self) -> str:
return self.file.name.replace(".md", "") return self.file.stem
@property @property
def relative_url(self) -> str: def relative_url(self) -> str:
return "/" + str(Path(self.file.parent, self.language_code)) return "/" + str(self)
def __repr__(self) -> str: def __repr__(self) -> str:
return f"{self.language_code}" return f"{self.language_code}"
@ -120,40 +146,67 @@ class CustomLanguageCode:
return f'<ul><a href="{self.relative_url}"><bold>{self.flag} {self.native_name}</bold></a></ul>' return f'<ul><a href="{self.relative_url}"><bold>{self.flag} {self.native_name}</bold></a></ul>'
def walk_directory(root): class Template:
src_path = Path(SOURCE_DIRECTORY, root) def __init__(self, root: CustomPath):
dst_path = Path(DIST_DIRECTORY, root) self.root = root
context = Context(src_path) self.articles = []
language_codes_found = []
for current_full_path in src_path.iterdir(): def copy(self):
current_name = Path(current_full_path).name return Template(root=self.root)
current_dst = Path(dst_path, current_name)
current_src = Path(src_path, current_name)
if current_name == "static": def _replace_keywords(self, text: str, **placeholder_values: str) -> str:
copy_static(current_src, current_dst) for key, value in placeholder_values.items():
text = text.replace(f"<{key}/>", value)
text = text.replace(f"<{key} />", value)
return text
@property
def article_template(self) -> str:
article = self.root.get_child("article.html", force_file=True)
return article.source_path.read_text() if article else "<content/>"
def convert_article(self, path: Article):
logger.info("converting %s", path)
article_text = self._replace_keywords(
self.article_template,
content = path.get_content(),
)
path.article_directory.mkdir(parents=True, exist_ok=True)
with Path(path.article_directory, "index.html").open("w") as f:
f.write(article_text)
def walk_directory(root: CustomPath, template: Optional[Template] = None):
template_dir = root.get_child("_templates", force_directory=True)
if template_dir is not None:
template = Template(template_dir)
if template is None:
logger.error("Didn't find template for %d", root)
return
for current_path in root.iterdir():
if current_path.name.startswith("_") or current_path.name == "static":
continue continue
if current_name.endswith(".md"): if current_path.source_path.is_file():
convert_md(current_src, current_dst, context=context) template.convert_article(Article(current_path))
language_codes_found.append(CustomLanguageCode(Path(root, current_name)))
continue continue
if current_src.is_dir(): if current_path.source_path.is_dir():
walk_directory(Path(root, current_full_path.name)) walk_directory(current_path, template=template.copy())
content = f"""
<li>
{''.join(l.html_code for l in language_codes_found)} static_dir = root.get_child("static", force_directory=True)
</li> if static_dir:
""" copy_static(static_dir)
with Path(dst_path, "index.html").open("w") as f:
f.write(context.get_text(content=content))
def build(): def build():
logger.info("building static page") logger.info("building static page")
walk_directory("") walk_directory(CustomPath(Path()))