updates
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
import argparse
|
import argparse
|
||||||
from config import Config
|
from config import config
|
||||||
|
|
||||||
argparser = argparse.ArgumentParser(
|
argparser = argparse.ArgumentParser(
|
||||||
prog = Config.APP_NAME,
|
prog = config.app_name,
|
||||||
description = Config.APP_DESCRIPTION,
|
description = config.app_description,
|
||||||
epilog = f"See {Config.APP_SRC_URL} for more info.")
|
epilog = f"See {config.app_src_url} for more info.")
|
||||||
|
|
||||||
subparsers = argparser.add_subparsers(dest='command', required=True)
|
subparsers = argparser.add_subparsers(dest='command', required=True)
|
||||||
|
|
||||||
|
|||||||
53
classes.py
53
classes.py
@@ -5,16 +5,15 @@ import shutil
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import markdown
|
import markdown
|
||||||
import frontmatter
|
import frontmatter
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from logger import logger
|
from logger import logger
|
||||||
from config import Config
|
from config import config
|
||||||
#from jinja_env import env, content_item_template, index_template
|
#from jinja_env import env, content_item_template, index_template
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
|
||||||
# get the scrip directory
|
# Get the script base_dir and check for templates dir
|
||||||
|
if Path(f'themes/{config.theme}/templates').exists():
|
||||||
if Path(f'themes/{Config.THEME}/templates').exists():
|
|
||||||
base_dir = "."
|
base_dir = "."
|
||||||
elif getattr(sys, 'frozen', False):
|
elif getattr(sys, 'frozen', False):
|
||||||
# Running fron Pyinstaller-packed binary
|
# Running fron Pyinstaller-packed binary
|
||||||
@@ -24,9 +23,9 @@ else:
|
|||||||
base_dir = Path(__file__).resolve().parent
|
base_dir = Path(__file__).resolve().parent
|
||||||
|
|
||||||
# Prepare template rendering engine
|
# Prepare template rendering engine
|
||||||
if Path(f"themes/{Config.THEME}/templates").exists():
|
if Path(f"themes/{config.theme}/templates").exists():
|
||||||
# Use the templates from the initialized site instance and the installed theme
|
# Use the templates from the initialized site instance and the installed theme
|
||||||
jinja_env_dir = f"themes/{Config.THEME}/templates"
|
jinja_env_dir = f"themes/{config.theme}/templates"
|
||||||
print("USING LOCALLY INITIALIZED THEMES")
|
print("USING LOCALLY INITIALIZED THEMES")
|
||||||
else:
|
else:
|
||||||
# Use default templates from the default theme shipped with the app
|
# Use default templates from the default theme shipped with the app
|
||||||
@@ -34,7 +33,7 @@ else:
|
|||||||
print("USING DEFAULT THEMES")
|
print("USING DEFAULT THEMES")
|
||||||
jinja_env_dir = f"{base_dir}/themes/default/templates"
|
jinja_env_dir = f"{base_dir}/themes/default/templates"
|
||||||
env = Environment(loader=FileSystemLoader(f"{jinja_env_dir}"))
|
env = Environment(loader=FileSystemLoader(f"{jinja_env_dir}"))
|
||||||
env.globals['header_image'] = f"{base_dir}/themes/{Config.THEME}/static/images/header.jpg"
|
env.globals['header_image'] = f"{base_dir}/themes/{config.theme}/static/images/header.jpg"
|
||||||
index_template = env.get_template("index.html")
|
index_template = env.get_template("index.html")
|
||||||
content_item_template = env.get_template("content_item.html")
|
content_item_template = env.get_template("content_item.html")
|
||||||
print(env.loader.searchpath)
|
print(env.loader.searchpath)
|
||||||
@@ -46,20 +45,20 @@ class ContentItem:
|
|||||||
logger.debug(f"Rendering {self.source_file} to {self.target_file}")
|
logger.debug(f"Rendering {self.source_file} to {self.target_file}")
|
||||||
try:
|
try:
|
||||||
if self.image_file and self.image_file.exists():
|
if self.image_file and self.image_file.exists():
|
||||||
image_targetfile = Path(f"{Config.OUTPUT_DIR}/{Config.STATIC_DIR}/images/{self.image_file.name}")
|
image_targetfile = Path(f"{config.output_dir}/{config.static_dir}/images/{self.image_file.name}")
|
||||||
logger.debug(f"Copying {self.image_file} to {image_targetfile}")
|
logger.debug(f"Copying {self.image_file} to {image_targetfile}")
|
||||||
shutil.copyfile(self.image_file, image_targetfile)
|
shutil.copyfile(self.image_file, image_targetfile)
|
||||||
self.image_file = f"{self.image_file.stem}.jpg"
|
self.image_file = f"{self.image_file.stem}.jpg"
|
||||||
if self.css_file and self.css_file.exists():
|
if self.css_file and self.css_file.exists():
|
||||||
css_targetfile = Path(f"{Config.OUTPUT_DIR}/{Config.STATIC_DIR}/css/{self.css_file.name}")
|
css_targetfile = Path(f"{config.output_dir}/{config.static_dir}/css/{self.css_file.name}")
|
||||||
logger.debug(f"Copying {self.css_file} to {css_targetfile}")
|
logger.debug(f"Copying {self.css_file} to {css_targetfile}")
|
||||||
shutil.copyfile(self.css_file, css_targetfile)
|
shutil.copyfile(self.css_file, css_targetfile)
|
||||||
if self.js_file and self.js_file.exists():
|
if self.js_file and self.js_file.exists():
|
||||||
js_targetfile = Path(f"{Config.OUTPUT_DIR}/{Config.STATIC_DIR}/js/{self.js_file.name}")
|
js_targetfile = Path(f"{config.output_dir}/{config.static_dir}/js/{self.js_file.name}")
|
||||||
logger.debug(f"Copying {self.js_file} to {js_targetfile}")
|
logger.debug(f"Copying {self.js_file} to {js_targetfile}")
|
||||||
shutil.copyfile(self.js_file, js_targetfile)
|
shutil.copyfile(self.js_file, js_targetfile)
|
||||||
with self.target_file.open("w", encoding="utf-8") as f:
|
with self.target_file.open("w", encoding="utf-8") as f:
|
||||||
f.write(content_item_template.render(content_item = self, page_title = f"{Config.MAIN_PAGE_TITLE}: {self.title}", parent_path = '../', categories = categories))
|
f.write(content_item_template.render(content_item = self, page_title = f"{config.site_name}: {self.title}", parent_path = '../', categories = categories))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Renderer: {e}")
|
logger.error(f"Renderer: {e}")
|
||||||
|
|
||||||
@@ -69,7 +68,7 @@ class ContentItem:
|
|||||||
self.source_file = Path(self.source_file)
|
self.source_file = Path(self.source_file)
|
||||||
self.parent_dir = self.source_file.parent
|
self.parent_dir = self.source_file.parent
|
||||||
self.slug = self.source_file.stem
|
self.slug = self.source_file.stem
|
||||||
self.target_file = Path(f"{Config.OUTPUT_DIR}/{self.source_file.parent}/{self.source_file.stem}.html")
|
self.target_file = Path(f"{config.output_dir}/{self.source_file.parent}/{self.source_file.stem}.html")
|
||||||
self.data = frontmatter.load(self.source_file)
|
self.data = frontmatter.load(self.source_file)
|
||||||
self.preview = self.data.content.replace('\n', '<br>')[:300]
|
self.preview = self.data.content.replace('\n', '<br>')[:300]
|
||||||
self.title = self.data.get("title", self.slug)
|
self.title = self.data.get("title", self.slug)
|
||||||
@@ -109,14 +108,14 @@ class ContentItem:
|
|||||||
|
|
||||||
class Site:
|
class Site:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.output_dir = Path(Config.OUTPUT_DIR)
|
self.output_dir = Path(config.output_dir)
|
||||||
self.content_dir = Path(Config.CONTENT_DIR)
|
self.content_dir = Path(config.content_dir)
|
||||||
self.static_dir = Path(Config.STATIC_DIR)
|
self.static_dir = Path(config.static_dir)
|
||||||
self.templates_dir = Path(Config.TEMPLATES_DIR)
|
self.templates_dir = Path(config.templates_dir)
|
||||||
self.images_dir = Path(f"{Config.STATIC_DIR}/images")
|
self.images_dir = Path(f"{config.static_dir}/images")
|
||||||
self.css_dir = Path(f"{Config.STATIC_DIR}/css")
|
self.css_dir = Path(f"{config.static_dir}/css")
|
||||||
self.js_dir = Path(f"{Config.STATIC_DIR}/js")
|
self.js_dir = Path(f"{config.static_dir}/js")
|
||||||
self.output_dir = Path(Config.OUTPUT_DIR)
|
self.output_dir = Path(config.output_dir)
|
||||||
self.content_items = []
|
self.content_items = []
|
||||||
self.categories = defaultdict(list)
|
self.categories = defaultdict(list)
|
||||||
|
|
||||||
@@ -132,8 +131,8 @@ class Site:
|
|||||||
def get_content_items(self):
|
def get_content_items(self):
|
||||||
logger.debug("Getting content items")
|
logger.debug("Getting content items")
|
||||||
self.get_content_items = []
|
self.get_content_items = []
|
||||||
logger.debug(f"Scanning {Path(Config.CONTENT_DIR)}")
|
logger.debug(f"Scanning {Path(config.content_dir)}")
|
||||||
for md_file in Path(Config.CONTENT_DIR).glob("*.md"):
|
for md_file in Path(config.content_dir).glob("*.md"):
|
||||||
content_item = ContentItem(md_file)
|
content_item = ContentItem(md_file)
|
||||||
content_item.parse_content()
|
content_item.parse_content()
|
||||||
self.content_items.append(content_item)
|
self.content_items.append(content_item)
|
||||||
@@ -159,7 +158,7 @@ class Site:
|
|||||||
subdir.mkdir(parents=True, exist_ok=True)
|
subdir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
# Copy theme's static dir to 'public/static
|
# Copy theme's static dir to 'public/static
|
||||||
shutil.copytree(f"{base_dir}/themes/{Config.THEME}/static", f"{self.output_dir}/static", dirs_exist_ok=True)
|
shutil.copytree(f"{base_dir}/themes/{config.theme}/static", f"{self.output_dir}/static", dirs_exist_ok=True)
|
||||||
|
|
||||||
# Get content items
|
# Get content items
|
||||||
self.get_content_items()
|
self.get_content_items()
|
||||||
@@ -172,14 +171,14 @@ class Site:
|
|||||||
content_item.render_content(categories = self.categories)
|
content_item.render_content(categories = self.categories)
|
||||||
|
|
||||||
# Render the about file
|
# Render the about file
|
||||||
about_content = ContentItem(Path(f'themes/{Config.THEME}/content/about.md'))
|
about_content = ContentItem(Path(f'themes/{config.theme}/content/about.md'))
|
||||||
about_content.parse_content()
|
about_content.parse_content()
|
||||||
about_content.render_content(categories = self.categories, target_file='public/static/about.html')
|
about_content.render_content(categories = self.categories, target_file='public/static/about.html')
|
||||||
|
|
||||||
# Render the index file
|
# Render the index file
|
||||||
visible_content_items = [c for c in self.content_items if c.data.get("hidden") != True]
|
visible_content_items = [c for c in self.content_items if c.data.get("hidden") != True]
|
||||||
with (self.output_dir / "index.html").open("w", encoding="utf-8") as f:
|
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=visible_content_items, categories = self.categories))
|
f.write(index_template.render(page_title = config.site_name, content_items=visible_content_items, categories = self.categories))
|
||||||
|
|
||||||
# Render the categories indices
|
# Render the categories indices
|
||||||
visible_content_items = [c for c in self.content_items if c.data.get("hidden") != True]
|
visible_content_items = [c for c in self.content_items if c.data.get("hidden") != True]
|
||||||
@@ -187,7 +186,7 @@ class Site:
|
|||||||
category_index = Path(f"{self.output_dir}/categories/{category}.html")
|
category_index = Path(f"{self.output_dir}/categories/{category}.html")
|
||||||
category_items = [i for i in visible_content_items if category in i.data.get("categories")]
|
category_items = [i for i in visible_content_items if category in i.data.get("categories")]
|
||||||
with (category_index).open(mode="w", encoding="utf-8") as f:
|
with (category_index).open(mode="w", encoding="utf-8") as f:
|
||||||
f.write(index_template.render(page_title=f"{Config.MAIN_PAGE_TITLE}: {category}", content_items=category_items, categories = self.categories, parent_path = '../'))
|
f.write(index_template.render(page_title=f"{config.site_name}: {category}", content_items=category_items, categories = self.categories, parent_path = '../'))
|
||||||
|
|
||||||
logger.info(f"Created {len(self.content_items)} content items.")
|
logger.info(f"Created {len(self.content_items)} content items.")
|
||||||
|
|
||||||
49
config.py
49
config.py
@@ -1,14 +1,41 @@
|
|||||||
import os
|
import os, yaml
|
||||||
|
|
||||||
# Main config section
|
# Main config section
|
||||||
|
#class Config:
|
||||||
|
# MAIN_PAGE_TITLE = "microgen library"
|
||||||
|
# APP_NAME = "hydrogen"
|
||||||
|
# APP_DESCRIPTION = "Simplistic static site generator"
|
||||||
|
# APP_SRC_URL = f"https://git.exocortex.ru/Exocortex/{APP_NAME}"
|
||||||
|
# OUTPUT_DIR = 'public'
|
||||||
|
# TEMPLATES_DIR = 'templates'
|
||||||
|
# CONTENT_DIR = 'content'
|
||||||
|
# STATIC_DIR = 'static'
|
||||||
|
# HEADER_IMAGE = 'static/header.jpg'
|
||||||
|
# THEME = "default"
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
MAIN_PAGE_TITLE = "microgen library"
|
def __init__(self, config_path="config.yml"):
|
||||||
APP_NAME = "hydrogen"
|
self.app_name = "microgen"
|
||||||
APP_DESCRIPTION = "Simplistic static site generator"
|
self.app_description = "Simplistic static site generator"
|
||||||
APP_SRC_URL = f"https://git.exocortex.ru/Exocortex/{APP_NAME}"
|
self.app_src_url = f"https://git.exocortex.ru/Exocortex/{self.app_name}"
|
||||||
OUTPUT_DIR = 'public'
|
self.content_dir = 'content'
|
||||||
TEMPLATES_DIR = 'templates'
|
self.templates_dir = 'templates'
|
||||||
CONTENT_DIR = 'content'
|
self.static_dir = 'static'
|
||||||
STATIC_DIR = 'static'
|
self.output_dir = 'public'
|
||||||
HEADER_IMAGE = 'static/header.jpg'
|
self.header_image = 'static/header.jpg'
|
||||||
THEME = "default"
|
self.site_name = "microgen library"
|
||||||
|
self.theme = "default"
|
||||||
|
if os.path.isfile (config_path):
|
||||||
|
with open(config_path, "r") as f:
|
||||||
|
config = yaml.safe_load(f)
|
||||||
|
if config:
|
||||||
|
self.update_from_dict(config)
|
||||||
|
|
||||||
|
def update_from_dict(self, config_dict):
|
||||||
|
for key, value in config_dict.items():
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{self.__dict__}"
|
||||||
|
|
||||||
|
config = Config()
|
||||||
0
config.yml
Normal file
0
config.yml
Normal file
@@ -1,11 +1,11 @@
|
|||||||
import os, subprocess
|
import os, subprocess
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from classes import *
|
from classes import *
|
||||||
from config import Config
|
from config import config
|
||||||
from logger import logger
|
from logger import logger
|
||||||
|
|
||||||
def create_content(filename):
|
def create_content(filename):
|
||||||
filename = Path(f"{Config.CONTENT_DIR}/{filename}.md")
|
filename = Path(f"{config.content_dir}/{filename}.md")
|
||||||
if not filename.exists():
|
if not filename.exists():
|
||||||
logger.debug(f"Creating new content {filename}")
|
logger.debug(f"Creating new content {filename}")
|
||||||
new_content_item = ContentItem(filename)
|
new_content_item = ContentItem(filename)
|
||||||
@@ -15,9 +15,9 @@ def edit_content(filename):
|
|||||||
logger.debug(f"Editing content {filename}")
|
logger.debug(f"Editing content {filename}")
|
||||||
editor = os.environ.get('EDITOR', 'vim')
|
editor = os.environ.get('EDITOR', 'vim')
|
||||||
# Create the content file if not exists
|
# Create the content file if not exists
|
||||||
if not Path(f"{Config.CONTENT_DIR}/{filename}.md").exists():
|
if not Path(f"{config.content_dir}/{filename}.md").exists():
|
||||||
create_content(filename)
|
create_content(filename)
|
||||||
filename = Path(f"{Config.CONTENT_DIR}/{filename}.md")
|
filename = Path(f"{config.content_dir}/{filename}.md")
|
||||||
subprocess.call([editor, filename])
|
subprocess.call([editor, filename])
|
||||||
|
|
||||||
def init_site():
|
def init_site():
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import logging, sys
|
import logging, sys
|
||||||
from config import Config
|
from config import config
|
||||||
|
|
||||||
# Logging config section
|
# Logging config section
|
||||||
|
|
||||||
LOG_TO = sys.stdout
|
LOG_TO = sys.stdout
|
||||||
LOG_LEVEL = logging.INFO
|
LOG_LEVEL = logging.INFO
|
||||||
|
|
||||||
logger = logging.getLogger(Config.APP_NAME)
|
logger = logging.getLogger(config.app_name)
|
||||||
logger.setLevel(LOG_LEVEL)
|
logger.setLevel(LOG_LEVEL)
|
||||||
stdout_handler = logging.StreamHandler(LOG_TO)
|
stdout_handler = logging.StreamHandler(LOG_TO)
|
||||||
stdout_handler.setLevel(LOG_LEVEL)
|
stdout_handler.setLevel(LOG_LEVEL)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="content">
|
<div id="top_wrapper">
|
||||||
<div id= "top_header" class="row top_header">
|
<div id= "top_header" class="row top_header">
|
||||||
<img id="top_header_image" src="{{ parent_path }}static/images/header.jpg" class="img-fluid">
|
<img id="top_header_image" src="{{ parent_path }}static/images/header.jpg" class="img-fluid">
|
||||||
<div id="top_title" class="row">
|
<div id="top_title" class="row">
|
||||||
@@ -37,11 +37,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content" class="container-fluid mb-2">
|
<div id="content_wrapper" class="container-fluid mb-2">
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
<div id="footer" class="container-fluid">
|
<div id="footer_wrapper" class="container-fluid">
|
||||||
<div id="footer-data" class="row my-1">
|
<div id="footer-data" class="row my-1">
|
||||||
{% block footer_includes %}
|
{% block footer_includes %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user