Files
hydrogen/classes.py
2025-06-09 23:34:36 +03:00

133 lines
5.7 KiB
Python

from datetime import datetime
import os
import shutil
import markdown
import frontmatter
from pathlib import Path
from logger import logger
from config import Config
from jinja_env import env, content_item_template, index_template
class DefaultFrontmatterHeader:
def __init__(self, title):
self.title = f"title: '{title}'\n"
self.date = f"date: '{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}'\n"
self.omit_second_title = f"omit_second_title: '{str(False)}'\n"
self.description = "description: \n"
self.author = "author: \n"
class ContentItemPrototype:
def render_content(self):
logger.debug(f"Rendering {self.source_filename} to {Config.OUTPUT_DIR}/{self.target_filename}")
if self.image_file.exists():
shutil.copyfile(self.image_src_file, Path(Config.OUTPUT_DIR) / self.image)
if self.css_file.exists():
shutil.copyfile(self.custom_css_src_file,Path(Config.OUTPUT_DIR) / self.custom_css)
if self.js_file.exists():
shutil.copyfile(self.custom_js_src_file, Path(Config.OUTPUT_DIR) / self.custom_js)
with self.target_filename.open("w", encoding="utf-8") as f:
f.write(content_item_template.render(content_item = self, page_title = self.title))
def parse_content(self):
try:
self.source_filename = Path(self.source_filename)
self.subdir = self.source_filename.parent
logger.debug(f"Parsing item {self.source_filename}")
self.slug = self.source_filename.stem
self.target_filename = Path(f"{Config.OUTPUT_DIR}/{self.source_filename.parent}/{self.source_filename.stem}.html")
self.data = frontmatter.load(self.source_filename)
self.html = markdown.markdown(self.data.content)
self.url = "<a href=" + f"{self.subdir}/{self.slug}.html" + "> ...read more</a>"
self.preview = self.html[:300] + self.url
self.title = self.data.get("title", self.slug)
self.omit_second_title = self.data.get("omit_second_title", False)
self.date = self.data.get("date", "2000-01-01T00:00:00+03:00")
self.image_file = self.source_filename.stem + ".jpg"
self.css_file = self.source_filename.stem + ".css"
self.js_file = self.source_filename.stem + ".js"
except Exception as e:
logger.error(e)
def create_content(self):
with open(self.source_filename, mode="w", encoding="utf-8") as f:
f.writelines([
"---\n",
self.default_frontmatter_header.title,
self.default_frontmatter_header.date,
self.default_frontmatter_header.description,
self.default_frontmatter_header.author,
self.default_frontmatter_header.omit_second_title,
"---\n"
])
def __init__(self, filename, title = None):
self.source_filename = filename
self.title = title or self.source_filename.stem
self.default_frontmatter_header = DefaultFrontmatterHeader(self.title)
class SitePrototype:
def init_site():
logger.info("Initializing new site")
content_dir = Path(Config.CONTENT_DIR)
static_dir = Path(Config.STATIC_DIR)
templates_dir = Path(Config.TEMPLATES_DIR)
images_dir = Path(f"{Config.STATIC_DIR}/images")
css_dir = Path(f"{Config.STATIC_DIR}/css")
js_dir = Path(f"{Config.STATIC_DIR}/js")
# Create directories
for subdir in [content_dir, static_dir, templates_dir, images_dir, css_dir, js_dir]:
os.makedirs(subdir, exist_ok=True)
# Create templates from literals
import templates
template_names = [t for t in dir(templates) if not t.startswith('_')]
for template_name in template_names:
template_content = getattr(templates, template_name)
with open(templates_dir / f"{template_name}.html", "w", encoding="utf8") as f:
f.write(template_content)
# Create static/about.md
def build_site(self):
# Recreate the output dir if needed
if output_dir.exists():
shutil.rmtree(output_dir)
output_dir.mkdir()
# Create public subdirs
subdirs = [img_dir, css_dir, js_dir]
for subdir in subdirs:
subdir.mkdir(arents=True, exist_ok=True)
# Copy static files if exist
if static_dir.exists():
shutil.copytree(static_dir, output_dir / "static", dirs_exist_ok=True)
# Parse the content files
content_items = []
for md_file in content_dir.glob("*.md"):
current_content_item = ContentItemPrototype(md_file)
current_content_item.render_content()
content_items.append({
"slug": current_content_item.slug,
"title": current_content_item.title,
"date": current_content_item.date,
# "preview": markdown.markdown(current_content_item.preview),
"image": current_content_item.image,
})
# Render the index file
with (output_dir / "index.html").open("w", encoding="utf-8") as f:
f.write(index_template.render(page_title = Config.MAIN_PAGE_TITLE, content_items=content_items))
# Render the about file
about_content = ContentItemPrototype(Path('static/about.md'))
about_content.render_content()
# Move 'robots.txt' into output_dir
shutil.copyfile(static_dir / 'robots.txt', output_dir / 'robots.txt')
logger.info(f"Created {len(content_items)} content items.")
def __init__(self):
self.output_dir = Path(Config.OUTPUT_DIR)