Compare commits

5 Commits

Author SHA1 Message Date
cf8e2955c2 feat: initializing location 2025-04-16 13:23:30 +02:00
7aa06b7f83 feat: added meta context 2025-04-16 13:15:27 +02:00
f7a690405b feat: add language context 2025-04-16 13:09:46 +02:00
93ea11cd0e feat: removed weird article cards 2025-04-16 12:30:54 +02:00
263281df3c feat: renamed ArticleOverview to article 2025-04-16 12:18:44 +02:00

View File

@@ -4,7 +4,7 @@ import shutil
from pathlib import Path
import os
import markdown
from typing import Optional, Union, Dict, Generator, List, DefaultDict
from typing import Optional, Union, Dict, Generator, List, DefaultDict, Any
from bs4 import BeautifulSoup
from collections import defaultdict
import toml
@@ -30,6 +30,37 @@ def get_first_header_content(content, fallback: str = ""):
return fallback
def stem_to_language_code(stem: str) -> str:
language_code = stem.lower().replace("-", "_")
if language_code in config.languages:
return language_code
language_code = language_code.split("_")[0]
if language_code in config.languages:
return language_code
logger.error("Didn't recognize %s as a valid language code, add it to the config, or fix your structure.", stem)
exit(1)
class LanguageDict(dict):
def __missing__(self, key: str):
if key not in config.languages:
raise KeyError(key)
lang_dict = config.languages[key]
lang_dict["priority"] = lang_dict.get("priority", 0)
elements = key.split("_")
if len(elements) > 1:
elements[-1] = elements[-1].upper()
lang_dict["code"] = "-".join(elements)
return lang_dict
LANGUAGES = LanguageDict()
class Template:
def __init__(self, folder: Path):
self.folder = folder
@@ -40,50 +71,33 @@ class Template:
self.article_card: str = (self.folder / "article_card.html").read_text()
class ArticleTranslation:
def __init__(self, file: Path, article_overview: ArticleOverview):
def __init__(self, file: Path, article: Article):
self.file = file
self.article_overview = article_overview
self.language_code = self.file.stem
self.article = article
self.context: Dict[str, Any] = {}
# initializing the location of the article translation
self.language_code = stem_to_language_code(self.file.stem)
self.location_in_tree = [self.language_code, *self.article.location_in_tree]
self.url = "/" + "/".join(self.location_in_tree)
self.dist_path = Path(config.setup.dist_directory, *self.location_in_tree)
self.priority = LANGUAGES[self.language_code]["priority"]
# TODO remove
self.article_content = self.file.read_text()
self.article_preview = self.article_content[:config.formatting.article_preview_length] + "..."
if self.file.suffix == ".md":
self.article_content = markdown.markdown(self.article_content)
self.article_preview = markdown.markdown(self.article_preview)
self.location_in_tree = [self.language_code, *self.article_overview.location_in_tree]
self.url = "/" + "/".join(self.location_in_tree)
self.dist_path = Path(config.setup.dist_directory, *self.location_in_tree)
_language_info = config.languages[config.formatting.fallback_language]
parsed_language_code = self.language_code.lower().replace("-", "_")
if parsed_language_code in config.languages:
_language_info = config.languages[parsed_language_code]
elif parsed_language_code.split("_")[0] in config.languages:
_language_info = config.languages[parsed_language_code.split("_")[0]]
self.language_name: str = _language_info["native_name"]
self.language_flag: str = _language_info["flag"]
self.priority: int = _language_info.get("priority", 0)
self.title = get_first_header_content(self.article_content, fallback=self.language_name)
self.article_cards = ""
def post_init(self):
"""
the initializing that takes place after the creation of the tree
"""
article_card_strings = []
for child in self.article_overview.child_articles:
if self.language_code in child.article_translations_map:
article_card_strings.append(child.article_translations_map[self.language_code].get_article_card())
self.article_cards = "\n".join(article_card_strings)
self.title = get_first_header_content(self.article_content, fallback="")
def __init_context__(self):
self.context["meta"] = self.article.context_meta
self.context["language"] = LANGUAGES[self.language_code]
def build(self):
self.dist_path.mkdir(parents=True, exist_ok=True)
@@ -96,15 +110,11 @@ class ArticleTranslation:
"article_content": self.article_content,
"article_preview": self.article_preview,
"article_url": self.url,
"article_overview_url": self.article_overview.url,
"article_slug": self.article_overview.slug,
"article_overview_url": self.article.url,
"article_slug": self.article.slug,
"article_title": self.title,
"article_datetime": self.article_overview.article_written.strftime(config.formatting.datetime_format),
"article_datetime_iso": self.article_overview.article_written.isoformat(),
"article_language_name": self.language_name,
"article_language_code": self.language_code,
"article_language_flag": self.language_flag,
"article_children_cards": self.article_cards,
"article_datetime": self.article.article_written.strftime(config.formatting.datetime_format),
"article_datetime_iso": self.article.article_written.isoformat(),
}
if return_foreign_articles:
@@ -115,7 +125,7 @@ class ArticleTranslation:
def get_article_values(self) -> Dict[str, str]:
res = {}
for key, value in self._get_values(return_foreign_articles=False).items():
res[key + ":" + self.article_overview.slug] = value
res[key + ":" + self.article.slug] = value
return res
@@ -129,17 +139,23 @@ class ArticleTranslation:
return replace_values(TEMPLATE.article_card, self._get_values())
class ArticleOverview:
class Article:
def __init__(self, directory: Path, location_in_tree: Optional[List[str]] = None, is_root: bool = False):
self.directory = directory
article_config = {}
if (self.directory / "index.toml").exists():
article_config = toml.load(self.directory / "index.toml")
self.context: Dict[str, Any] = {}
self.context_meta = self.context["meta"] = {}
self.slug = article_config.get("name", self.directory.name)
# initializing the config values of the article
config_file = self.directory / "index.toml"
self.config = toml.load(config_file) if config_file.exists() else {}
self.article_written = datetime.datetime.fromisoformat(article_config["datetime"]) if "datetime" in article_config else datetime.datetime.fromtimestamp(self.directory.stat().st_mtime)
# initializing the location and slug of the article
self.slug = self.config.get("name", self.directory.name)
if self.slug in ARTICLE_LAKE:
logger.error("two articles have the same name at %s and %r", ARTICLE_LAKE[self.slug].directory, self.directory)
exit(1)
ARTICLE_LAKE[self.slug] = self
self.location_in_tree: List[str] = location_in_tree or []
if not is_root:
@@ -147,12 +163,12 @@ class ArticleOverview:
self.url = "/" + "/".join(self.location_in_tree)
self.dist_path = Path(config.setup.dist_directory, *self.location_in_tree)
if self.slug in ARTICLE_LAKE:
logger.error("two articles have the same name at %s and %r", ARTICLE_LAKE[self.slug].directory, self.directory)
exit(1)
ARTICLE_LAKE[self.slug] = self
self.child_articles: List[ArticleOverview] = []
self.article_written = datetime.datetime.fromisoformat(article_config["datetime"]) if "datetime" in article_config else datetime.datetime.fromtimestamp(self.directory.stat().st_mtime)
self.child_articles: List[Article] = []
self.article_translations: List[ArticleTranslation] = []
self.article_translations_map: Dict[str, ArticleTranslation] = {}
@@ -165,7 +181,7 @@ class ArticleOverview:
self.article_translations.append(at)
self.article_translations_map[at.language_code] = at
elif c.is_dir():
self.child_articles.append(ArticleOverview(
self.child_articles.append(Article(
directory=c,
location_in_tree=self.location_in_tree.copy(),
))
@@ -176,7 +192,7 @@ class ArticleOverview:
self.article_cards = "\n".join(c.get_article_card() for c in self.child_articles)
for at in self.article_translations:
at.post_init()
at.__init_context__()
logger.info("found %s at %s with the translations %s", self.slug, ".".join(list(self.location_in_tree)), ",".join(self.article_translations_map.keys()))
@@ -227,7 +243,7 @@ class ArticleOverview:
# GLOBALS
logger = logging.getLogger("stsg.build")
TEMPLATE = Template(Path(config.setup.source_directory, "templates"))
ARTICLE_LAKE: Dict[str, ArticleOverview] = {}
ARTICLE_LAKE: Dict[str, Article] = {}
ARTICLE_REFERENCE_VALUES: DefaultDict[str, Dict[str, str]] = defaultdict(dict)
def build():
@@ -237,7 +253,7 @@ def build():
shutil.copytree(Path(config.setup.source_directory, "static"), Path(config.setup.dist_directory, "static"), dirs_exist_ok=True)
logger.info("reading page tree...")
tree = ArticleOverview(directory=Path(config.setup.source_directory, "articles"), is_root=True)
tree = Article(directory=Path(config.setup.source_directory, "articles"), is_root=True)
# build article reverence values
for article_overview in ARTICLE_LAKE.values():