Skip to content

Commit

Permalink
feat: refactored backend; bump version
Browse files Browse the repository at this point in the history
  • Loading branch information
yozachar committed Feb 17, 2024
1 parent 7bdd814 commit 3f2f163
Show file tree
Hide file tree
Showing 17 changed files with 237 additions and 187 deletions.
36 changes: 18 additions & 18 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,17 @@ jobs:
steps:
# Checkout repository
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Setup Node
- name: Setup Node 18
uses: actions/setup-node@v3
- name: Setup Node 20
uses: actions/setup-node@v4
with:
node-version: "18"
node-version: "20"
# Setup Python
- name: Setup Python 3.11
uses: actions/setup-python@v4
- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.11"
# Build landing page
- name: Build frontend
run: |
corepack enable
pnpm install
pnpm build --base /hymnal/
python-version: "3.12"
# Populate HTML template with JSON
- name: Generate static content
run: |
Expand All @@ -57,15 +51,21 @@ jobs:
pip install .
python src/hymnal/main.py
deactivate
git clone --depth 1 "https://github.com/hakimel/reveal.js.git" dist/lib/reveal.js
# Build frontend
- name: Build frontend
run: |
corepack enable
corepack prepare pnpm@latest --activate
pnpm install
pnpm build
# Setup Pages
- name: Setup Pages
uses: actions/configure-pages@v3
uses: actions/configure-pages@v4
# Upload static page
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
uses: actions/upload-pages-artifact@v3
with:
path: ${{ env.BUILD_PATH }}/dist
path: ${{ env.BUILD_PATH }}/build
deploy:
environment:
name: github-pages
Expand All @@ -75,4 +75,4 @@ jobs:
name: Deploy
steps:
- name: Deploy to GitHub Pages
uses: actions/deploy-pages@v1
uses: actions/deploy-pages@v4
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,6 @@ vite.config.ts.timestamp-*
# project
hymnal/temp/
scripts/
# songbook - related
static/lib/
static/ag/
2 changes: 1 addition & 1 deletion compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ services:
ports:
- "8080:80"
volumes:
- ./dist:/usr/share/nginx/html:ro
- ./build:/usr/share/nginx/html:ro
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "hymnal",
"private": true,
"version": "0.1.7",
"version": "0.2.0",
"description": "multilingual christian hymnal",
"type": "module",
"author": "Jovial Joe Jayarson",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "hymnal"
version = "0.1.7"
version = "0.2.0"
description = "multilingual christian hymnal"
authors = [{ name = "Jovial Joe Jayarson", email = "[email protected]" }]
license = { text = "AGPL-3.0-only" }
Expand Down
12 changes: 8 additions & 4 deletions deploy.sh → run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ command_exists() {
}

# cleanup
rm -rf ./dist/
rm -rf ./build/

# build
echo -e "${BLUE}==> Build & Generate${RESET}"
pnpm build &&
pdm run python ./src/hymnal/main.py &&
git clone --depth 1 "https://github.com/hakimel/reveal.js.git" ./dist/hymnal/lib/reveal.js
pdm run python ./src/hymnal/main.py &&
pnpm build

# # preview
# pnpm preview

# deploy
commands=("docker" "podman")
Expand All @@ -37,3 +39,5 @@ for cmd in "${commands[@]}"; do
done
echo -e "\n${RED}==> Error: Deploymnet failed${RESET}"
exit 1

