Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

build: new workflow and some reformatting #8

Merged
merged 6 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/makesite.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Build with makesite.py and deploy to Pages

on:
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

defaults:
run:
shell: bash

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Ensure python is available
run: |
sudo apt-get -y update && sudo apt-get -y install python3 python-is-python3
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- name: Setup Pages
id: pages
uses: actions/configure-pages@v3
- name: Build with makesite.py
run: |
python makesite.py
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: ./_site

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
}
}
128 changes: 72 additions & 56 deletions makesite.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

def fread(filename):
"""Read file and close the file."""
with open(filename, 'r') as f:
with open(filename, "r") as f:
return f.read()


Expand All @@ -19,32 +19,32 @@ def fwrite(filename, text):
if not os.path.isdir(basedir):
os.makedirs(basedir)

with open(filename, 'w') as f:
with open(filename, "w") as f:
f.write(text)


def log(msg, *args):
"""Log message with specified arguments."""
sys.stderr.write(msg.format(*args) + '\n')
sys.stderr.write(msg.format(*args) + "\n")


def truncate(text, words=25):
"""Remove tags and truncate text to the specified number of words."""
return ' '.join(re.sub('(?s)<.*?>', ' ', text).split()[:words])
return " ".join(re.sub("(?s)<.*?>", " ", text).split()[:words])


def read_headers(text):
"""Parse headers in text and yield (key, value, end-index) tuples."""
for match in re.finditer(r'\s*<!--\s*(.+?)\s*:\s*(.+?)\s*-->\s*|.+', text):
for match in re.finditer(r"\s*<!--\s*(.+?)\s*:\s*(.+?)\s*-->\s*|.+", text):
if not match.group(1):
break
yield match.group(1), match.group(2), match.end()


def rfc_2822_format(date_str):
"""Convert yyyy-mm-dd date string to RFC 2822 format date string."""
d = datetime.datetime.strptime(date_str, '%Y-%m-%d')
return d.strftime('%a, %d %b %Y %H:%M:%S +0000')
d = datetime.datetime.strptime(date_str, "%Y-%m-%d")
return d.strftime("%a, %d %b %Y %H:%M:%S +0000")


def read_content(filename):
Expand All @@ -53,11 +53,11 @@ def read_content(filename):
text = fread(filename)

# Read metadata and save it in a dictionary.
date_slug = os.path.basename(filename).split('.')[0]
match = re.search(r'^(?:(\d\d\d\d-\d\d-\d\d)-)?(.+)$', date_slug)
date_slug = os.path.basename(filename).split(".")[0]
match = re.search(r"^(?:(\d\d\d\d-\d\d-\d\d)-)?(.+)$", date_slug)
content = {
'date': match.group(1) or '1970-01-01',
'slug': match.group(2),
"date": match.group(1) or "1970-01-01",
"slug": match.group(2),
}

# Read headers.
Expand All @@ -69,20 +69,18 @@ def read_content(filename):
text = text[end:]

# Update the dictionary with content and RFC 2822 date.
content.update({
'content': text,
'rfc_2822_date': rfc_2822_format(content['date'])
})
content.update({"content": text, "rfc_2822_date": rfc_2822_format(content["date"])})

return content


def render(template, **params):
"""Replace placeholders in template with values from params."""
return re.sub(r'{{\s*([^}\s]+)\s*}}',
lambda match: str(params.get(
match.group(1), match.group(0))),
template)
return re.sub(
r"{{\s*([^}\s]+)\s*}}",
lambda match: str(params.get(match.group(1), match.group(0))),
template,
)


def make_pages(src, dst, layout, **params):
Expand All @@ -95,92 +93,110 @@ def make_pages(src, dst, layout, **params):
page_params = dict(params, **content)

# Populate placeholders in content if content-rendering is enabled.
if page_params.get('render') == 'yes':
rendered_content = render(page_params['content'], **page_params)
page_params['content'] = rendered_content
content['content'] = rendered_content
if page_params.get("render") == "yes":
rendered_content = render(page_params["content"], **page_params)
page_params["content"] = rendered_content
content["content"] = rendered_content

