from argparse import ArgumentParser
import subprocess
import json
from jinja2 import Environment, Template, FileSystemLoader
from filters import TemplateFilters
from pathlib import Path
def parse_args() -> dict:
parser: ArgumentParser = ArgumentParser(
prog="LiveJrnl",
description="Renders a Jrnl journal as a static site."
)
parser.add_argument("-t", "--template", type=str,
help="the template file to use to build the output", required=True)
parser.add_argument("-o", "--output", type=str,
help="the output file to write to", required=True)
parser.add_argument("-x", "--cutoff", type=int,
help="the maximum number of items to render", default=-1)
parser.add_argument("-c", "--config", type=str,
help="the configuration file to use for building your journal")
args: dict = parser.parse_args()
return args
def get_journal() -> dict:
json_data = subprocess.run(["jrnl", "--format", "json"], capture_output=True, encoding='UTF-8')
return json.loads(json_data.stdout)
def get_default_config() -> dict:
default_config: dict = {
"title": "Ashley Robin's Journal",
"base_url": "https://localhost",
"description": "Write a bit about your website here.",
"author": "Ashley Robin",
"author_link": "https://localhost/arobin",
"year": "2023",
"language": "en",
"rss_language": "en-gb"
}
return default_config
def load_config(args: dict) -> str:
Keyword arguments:
args -- arguments passed from parse_args()
if args.config is None:
return get_default_config()
else:
with open(args.config, 'r') as config_file:
data = config_file.read()
return json.loads(data)
def generate_from_template(template: str, loaded_config: str) -> str:
Keyword arguments:
template -- the path to the template to use for output
loaded_config -- a dictionary of extra information to render
template_path: Path = Path(template)
if template_path.exists():
jrnl_json: dict = get_journal()
environment: Environment = Environment(loader=FileSystemLoader(template_path.parent), extensions=[
'jinja2_time.TimeExtension', 'jinja_markdown.MarkdownExtension'])
environment.filters['datetime'] = TemplateFilters.str_to_datetime
environment.filters['md2html'] = TemplateFilters.markdown_to_html
environment.filters['tagstrip'] = TemplateFilters.strip_entry_tag
loaded_template: Template = environment.get_template(
template_path.name)
return loaded_template.render(jrnl_json, config=loaded_config)
return str()
def remove_empty_lines(string: str) -> str:
Keyword arguments:
string -- the string to clean up
return "".join([s for s in string.splitlines(True) if s.strip()])
def write_output_file(filename: str, contents: str) -> None:
Keyword arguments:
filename -- the full path to the file to write to
contents -- the contents to write to file
output_path: Path = Path(filename)
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, "w") as output_file:
output_file.write(remove_empty_lines(contents))
if __name__ == '__main__':
args: dict = parse_args()
config = load_config(args)
if not args.cutoff is None:
config["cutoff"] = int(args.cutoff)
contents = generate_from_template(args.template, config)
write_output_file(args.output, contents)