Configured to run as a Python module
This commit is contained in:
parent
d8067b1d93
commit
f42b103515
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ tmp
|
|||||||
build
|
build
|
||||||
dist
|
dist
|
||||||
**/__pycache__
|
**/__pycache__
|
||||||
|
custom.yaml
|
||||||
@ -17,7 +17,8 @@ sites:
|
|||||||
title: Resume
|
title: Resume
|
||||||
base_url: http://localhost:8000
|
base_url: http://localhost:8000
|
||||||
web_root: ./dist
|
web_root: ./dist
|
||||||
git_repo: ssh://gitea/jim/resume.git
|
git_repo:
|
||||||
|
url: ssh://gitea/jim/resume.git
|
||||||
build_cache: ./build/resume
|
build_cache: ./build/resume
|
||||||
assets:
|
assets:
|
||||||
- 'shepich_resume.pdf'
|
- 'shepich_resume.pdf'
|
||||||
@ -26,7 +27,9 @@ sites:
|
|||||||
title: Dogma Jimfinium
|
title: Dogma Jimfinium
|
||||||
description: May it bolster the skills of all who read it.
|
description: May it bolster the skills of all who read it.
|
||||||
base_url: http://localhost:8000/dogma-jimfinium
|
base_url: http://localhost:8000/dogma-jimfinium
|
||||||
git_repo: ssh://gitea/jim/dogma-jimfinium.git
|
git_repo:
|
||||||
|
url: ssh://gitea/jim/dogma-jimfinium.git
|
||||||
|
branch: pub
|
||||||
build_cache: ./build/dogma-jimfinium
|
build_cache: ./build/dogma-jimfinium
|
||||||
web_root: ./dist/dogma-jimfinium
|
web_root: ./dist/dogma-jimfinium
|
||||||
assets:
|
assets:
|
||||||
|
|||||||
@ -1,13 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import glob
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
import markdown
|
|
||||||
import yaml
|
import yaml
|
||||||
import pydantic
|
|
||||||
from typing import Optional
|
|
||||||
from datetime import datetime, date
|
|
||||||
from dotmap import DotMap
|
from dotmap import DotMap
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -21,13 +13,8 @@ from .articles import ArticleMetadata, load_markdown, build_articles, build_inde
|
|||||||
from .blog import build_blog_archive, build_rss_feed
|
from .blog import build_blog_archive, build_rss_feed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def build_site(site: SiteConfig, templates: DotMap):
|
def build_site(site: SiteConfig, templates: DotMap):
|
||||||
|
'''The pipeline for building a site defined in config.yaml.'''
|
||||||
|
|
||||||
logger.info(f'Building site "{site.title}".')
|
logger.info(f'Building site "{site.title}".')
|
||||||
|
|
||||||
@ -74,9 +61,11 @@ def build_site(site: SiteConfig, templates: DotMap):
|
|||||||
else:
|
else:
|
||||||
logger.debug('Addon "rss" not elected.')
|
logger.debug('Addon "rss" not elected.')
|
||||||
|
|
||||||
def main():
|
|
||||||
|
def build(config_filepath = './config.yaml'):
|
||||||
|
'''Pipeline for building the entire website, including all sites defined in config.yaml.'''
|
||||||
logger.info('Loading config.')
|
logger.info('Loading config.')
|
||||||
with open('./config.yaml', 'r') as config_file:
|
with open(config_filepath, 'r') as config_file:
|
||||||
config = yaml.safe_load(config_file.read())
|
config = yaml.safe_load(config_file.read())
|
||||||
|
|
||||||
logger.info('Loading global templates.')
|
logger.info('Loading global templates.')
|
||||||
@ -85,6 +74,5 @@ def main():
|
|||||||
for site in config['sites'].values():
|
for site in config['sites'].values():
|
||||||
build_site(SiteConfig(**site), templates)
|
build_site(SiteConfig(**site), templates)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
|
|
||||||
|
|||||||
15
jimsite/__main__.py
Normal file
15
jimsite/__main__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import argparse
|
||||||
|
from jimsite import build
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog='Jimsite',
|
||||||
|
description='A Python-based templating engine for building static websites from Markdown documents.',
|
||||||
|
epilog='Gonna be a hot one!'
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument('-c', '--config', type=str, default='config.yaml', help='Specifies the path to a YAML config file; defaults to config.yaml in the CWD.')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
build(config_filepath = args.config)
|
||||||
@ -11,6 +11,7 @@ from .common import filepath_or_string, SiteConfig
|
|||||||
from .templating import format_html_template, TemplateSelections
|
from .templating import format_html_template, TemplateSelections
|
||||||
|
|
||||||
class ArticleMetadata(pydantic.BaseModel):
|
class ArticleMetadata(pydantic.BaseModel):
|
||||||
|
'''A model for the YAML frontmatter included with Markdown articles.'''
|
||||||
title: str
|
title: str
|
||||||
date: date
|
date: date
|
||||||
published: bool
|
published: bool
|
||||||
@ -21,6 +22,8 @@ class ArticleMetadata(pydantic.BaseModel):
|
|||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
|
|
||||||
class Article(pydantic.BaseModel):
|
class Article(pydantic.BaseModel):
|
||||||
|
'''A model for a Markdown article, including its YAML frontmatter
|
||||||
|
metadata, as well as its path relative to the build cache root.'''
|
||||||
path: str
|
path: str
|
||||||
content: str
|
content: str
|
||||||
metadata: Optional[ArticleMetadata] = None
|
metadata: Optional[ArticleMetadata] = None
|
||||||
|
|||||||
@ -1,20 +1,30 @@
|
|||||||
import os
|
import os
|
||||||
import glob
|
import glob
|
||||||
import shutil
|
import shutil
|
||||||
from .common import run, SiteConfig
|
from .common import run, GitRepo, SiteConfig
|
||||||
|
|
||||||
|
|
||||||
# TODO: Add support for origin and branch.
|
def pull_git_repo(repo: GitRepo, build_cache: str) -> None:
|
||||||
def pull_git_repo(repo: str, build_cache: str) -> None:
|
|
||||||
'''Pulls/clones a repo into the build cache directory.'''
|
'''Pulls/clones a repo into the build cache directory.'''
|
||||||
|
|
||||||
|
# If a repo exists in the build cache, pull to it.
|
||||||
if os.path.exists(f'{build_cache}/.git'):
|
if os.path.exists(f'{build_cache}/.git'):
|
||||||
run(f'git -C {build_cache} pull origin')
|
|
||||||
|
# If a branch is specified, check out to it.
|
||||||
|
if repo.branch is not None:
|
||||||
|
run(f"git checkout {repo.branch}")
|
||||||
|
run(f"git -C {build_cache} pull {repo.remote}{' '+repo.branch if repo.branch else ''}")
|
||||||
|
|
||||||
|
# If the build cache is empty, clone the repo into it.
|
||||||
else:
|
else:
|
||||||
run(f'git clone {repo} {build_cache}')
|
run(f"git clone {repo.url}{(' -b '+repo.branch) if repo.branch else ''} -o {repo.remote} {build_cache}")
|
||||||
|
|
||||||
|
|
||||||
def copy_assets(site: SiteConfig):
|
def copy_assets(site: SiteConfig) -> None:
|
||||||
'''Copies the list of site assets from the build cache to the web root.'''
|
'''Copies the list of site assets from the build cache to the web root.
|
||||||
|
The asset list can include globs (*). All paths are resolved relative to
|
||||||
|
the build cache root, and will be copied to an analogous location in the
|
||||||
|
web root.'''
|
||||||
|
|
||||||
# Expand any globbed expressions.
|
# Expand any globbed expressions.
|
||||||
expanded_asset_list = []
|
expanded_asset_list = []
|
||||||
@ -28,7 +38,7 @@ def copy_assets(site: SiteConfig):
|
|||||||
|
|
||||||
# Construct the destination path analogous to the source path
|
# Construct the destination path analogous to the source path
|
||||||
# but in the web root instead of the build cache.
|
# but in the web root instead of the build cache.
|
||||||
destination = f'{site.web_root}/{a.lstrip("/")}'
|
destination = f'{site.web_root}/What the program does{a.lstrip("/")}'
|
||||||
|
|
||||||
# Delete existing files.
|
# Delete existing files.
|
||||||
shutil.rmtree(destination, ignore_errors=True)
|
shutil.rmtree(destination, ignore_errors=True)
|
||||||
|
|||||||
@ -25,6 +25,11 @@ class GlobalVars(pydantic.BaseModel):
|
|||||||
'''Static-valued global variables to be interpolated into any HTML templates.'''
|
'''Static-valued global variables to be interpolated into any HTML templates.'''
|
||||||
today: date = datetime.today()
|
today: date = datetime.today()
|
||||||
|
|
||||||
|
class GitRepo(pydantic.BaseModel):
|
||||||
|
'''A nested model used in SiteConfig to represent a Git repo.'''
|
||||||
|
url: str
|
||||||
|
branch: Optional[str] = None
|
||||||
|
remote: Optional[str] = 'origin'
|
||||||
|
|
||||||
class SiteConfig(pydantic.BaseModel):
|
class SiteConfig(pydantic.BaseModel):
|
||||||
base_url: str
|
base_url: str
|
||||||
@ -33,7 +38,7 @@ class SiteConfig(pydantic.BaseModel):
|
|||||||
title: str
|
title: str
|
||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
published: Optional[bool] = True
|
published: Optional[bool] = True
|
||||||
git_repo: Optional[str] = None
|
git_repo: Optional[GitRepo] = None
|
||||||
assets: Optional[list] = None
|
assets: Optional[list] = None
|
||||||
articles: Optional[list] = None
|
articles: Optional[list] = None
|
||||||
template_selections: Optional[dict] = {}
|
template_selections: Optional[dict] = {}
|
||||||
|
|||||||
@ -6,5 +6,7 @@
|
|||||||
<br />
|
<br />
|
||||||
<h2>Post History</h2>
|
<h2>Post History</h2>
|
||||||
{content}
|
{content}
|
||||||
|
<br /><hr /><br />
|
||||||
|
<p>Last Updated: {globalvars.today}<span>{templates.components.rss_icon}</span></p>
|
||||||
</article>
|
</article>
|
||||||
<script src="/assets/js/blog_archive_query.js"></script>
|
<script src="/assets/js/blog_archive_query.js"></script>
|
||||||
Loading…
x
Reference in New Issue
Block a user