items.append(content)

dst_path = render(dst, **page_params)
output = render(layout, **page_params)

log('Rendering {} => {} ...', src_path, dst_path)
log("Rendering {} => {} ...", src_path, dst_path)
fwrite(dst_path, output)

return sorted(items, key=lambda x: x['date'], reverse=True)
return sorted(items, key=lambda x: x["date"], reverse=True)


def make_list(posts, dst, list_layout, item_layout, **params):
"""Generate list page for a blog."""
items = []
for post in posts:
item_params = dict(params, **post)
item_params['summary'] = truncate(post['content'])
item_params["summary"] = truncate(post["content"])
item = render(item_layout, **item_params)
items.append(item)

params['content'] = ''.join(items)
params["content"] = "".join(items)
dst_path = render(dst, **params)
output = render(list_layout, **params)

log('Rendering list => {} ...', dst_path)
log("Rendering list => {} ...", dst_path)
fwrite(dst_path, output)


def main():
# Create a new _site directory from scratch.
if os.path.isdir('_site'):
shutil.rmtree('_site')
shutil.copytree('static', '_site')
if os.path.isdir("_site"):
shutil.rmtree("_site")
shutil.copytree("static", "_site")

# Default parameters.
params = {
'base_path': '',
'subtitle': 'Lorem Ipsum',
'author': 'Admin',
'site_url': 'http://localhost:8000',
'current_year': datetime.datetime.now().year
"base_path": "",
"subtitle": "Lorem Ipsum",
"author": "Admin",
"site_url": "http://localhost:8000",
"current_year": datetime.datetime.now().year,
}

# If params.json exists, load it.
if os.path.isfile('params.json'):
params.update(json.loads(fread('params.json')))
if os.path.isfile("params.json"):
params.update(json.loads(fread("params.json")))

# Load layouts.
page_layout = fread('layout/page.html')
post_layout = fread('layout/post.html')
list_layout = fread('layout/list.html')
item_layout = fread('layout/item.html')
feed_xml = fread('layout/feed.xml')
item_xml = fread('layout/item.xml')
page_layout = fread("layout/page.html")
post_layout = fread("layout/post.html")
list_layout = fread("layout/list.html")
item_layout = fread("layout/item.html")
feed_xml = fread("layout/feed.xml")
item_xml = fread("layout/item.xml")

# Combine layouts to form final layouts.
post_layout = render(page_layout, content=post_layout)
list_layout = render(page_layout, content=list_layout)

# Create site pages.
make_pages('content/_index.html', '_site/index.html',
page_layout, **params)
make_pages('content/[!_]*.html', '_site/{{ slug }}/index.html',
page_layout, **params)
make_pages("content/_index.html", "_site/index.html", page_layout, **params)
make_pages(
"content/[!_]*.html", "_site/{{ slug }}/index.html", page_layout, **params
)

# Create blogs.
blog_posts = make_pages('content/blog/*.html',
'_site/blog/{{ slug }}/index.html',
post_layout, blog='blog', **params)
blog_posts = make_pages(
"content/blog/*.html",
"_site/blog/{{ slug }}/index.html",
post_layout,
blog="blog",
**params
)

# Create blog list pages.
make_list(blog_posts, '_site/blog/index.html',
list_layout, item_layout, blog='blog', title='Blog', **params)
make_list(
blog_posts,
"_site/blog/index.html",
list_layout,
item_layout,
blog="blog",
title="Blog",
**params
)

# Create RSS feeds.
make_list(blog_posts, '_site/blog/rss.xml',
feed_xml, item_xml, blog='blog', title='Blog', **params)
make_list(
blog_posts,
"_site/blog/rss.xml",
feed_xml,
item_xml,
blog="blog",
title="Blog",
**params
)


# Test parameter to be set temporarily by unit tests.
_test = None

if __name__ == '__main__':
if __name__ == "__main__":
main()
Loading