# IndexGen is the index generator for the static website. import argparse import datetime import jinja2 import glob import yaml import sys import os from dateutil import parser as dateparser def parse_date(date_value): """Parse date from string or return date object as-is.""" if isinstance(date_value, (datetime.date, datetime.datetime)): return date_value if isinstance(date_value, str) and date_value: return dateparser.parse(date_value) return datetime.datetime.min def directory_exists(directory) -> bool: return os.path.exists(directory) def find_articles(resources) -> list: articles = [] articles_dir = os.path.join(resources, 'articles') if not directory_exists(articles_dir): print('The articles directory does not exist.') os._exit(1) for article in glob.glob(os.path.join(articles_dir, '*.md')): if os.path.exists(article): with open(article, 'r') as file: print(article) article_data = yaml.load_all(file, Loader=yaml.SafeLoader) # get only first element out of the generator article_data = next(article_data) # articles marked "unlisted: true" are built and deployed at # their URL but never shown on the index page if article_data.get('unlisted'): continue # append link to the article article_data['link'] = f"/articles/{os.path.basename(article).replace('.md', '.html')}" articles.append(article_data) # Sort by date, newest first articles.sort(key=lambda x: parse_date(x.get('date')), reverse=True) return articles def find_advisories(resources) -> list: advisories = [] advisories_dir = os.path.join(resources, 'advisory') if not directory_exists(advisories_dir): print('The advisories directory does not exist.') os._exit(1) for advisory in glob.glob(os.path.join(advisories_dir, '*.txt')): if os.path.exists(advisory): with open(advisory, 'r') as file: advisory_data = yaml.load_all(file, Loader=yaml.SafeLoader) # get only first element out of the generator advisory_data = next(advisory_data) # append link to the advisory advisory_data['link'] = f"/advisory/{os.path.basename(advisory)}" advisories.append(advisory_data) # Sort by date, newest first advisories.sort(key=lambda x: parse_date(x.get('date')), reverse=True) return advisories def find_projects(resources) -> list: projects = [] projects_dir = os.path.join(resources, 'projects') if not directory_exists(projects_dir): print('The projects directory does not exist.') os._exit(1) for project in glob.glob(os.path.join(projects_dir, '*.yaml')): if os.path.exists(project): with open(project, 'r') as file: project_data = yaml.load_all(file, Loader=yaml.SafeLoader) # get only first element out of the generator project_data = next(project_data) projects.append(project_data) return projects def main(args): parser = argparse.ArgumentParser(description='Generate index.md file for the static website.') parser.add_argument('--resources', type=str, help='Path to the resources directory.', required=True) parser.add_argument("--blog-title", type=str, help="Title of the blog", required=True) parser.add_argument("--blog-author", type=str, help="Author of the blog", required=True) args = parser.parse_args(args) # check if the resources directory exists resources = args.resources if not directory_exists(resources): print('The resources directory does not exist.') os._exit(1) articles = find_articles(resources) advisories = find_advisories(resources) projects = find_projects(resources) blog = { 'title': args.blog_title, 'author': args.blog_author, # format the date like Thursday, 1 January 2021 'update_date': datetime.datetime.now().strftime('%A, %d %B %Y') } template = os.path.join(os.path.dirname(__file__), 'index.md') with open(template, 'r') as file: tmpl = jinja2.Template(file.read()) with open(os.path.join(resources, "pages", "index.md"), 'w') as file: file.write(tmpl.render(articles=articles, advisories=advisories, projects=projects, blog=blog)) if __name__ == '__main__': main(sys.argv[1:])