mirror of
https://git.ari.lt/ari.lt/blog.ari.lt.git
synced 2025-02-04 09:39:25 +01:00
update @ Sat 5 Nov 20:04:39 EET 2022
Signed-off-by: Ari Archer <ari.web.xyz@gmail.com>
This commit is contained in:
parent
eaccc341e2
commit
b0bdb02a01
5 changed files with 99 additions and 56 deletions
|
@ -1,5 +1,5 @@
|
||||||
[build]
|
[build]
|
||||||
command = "python3 ./scripts/blog static"
|
command = "python3 ./scripts/blog.py static"
|
||||||
|
|
||||||
[[redirects]]
|
[[redirects]]
|
||||||
from = "/git/*"
|
from = "/git/*"
|
||||||
|
|
14
pyproject.toml
Normal file
14
pyproject.toml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[tool.pyright]
|
||||||
|
pythonVersion = "3.10"
|
||||||
|
exclude = [
|
||||||
|
"venv",
|
||||||
|
"**/node_modules",
|
||||||
|
"**/__pycache__",
|
||||||
|
".git"
|
||||||
|
]
|
||||||
|
include = ["src", "scripts"]
|
||||||
|
venv = "venv"
|
||||||
|
stubPath = "src/stubs"
|
||||||
|
typeCheckingMode = "strict"
|
||||||
|
useLibraryCodeForTypes = true
|
||||||
|
reportMissingTypeStubs = true
|
|
@ -1 +1 @@
|
||||||
3.8
|
3.10
|
||||||
|
|
|
@ -9,20 +9,23 @@ import string
|
||||||
import sys
|
import sys
|
||||||
import xml.etree.ElementTree as etree
|
import xml.etree.ElementTree as etree
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode, b64encode
|
||||||
|
from collections.abc import Callable, Iterable
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from glob import iglob
|
from glob import iglob
|
||||||
from html import escape as html_escape
|
from html import escape as html_escape
|
||||||
|
from re import Match as RegexMatch
|
||||||
from shutil import copy as copy_file
|
from shutil import copy as copy_file
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from tempfile import gettempdir
|
from tempfile import gettempdir
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from timeit import default_timer as code_timer
|
from timeit import default_timer as code_timer
|
||||||
from typing import Any, Callable, Dict, Iterable, List, Set, Tuple, Union
|
from typing import Any, Dict, List, Optional, Set, Tuple
|
||||||
from warnings import filterwarnings as filter_warnings
|
from warnings import filterwarnings as filter_warnings
|
||||||
|
|
||||||
import ujson # type: ignore
|
import ujson # type: ignore
|
||||||
from css_html_js_minify import html_minify # type: ignore
|
from css_html_js_minify import html_minify # type: ignore
|
||||||
from css_html_js_minify import process_single_css_file
|
from css_html_js_minify import process_single_css_file # type: ignore
|
||||||
|
from markdown import core as markdown_core # type: ignore
|
||||||
from markdown import markdown # type: ignore
|
from markdown import markdown # type: ignore
|
||||||
from markdown.extensions import Extension # type: ignore
|
from markdown.extensions import Extension # type: ignore
|
||||||
from markdown.inlinepatterns import InlineProcessor # type: ignore
|
from markdown.inlinepatterns import InlineProcessor # type: ignore
|
||||||
|
@ -39,7 +42,7 @@ if NOT_CI_BUILD:
|
||||||
EXIT_OK: int = 0
|
EXIT_OK: int = 0
|
||||||
EXIT_ERR: int = 1
|
EXIT_ERR: int = 1
|
||||||
|
|
||||||
DEFAULT_CONFIG: Dict = {
|
DEFAULT_CONFIG: Dict[str, Any] = {
|
||||||
"editor-command": f"{os.environ.get('EDITOR', 'vim')} -- %s",
|
"editor-command": f"{os.environ.get('EDITOR', 'vim')} -- %s",
|
||||||
"blog-dir": "b",
|
"blog-dir": "b",
|
||||||
"git-url": "/git",
|
"git-url": "/git",
|
||||||
|
@ -220,7 +223,7 @@ HOME_PAGE_HTML_TEMPLATE: str = f"""<!DOCTYPE html>
|
||||||
</html>"""
|
</html>"""
|
||||||
|
|
||||||
|
|
||||||
def sanitise_title(title: str, titleset: Iterable, _nosep: bool = False) -> str:
|
def sanitise_title(title: str, titleset: Iterable[str], _nosep: bool = False) -> str:
|
||||||
_title: str = ""
|
_title: str = ""
|
||||||
|
|
||||||
for char in title:
|
for char in title:
|
||||||
|
@ -258,7 +261,7 @@ class BetterHeaders(Treeprocessor):
|
||||||
- Downsizes headers from h1 -> h2
|
- Downsizes headers from h1 -> h2
|
||||||
- Adds header links"""
|
- Adds header links"""
|
||||||
|
|
||||||
def run(self, root) -> None:
|
def run(self, root: etree.Element) -> None:
|
||||||
ids: List[str] = []
|
ids: List[str] = []
|
||||||
heading_sizes_em: Dict[str, float] = {
|
heading_sizes_em: Dict[str, float] = {
|
||||||
"h2": 1.32,
|
"h2": 1.32,
|
||||||
|
@ -275,10 +278,13 @@ class BetterHeaders(Treeprocessor):
|
||||||
if elem.tag not in heading_sizes_em:
|
if elem.tag not in heading_sizes_em:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if elem.text is None:
|
||||||
|
elem.text = ""
|
||||||
|
|
||||||
gen_id: str = sanitise_title(elem.text, ids)
|
gen_id: str = sanitise_title(elem.text, ids)
|
||||||
ids.append(gen_id)
|
ids.append(gen_id)
|
||||||
|
|
||||||
heading_parent = elem.makeelement(
|
heading_parent: etree.Element = elem.makeelement(
|
||||||
"div",
|
"div",
|
||||||
{
|
{
|
||||||
"data-pl": "",
|
"data-pl": "",
|
||||||
|
@ -291,8 +297,10 @@ class BetterHeaders(Treeprocessor):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
heading = heading_parent.makeelement(elem.tag, {"id": gen_id})
|
heading: etree.Element = heading_parent.makeelement(
|
||||||
link = heading.makeelement(
|
elem.tag, {"id": gen_id}
|
||||||
|
)
|
||||||
|
link: etree.Element = heading.makeelement(
|
||||||
"a",
|
"a",
|
||||||
{
|
{
|
||||||
"href": f"#{gen_id}",
|
"href": f"#{gen_id}",
|
||||||
|
@ -303,11 +311,14 @@ class BetterHeaders(Treeprocessor):
|
||||||
)
|
)
|
||||||
|
|
||||||
link.text = "#"
|
link.text = "#"
|
||||||
heading_parent.append(link)
|
|
||||||
|
|
||||||
heading.text = elem.text
|
heading.text = elem.text
|
||||||
heading_parent.append(heading)
|
|
||||||
|
|
||||||
|
heading_parent.extend(
|
||||||
|
(
|
||||||
|
link,
|
||||||
|
heading,
|
||||||
|
)
|
||||||
|
)
|
||||||
root.remove(elem)
|
root.remove(elem)
|
||||||
root.insert(idx, heading_parent)
|
root.insert(idx, heading_parent)
|
||||||
|
|
||||||
|
@ -315,11 +326,13 @@ class BetterHeaders(Treeprocessor):
|
||||||
class AddIDLinks(InlineProcessor):
|
class AddIDLinks(InlineProcessor):
|
||||||
"""Add support for <#ID> links"""
|
"""Add support for <#ID> links"""
|
||||||
|
|
||||||
def handleMatch(self, match, data: str) -> Tuple[etree.Element, Any, Any]:
|
def handleMatch( # pyright: ignore
|
||||||
|
self, match: RegexMatch[str], *_
|
||||||
|
) -> Tuple[etree.Element, Any, Any]:
|
||||||
link: etree.Element = etree.Element("a")
|
link: etree.Element = etree.Element("a")
|
||||||
|
|
||||||
link.text = match.group(1) or "#"
|
link.text = match.group(1) or "#"
|
||||||
link.set("href", link.text)
|
link.set("href", link.text or "#")
|
||||||
|
|
||||||
return link, match.start(0), match.end(0)
|
return link, match.start(0), match.end(0)
|
||||||
|
|
||||||
|
@ -327,11 +340,20 @@ class AddIDLinks(InlineProcessor):
|
||||||
class AriMarkdownExts(Extension):
|
class AriMarkdownExts(Extension):
|
||||||
"""Ari-web markdown extensions"""
|
"""Ari-web markdown extensions"""
|
||||||
|
|
||||||
def extendMarkdown(self, md, key: str = "add_header_links", index: int = int(1e8)):
|
def extendMarkdown(
|
||||||
|
self,
|
||||||
|
md: markdown_core.Markdown,
|
||||||
|
key: str = "add_header_links",
|
||||||
|
index: int = int(1e8),
|
||||||
|
):
|
||||||
md.registerExtension(self)
|
md.registerExtension(self)
|
||||||
|
|
||||||
md.treeprocessors.register(BetterHeaders(md.parser), key, index)
|
md.treeprocessors.register(
|
||||||
md.inlinePatterns.register(AddIDLinks(r"<(#.*)>", "a"), key, index)
|
BetterHeaders(md.parser), key, index # pyright: ignore
|
||||||
|
)
|
||||||
|
md.inlinePatterns.register(
|
||||||
|
AddIDLinks(r"<(#.*)>", "a"), key, index # pyright: ignore
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def log(message: str, header: str = "ERROR", code: int = EXIT_ERR) -> int:
|
def log(message: str, header: str = "ERROR", code: int = EXIT_ERR) -> int:
|
||||||
|
@ -345,7 +367,7 @@ def tmp_path(path: str) -> str:
|
||||||
return os.path.join(gettempdir(), path)
|
return os.path.join(gettempdir(), path)
|
||||||
|
|
||||||
|
|
||||||
def editor(config: Dict, file: str) -> None:
|
def editor(config: Dict[str, Any], file: str) -> None:
|
||||||
copy_file(".editorconfig", tmp_path(".editorconfig"))
|
copy_file(".editorconfig", tmp_path(".editorconfig"))
|
||||||
os.system(config["editor-command"] % file)
|
os.system(config["editor-command"] % file)
|
||||||
|
|
||||||
|
@ -388,18 +410,18 @@ def new_config() -> None:
|
||||||
ujson.dump(DEFAULT_CONFIG, cfg, indent=4)
|
ujson.dump(DEFAULT_CONFIG, cfg, indent=4)
|
||||||
|
|
||||||
|
|
||||||
def pick_blog(config: Dict) -> str:
|
def pick_blog(config: Dict[str, Any]) -> str:
|
||||||
try:
|
try:
|
||||||
blog_id: str = (
|
blog_id: str = (
|
||||||
FzfPrompt()
|
FzfPrompt()
|
||||||
.prompt(
|
.prompt( # pyright: ignore
|
||||||
map(
|
map(
|
||||||
lambda key: f"{key} | {b64decode(config['blogs'][key]['title']).decode()!r}",
|
lambda key: f"{key} | {b64decode(config['blogs'][key]['title']).decode()!r}", # pyright: ignore
|
||||||
tuple(config["blogs"].keys())[::-1],
|
tuple(config["blogs"].keys())[::-1],
|
||||||
),
|
),
|
||||||
"--prompt='Pick blog: '",
|
"--prompt='Pick blog: '",
|
||||||
)[0]
|
)[0]
|
||||||
.split()[0]
|
.split()[0] # pyright: ignore
|
||||||
)
|
)
|
||||||
except ProcessExecutionError:
|
except ProcessExecutionError:
|
||||||
log("Fzf process exited unexpectedly")
|
log("Fzf process exited unexpectedly")
|
||||||
|
@ -412,7 +434,7 @@ def pick_blog(config: Dict) -> str:
|
||||||
return blog_id
|
return blog_id
|
||||||
|
|
||||||
|
|
||||||
def new_blog(config: Dict) -> Tuple[int, Dict]:
|
def new_blog(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Make a new blog"""
|
"""Make a new blog"""
|
||||||
|
|
||||||
if title := iinput("blog title"):
|
if title := iinput("blog title"):
|
||||||
|
@ -420,8 +442,10 @@ def new_blog(config: Dict) -> Tuple[int, Dict]:
|
||||||
|
|
||||||
us_title: str = title
|
us_title: str = title
|
||||||
s_title: str = sanitise_title(us_title, config["blogs"])
|
s_title: str = sanitise_title(us_title, config["blogs"])
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unreachable")
|
||||||
|
|
||||||
blog = {
|
blog: Dict[str, Any] = {
|
||||||
"title": b64encode(us_title.encode()).decode(),
|
"title": b64encode(us_title.encode()).decode(),
|
||||||
"content": "",
|
"content": "",
|
||||||
"version": BLOG_VERSION,
|
"version": BLOG_VERSION,
|
||||||
|
@ -456,7 +480,7 @@ def new_blog(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
def build_css(config: Dict) -> Tuple[int, Dict]:
|
def build_css(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Minify (build) the CSS"""
|
"""Minify (build) the CSS"""
|
||||||
|
|
||||||
log("Minifying CSS...", "MINIFY")
|
log("Minifying CSS...", "MINIFY")
|
||||||
|
@ -466,13 +490,15 @@ def build_css(config: Dict) -> Tuple[int, Dict]:
|
||||||
|
|
||||||
css_threads: List[Thread] = []
|
css_threads: List[Thread] = []
|
||||||
|
|
||||||
def _thread(t: Callable) -> None:
|
def _thread(t: Callable[..., Any]) -> None:
|
||||||
css_threads.append(Thread(target=t, daemon=True))
|
css_threads.append(Thread(target=t, daemon=True))
|
||||||
css_threads[-1].start()
|
css_threads[-1].start()
|
||||||
|
|
||||||
if os.path.isfile("content/styles.css"):
|
if os.path.isfile("content/styles.css"):
|
||||||
log("Minifying main styles", "MINIFY")
|
log("Minifying main styles", "MINIFY")
|
||||||
_thread(lambda: process_single_css_file("content/styles.css"))
|
_thread(
|
||||||
|
lambda: process_single_css_file("content/styles.css") # pyright: ignore
|
||||||
|
)
|
||||||
|
|
||||||
if os.path.isdir("content/fonts"):
|
if os.path.isdir("content/fonts"):
|
||||||
log("Minifying fonts...", "MINIFY")
|
log("Minifying fonts...", "MINIFY")
|
||||||
|
@ -482,7 +508,7 @@ def build_css(config: Dict) -> Tuple[int, Dict]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
log(f"Minifying font file: {font}", "MINIFY")
|
log(f"Minifying font file: {font}", "MINIFY")
|
||||||
_thread(lambda: process_single_css_file(font))
|
_thread(lambda: process_single_css_file(font)) # pyright: ignore
|
||||||
|
|
||||||
for t in css_threads:
|
for t in css_threads:
|
||||||
t.join()
|
t.join()
|
||||||
|
@ -495,7 +521,7 @@ def build_css(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
def build(config: Dict) -> Tuple[int, Dict]:
|
def build(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Build, minimise and generate site"""
|
"""Build, minimise and generate site"""
|
||||||
|
|
||||||
if not config["blogs"]:
|
if not config["blogs"]:
|
||||||
|
@ -510,7 +536,7 @@ def build(config: Dict) -> Tuple[int, Dict]:
|
||||||
|
|
||||||
log("Building blogs...", "INFO")
|
log("Building blogs...", "INFO")
|
||||||
|
|
||||||
def thread(blog_id: str, blog_meta: Dict):
|
def thread(blog_id: str, blog_meta: Dict[str, Any]):
|
||||||
if blog_meta["version"] != BLOG_VERSION:
|
if blog_meta["version"] != BLOG_VERSION:
|
||||||
log(
|
log(
|
||||||
f"{blog_id}: unmatching version between \
|
f"{blog_id}: unmatching version between \
|
||||||
|
@ -583,7 +609,7 @@ def build(config: Dict) -> Tuple[int, Dict]:
|
||||||
log("Building blog index...", "INFO")
|
log("Building blog index...", "INFO")
|
||||||
|
|
||||||
with open("index.html", "w") as index:
|
with open("index.html", "w") as index:
|
||||||
lastest_blog: Dict = config["blogs"][latest_blog_id]
|
lastest_blog: Dict[str, Any] = config["blogs"][latest_blog_id]
|
||||||
lastest_blog_time: str = format_time(lastest_blog["time"])
|
lastest_blog_time: str = format_time(lastest_blog["time"])
|
||||||
|
|
||||||
blog_list = '<ol reversed="true" aria-label="latest blogs">'
|
blog_list = '<ol reversed="true" aria-label="latest blogs">'
|
||||||
|
@ -619,7 +645,7 @@ def build(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
def list_blogs(config: Dict) -> Tuple[int, Dict]:
|
def list_blogs(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""List blogs"""
|
"""List blogs"""
|
||||||
|
|
||||||
if not config["blogs"]:
|
if not config["blogs"]:
|
||||||
|
@ -638,7 +664,7 @@ Keywords: {blog_meta['keywords'].replace(" ", ", ")}
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
def remove_blog(config: Dict) -> Tuple[int, Dict]:
|
def remove_blog(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Remove a blog page"""
|
"""Remove a blog page"""
|
||||||
|
|
||||||
if not config["blogs"]:
|
if not config["blogs"]:
|
||||||
|
@ -653,11 +679,13 @@ def remove_blog(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
def dummy() -> None:
|
def dummy(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Print help/usage information"""
|
"""Print help/usage information"""
|
||||||
|
|
||||||
|
return EXIT_OK, config
|
||||||
|
|
||||||
def edit_title(blog: str, config: Dict) -> int:
|
|
||||||
|
def edit_title(blog: str, config: Dict[str, Any]) -> int:
|
||||||
new_title: str = iinput(
|
new_title: str = iinput(
|
||||||
"edit title", b64decode(config["blogs"][blog]["title"]).decode()
|
"edit title", b64decode(config["blogs"][blog]["title"]).decode()
|
||||||
)
|
)
|
||||||
|
@ -679,7 +707,7 @@ def edit_title(blog: str, config: Dict) -> int:
|
||||||
return EXIT_OK
|
return EXIT_OK
|
||||||
|
|
||||||
|
|
||||||
def edit_keywords(blog: str, config: Dict) -> int:
|
def edit_keywords(blog: str, config: Dict[str, Any]) -> int:
|
||||||
new_keywords: str = iinput("edit keywords", config["blogs"][blog]["keywords"])
|
new_keywords: str = iinput("edit keywords", config["blogs"][blog]["keywords"])
|
||||||
|
|
||||||
if not new_keywords.strip():
|
if not new_keywords.strip():
|
||||||
|
@ -690,7 +718,7 @@ def edit_keywords(blog: str, config: Dict) -> int:
|
||||||
return EXIT_OK
|
return EXIT_OK
|
||||||
|
|
||||||
|
|
||||||
def edit_content(blog: str, config: Dict) -> int:
|
def edit_content(blog: str, config: Dict[str, Any]) -> int:
|
||||||
file: str = tmp_path(f"{blog}.md")
|
file: str = tmp_path(f"{blog}.md")
|
||||||
|
|
||||||
with open(file, "w") as blog_md:
|
with open(file, "w") as blog_md:
|
||||||
|
@ -710,15 +738,15 @@ def edit_content(blog: str, config: Dict) -> int:
|
||||||
return EXIT_OK
|
return EXIT_OK
|
||||||
|
|
||||||
|
|
||||||
EDIT_HOOKS: Dict = {
|
EDIT_HOOKS: Dict[str, Callable[[str, Dict[str, Any]], int]] = {
|
||||||
"quit": lambda *_: EXIT_OK,
|
"quit": lambda *_: EXIT_OK, # pyright: ignore
|
||||||
"title": edit_title,
|
"title": edit_title,
|
||||||
"keywords": edit_keywords,
|
"keywords": edit_keywords,
|
||||||
"content": edit_content,
|
"content": edit_content,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def edit(config: Dict) -> Tuple[int, Dict]:
|
def edit(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Edit a blog"""
|
"""Edit a blog"""
|
||||||
|
|
||||||
if not config["blogs"]:
|
if not config["blogs"]:
|
||||||
|
@ -730,9 +758,9 @@ def edit(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_ERR, config
|
return EXIT_ERR, config
|
||||||
|
|
||||||
try:
|
try:
|
||||||
hook: str = FzfPrompt().prompt(EDIT_HOOKS.keys(), "--prompt='What to edit: '")[
|
hook: str = FzfPrompt().prompt( # pyright: ignore
|
||||||
0
|
EDIT_HOOKS.keys(), "--prompt='What to edit: '"
|
||||||
]
|
)[0]
|
||||||
|
|
||||||
if hook not in EDIT_HOOKS:
|
if hook not in EDIT_HOOKS:
|
||||||
return log(f"Hook {hook!r} does not exist"), config
|
return log(f"Hook {hook!r} does not exist"), config
|
||||||
|
@ -744,7 +772,7 @@ def edit(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
def gen_def_config(config: Dict) -> Tuple[int, Dict]:
|
def gen_def_config(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Generate default config"""
|
"""Generate default config"""
|
||||||
|
|
||||||
if os.path.exists(DEFAULT_CONFIG_FILE):
|
if os.path.exists(DEFAULT_CONFIG_FILE):
|
||||||
|
@ -759,7 +787,7 @@ def gen_def_config(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
def clean(config: Dict) -> Tuple[int, Dict]:
|
def clean(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Clean up current directory"""
|
"""Clean up current directory"""
|
||||||
|
|
||||||
TRASH: Set[str] = {
|
TRASH: Set[str] = {
|
||||||
|
@ -789,7 +817,7 @@ def clean(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
def generate_metadata(config: Dict) -> Tuple[int, Dict]:
|
def generate_metadata(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Generate metadata"""
|
"""Generate metadata"""
|
||||||
|
|
||||||
with open("manifest.json", "w") as manifest:
|
with open("manifest.json", "w") as manifest:
|
||||||
|
@ -820,10 +848,10 @@ def generate_metadata(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
def generate_static_full(config: Dict) -> Tuple[int, Dict]:
|
def generate_static_full(config: Dict[str, Any]) -> Tuple[int, Dict[str, Any]]:
|
||||||
"""Generate full static site"""
|
"""Generate full static site"""
|
||||||
|
|
||||||
BUILD_CFG: Dict = {
|
BUILD_CFG: Dict[str, Callable[[Dict[str, Any]], Tuple[int, Dict[str, Any]]]] = {
|
||||||
"Cleaning up": clean,
|
"Cleaning up": clean,
|
||||||
"Building CSS": build_css,
|
"Building CSS": build_css,
|
||||||
"Building static site": build,
|
"Building static site": build,
|
||||||
|
@ -841,7 +869,7 @@ def generate_static_full(config: Dict) -> Tuple[int, Dict]:
|
||||||
return EXIT_OK, config
|
return EXIT_OK, config
|
||||||
|
|
||||||
|
|
||||||
SUBCOMMANDS: Dict = {
|
SUBCOMMANDS: Dict[str, Callable[[Dict[str, Any]], Tuple[int, Dict[str, Any]]]] = {
|
||||||
"help": dummy,
|
"help": dummy,
|
||||||
"new": new_blog,
|
"new": new_blog,
|
||||||
"build": build,
|
"build": build,
|
||||||
|
@ -856,7 +884,7 @@ SUBCOMMANDS: Dict = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def usage(code: int = EXIT_ERR, config: Dict = None) -> int:
|
def usage(code: int = EXIT_ERR, _: Optional[Dict[str, Any]] = None) -> int:
|
||||||
sys.stderr.write(f"Usage: {sys.argv[0]} <subcommand>\n")
|
sys.stderr.write(f"Usage: {sys.argv[0]} <subcommand>\n")
|
||||||
|
|
||||||
for subcommand, func in SUBCOMMANDS.items():
|
for subcommand, func in SUBCOMMANDS.items():
|
||||||
|
@ -897,7 +925,10 @@ def main() -> int:
|
||||||
with open(DEFAULT_CONFIG_FILE, "r") as lcfg:
|
with open(DEFAULT_CONFIG_FILE, "r") as lcfg:
|
||||||
cmd_time_init = code_timer()
|
cmd_time_init = code_timer()
|
||||||
|
|
||||||
code, config = SUBCOMMANDS[sys.argv[1]](config=ujson.load(lcfg))
|
code: int
|
||||||
|
config: Dict[str, Any]
|
||||||
|
|
||||||
|
code, config = SUBCOMMANDS[sys.argv[1]](ujson.load(lcfg))
|
||||||
|
|
||||||
log(
|
log(
|
||||||
f"Finished in {code_timer() - cmd_time_init} seconds with code {code}",
|
f"Finished in {code_timer() - cmd_time_init} seconds with code {code}",
|
||||||
|
@ -927,9 +958,7 @@ def main() -> int:
|
||||||
|
|
||||||
log(f"Dumped config in {code_timer() - dump_timer} seconds", "TIME")
|
log(f"Dumped config in {code_timer() - dump_timer} seconds", "TIME")
|
||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
return EXIT_OK
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
|
@ -3,7 +3,7 @@
|
||||||
set -xe
|
set -xe
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
python3 scripts/blog clean
|
python3 scripts/blog.py clean
|
||||||
|
|
||||||
git diff >/tmp/ari-web-blog.diff
|
git diff >/tmp/ari-web-blog.diff
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue