First commit

This commit is contained in:
Digital Studium 2023-07-22 16:38:20 +03:00
commit 4a3074d4dd
5 changed files with 163 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.venv

7
README.md Normal file
View File

@ -0,0 +1,7 @@
# Crater
Multilingual static site generator based on Jinja templates.
Example theme: https://git.digitalstudium.com/digitalstudium/crater-theme-digitalstudium
Example website: https://git.digitalstudium.com/digitalstudium/digitalstudium.com

139
crater.py Normal file
View File

@ -0,0 +1,139 @@
import csv
import os
import pathlib
import shutil
import http.server
import socketserver
from jinja2 import Environment, FileSystemLoader, select_autoescape
import yaml
import frontmatter
import markdown
import fire
translations = {}
def copy_file(src, dst):
os.makedirs(os.path.dirname(dst), exist_ok=True)
shutil.copy2(src, dst)
def load_translations(file_path, _dict):
with open(file_path) as f:
reader = csv.DictReader(f, delimiter='|')
for row in reader:
_dict[row['id']] = row
del row['id']
def translate(id, language):
global translations
return translations[id][language]
def develop():
PORT = 8000
os.chdir('public')
handler = http.server.SimpleHTTPRequestHandler
server = socketserver.TCPServer(("", PORT), handler)
print("Server started at port 8000. Press CTRL+C to close the server.")
try:
server.serve_forever()
except KeyboardInterrupt:
server.server_close()
print("Server Closed")
def site_creator(prod=False):
global translations
# Read config of site
with open('config.yaml', 'r') as file:
config = yaml.safe_load(file)
# Load theme's jinja templates
templates = Environment(loader=FileSystemLoader(
f"themes/{config['theme']}/templates/"), autoescape=select_autoescape())
# Load base jinja template
base = templates.get_template("base.j2")
# Load translations
load_translations(f"themes/{config['theme']}/i18n.csv", translations)
load_translations("i18n.csv", translations)
# Add functions to base template
base.globals.update({"translate": translate})
# Remove public folder if exists before generating new content
shutil.rmtree('public', ignore_errors=True)
posts = {}
# Create new public folder
for language in config['languages']:
path = f"content/{language}"
content_dir = pathlib.Path(path)
content_files = content_dir.rglob("*.md")
posts[language] = {}
# Create posts dict
for item in list(content_files):
with open(item, 'r') as f:
data = frontmatter.loads(f.read())
post_path = str(item).replace(
"content", "public").rstrip(".md")
os.makedirs(post_path, exist_ok=True)
content = "{% import 'shortcodes.j2' as shortcodes %}" + \
markdown.markdown(data.content)
content = templates.from_string(content).render()
description = content.partition('<!--more-->')[0]
url = post_path.replace(f"public/{language}", "")
section = url.split('/')[1]
if not os.path.dirname(url) == "/":
posts[language].setdefault(section, {})
posts[language][section][url] = {
'title': data['title'],
'description': description,
'date': data['date'],
'content': content
}
image = data.get('image', None)
if image:
posts[language][section][url]['image'] = image
copy_file(f'assets{image}', f'public{image}')
for section, urls in posts[language].items():
html = base.render(config=config, section=section,
language=language, posts=posts)
with open(f"public/{language}/{section}/index.html", 'w') as f:
f.write(html)
for url, post in urls.items():
html = base.render(config=config, post=post,
language=language, url=url, posts=posts)
with open(f"public/{language}{url}/index.html", 'w') as f:
f.write(html)
html = base.render(config=config, posts=posts,
language=language, home=True)
with open(f"public/{language}/index.html", 'w') as f:
f.write(html)
shutil.copytree('static', 'public', dirs_exist_ok=True)
shutil.copytree(
f"themes/{config['theme']}/static", 'public', dirs_exist_ok=True)
if not prod:
develop()
if __name__ == '__main__':
fire.Fire(site_creator)

5
deploy.sh Executable file
View File

@ -0,0 +1,5 @@
pip install -r requirements.txt
python -m PyInstaller --onefile crater.py
chmod +x dist/crater
sudo mv dist/crater /usr/local/bin/
rm -rf dist build crater.spec

11
requirements.txt Normal file
View File

@ -0,0 +1,11 @@
altgraph==0.17.3
fire==0.5.0
Jinja2==3.1.2
Markdown==3.4.3
MarkupSafe==2.1.3
pyinstaller==5.13.0
pyinstaller-hooks-contrib==2023.6
python-frontmatter==1.0.0
PyYAML==6.0.1
six==1.16.0
termcolor==2.3.0