Files
hydrogen/classes.py
2025-06-10 20:50:21 +03:00

128 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 ContentItem:
def render_content(self):
logger.debug(f"Rendering {self.source_filename} to {self.target_filename}")
if self.image_file and self.image_file.exists():
logger.debug(f"Copying {self.image_file} to {Path(Config.OUTPUT_DIR) / self.image_file}")
shutil.copyfile(self.image_file, Path(Config.OUTPUT_DIR) / self.image_file)
self.image_file = f"{self.image_file.stem}.jpg"
if self.css_file and self.css_file.exists():
shutil.copyfile(self.css_file,Path(Config.OUTPUT_DIR) / self.css_file)
if self.js_file and self.js_file.exists():
shutil.copyfile(self.js_file, Path(Config.OUTPUT_DIR) / self.js_file)
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)
logger.debug(f"Parsing item {self.source_filename}")
self.subdir = self.source_filename.parent
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.replace('\n', ' \n'))
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.categories = self.data.get("categories", str([]))
self.hidden = self.data.get("hidden", str(False))
cover_image_path = Path(self.source_filename.parent) / Path(self.source_filename.stem + ".jpg")
self.image_file = cover_image_path if cover_image_path.exists() else None
self.css_file = Path(self.source_filename.stem + ".css") if Path(self.source_filename.stem + ".css").exists() else None
self.js_file = Path(self.source_filename.stem + ".js") if Path(self.source_filename.stem + ".js").exists else None
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",
f"title: {self.source_filename.stem}\n",
f"date: '{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}'\n",
"description: ''\n",
"author: ''\n",
"categories: ['default']\n",
"hidden: 'False'\n",
"omit_second_title: 'False'\n",
"---\n",
"\n\n\n"
])
def __init__(self, filename):
self.source_filename = filename
class Site:
def __init__(self):
self.output_dir = Path(Config.OUTPUT_DIR)
logger.info("Initializing new site")
self.content_dir = Path(Config.CONTENT_DIR)
self.static_dir = Path(Config.STATIC_DIR)
self.templates_dir = Path(Config.TEMPLATES_DIR)
self.images_dir = Path(f"{Config.STATIC_DIR}/images")
self.css_dir = Path(f"{Config.STATIC_DIR}/css")
self.js_dir = Path(f"{Config.STATIC_DIR}/js")
self.output_dir = Path(Config.OUTPUT_DIR)
def init_site(self):
# Create directories
for subdir in [self.content_dir, self.static_dir, self.templates_dir,
self.images_dir, self.css_dir, self.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(self.templates_dir / f"{template_name}.html", "w", encoding="utf8") as f:
f.write(template_content)
# Create static/about.md
def build(self):
# Recreate the output dir if needed
if self.output_dir.exists():
shutil.rmtree(self.output_dir)
self.output_dir.mkdir()
# Create public subdirs
subdirs = [self.images_dir, self.css_dir, self.js_dir, self.content_dir]
for subdir in subdirs:
subdir = self.output_dir / subdir
subdir.mkdir(parents=True, exist_ok=True)
# Copy static files if exist
if self.static_dir.exists():
shutil.copytree(self.static_dir, self.output_dir / self.static_dir, dirs_exist_ok=True)
# Parse the content files
content_items = []
for md_file in self.content_dir.glob("*.md"):
current_content_item = ContentItem(md_file)
current_content_item.parse_content()
current_content_item.render_content()
content_items.append(current_content_item)
# Render the index file
with (self.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 = ContentItem(Path('static/about.md'))
about_content.parse_content()
about_content.render_content()
logger.info(f"Created {len(content_items)} content items.")