set +e
60 changes: 60 additions & 0 deletions src/hymnal/html2json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Transform HTML to JSON."""

# standard
from dataclasses import asdict
from pathlib import Path
from json import dump

# external
from bs4 import BeautifulSoup

# local
from hymnal.sketch import Hymn, Verse


def _html_song_parser(hymn_file: Path):
"""Parse songs from reveal.js HTML files."""
with open(file=hymn_file, mode="rt", encoding="utf-8") as html_file:
html_content = html_file.read()
soup = BeautifulSoup(html_content, "lxml")
hymn = Hymn()
if hymn_number_tag := soup.select_one("h1.hymn-no"):
hymn.number = int(hymn_number_tag.text)
hymn.starts = (
"refrain"
if '<section id="refrain" class="start-here">' in html_content
else "verse-1"
)
for each_verse in soup.select('section[id^="verse-"]'):
verse_number = (
int(verse_number_tag.text.rstrip("."))
if (verse_number_tag := each_verse.select_one("p.verse-no"))
else -1
)
lines = [line_tag.text.strip() for line_tag in each_verse.select("h3")]
lines.extend([line_tag.text.strip() for line_tag in each_verse.select("h4")])
hymn.verses.append(Verse(number=verse_number, lines=lines))
if (refrain_tag := soup.select_one('section[id^="refrain"]')) and (
refrain := refrain_tag.select("em")
):
hymn.refrain = [line_tag.text.strip() for line_tag in refrain]
hymn.verses.sort(key=lambda verses: verses.number)
return hymn


def h2j_transform(source: Path, destination: Path):
"""Convert HTML to JSON."""
for idx in range(1, 1632):
hymn_path = source / f"{str(idx).zfill(4)}.html"
if not hymn_path.exists() or not hymn_path.is_file():
continue
with open(
file=destination / f"{str(idx).zfill(4)}.json",
mode="wt",
encoding="utf-8",
) as json_file:
dump(
obj=asdict(_html_song_parser(hymn_path)),
fp=json_file,
ensure_ascii=False,
)
76 changes: 76 additions & 0 deletions src/hymnal/json2html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Transform JSON to HTML."""

# standard
from logging import DEBUG, INFO, debug, getLogger
from pathlib import Path
from json import load

# external
from jinja2 import Environment, PackageLoader, select_autoescape

# local
from hymnal.sketch import Hymn


def _json_song_parser(hymn_path: Path, hymnal_name: str):
"""Parse songs from JSON files."""
with open(file=hymn_path, mode="rb") as json_file:
hymn = Hymn(**load(json_file))
if hymn.number == -1:
return (
"<html>"
+ "<head><title>BAD FILE</title></head>"
+ f"<body><p>Bad File Error: {hymn_path}</p><body>"
+ "</html>"
)
cathedral = Environment(
loader=PackageLoader("main"),
autoescape=select_autoescape(),
trim_blocks=True,
lstrip_blocks=True,
)
song_template = (
(
"start-at-refrain-without-verses.html.j2"
if not hymn.verses
else "start-at-refrain.html.j2"
)
if hymn.starts == "refrain"
else (
"start-at-verse-without-refrain.html.j2"
if not hymn.refrain
else "start-at-verse-with-refrain.html.j2"
)
)
# .render(**kwargs) ignores keys not found in template
return cathedral.get_template(song_template).render(
hymn_number=hymn.number,
hymnal_name=hymnal_name,
relative_path="..",
start_tag="<h3>",
first_verse=hymn.verses[0] if hymn.verses else None,
verses=hymn.verses if hymn.starts == "refrain" else hymn.verses[1:],
end_tag="</h3>",
start_ref_tag="<h3><em>",
refrain=hymn.refrain,
end_ref_tag="</em></h3>",
)


def j2h_transform(source: Path, destination: Path, hymnal_name: str):
"""Convert JSON to HTML."""
getLogger().setLevel(DEBUG)
for idx in range(1, 1632): # NOTE: this is not cool!
file_name = str(idx).zfill(4)
hymn_path = source / f"{file_name}.json"
if not hymn_path.exists() or not hymn_path.is_file():
continue
with open(
file=destination / f"{file_name}.html",
mode="wt",
encoding="utf-8",
) as html_file:
html_file.write(_json_song_parser(hymn_path, hymnal_name))
print(f"Created file {file_name}.html", end="\r")
debug(" file generation complete\n")
getLogger().setLevel(INFO)
Loading

0 comments on commit 3f2f163

Please sign in to comment.