jimsite/testbench.ipynb

335 lines
14 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "dda60de8",
"metadata": {},
"source": [
"## Roadmap\n",
"\n",
"- [x] Load markdown\n",
"- [] Determine static website structure\n",
" - Where to put assets for subsites like dogma jimfinium\n",
" - How to otherwise organize pages\n",
"- [x] ~~Resolve markdown links~~\n",
"- [] Consider separating article templates and overall page templates\n",
"- [] RSS feed\n",
"\n",
"\n",
"WEBROOT\n",
"- assets\n",
"- main pages\n",
"- resume\n",
"- dogma-jimfinium/\n",
" - assets/\n",
" - pages"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "207d2510",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import shutil\n",
"import markdown\n",
"import yaml\n",
"import subprocess\n",
"import rfeed\n",
"import pydantic\n",
"from typing import Optional, Union, Literal, BinaryIO, Any\n",
"\n",
"\n",
"\n",
"from datetime import datetime\n",
"from main import *"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4b17a3ed",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'dist/assets'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"PARTIALS = load_partials()\n",
"shutil.rmtree('dist/assets', ignore_errors=True)\n",
"shutil.copytree('assets','dist/assets')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d2361c42",
"metadata": {},
"outputs": [
{
"ename": "ValidationError",
"evalue": "2 validation errors for ArticleMetadata\ndate\n Input should be a valid string [type=string_type, input_value=datetime.date(2026, 1, 30), input_type=date]\n For further information visit https://errors.pydantic.dev/2.12/v/string_type\nlastmod\n Field required [type=missing, input_value={'title': 'Welcome', 'dat...shed': True, 'tags': []}, input_type=dict]\n For further information visit https://errors.pydantic.dev/2.12/v/missing",
"output_type": "error",
"traceback": [
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
"\u001b[31mValidationError\u001b[39m Traceback (most recent call last)",
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m metadata, content = \u001b[43mload_markdown\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mpages/home.md\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 2\u001b[39m \u001b[38;5;66;03m# content = content.replace('src=\"assets', 'src=\"../tmp/dogma-jimfinium/assets')\u001b[39;00m\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/projects/shepich.com/main.py:59\u001b[39m, in \u001b[36mload_markdown\u001b[39m\u001b[34m(md)\u001b[39m\n\u001b[32m 56\u001b[39m \u001b[38;5;66;03m# Convert the contents to a HTML string.\u001b[39;00m\n\u001b[32m 57\u001b[39m content = markdown.markdown(raw_article)\n\u001b[32m---> \u001b[39m\u001b[32m59\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mArticleMetadata\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m)\u001b[49m, content\n",
"\u001b[36mFile \u001b[39m\u001b[32m~/projects/shepich.com/.venv/lib/python3.12/site-packages/pydantic/main.py:250\u001b[39m, in \u001b[36mBaseModel.__init__\u001b[39m\u001b[34m(self, **data)\u001b[39m\n\u001b[32m 248\u001b[39m \u001b[38;5;66;03m# `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks\u001b[39;00m\n\u001b[32m 249\u001b[39m __tracebackhide__ = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m250\u001b[39m validated_self = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m__pydantic_validator__\u001b[49m\u001b[43m.\u001b[49m\u001b[43mvalidate_python\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mself_instance\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 251\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m validated_self:\n\u001b[32m 252\u001b[39m warnings.warn(\n\u001b[32m 253\u001b[39m \u001b[33m'\u001b[39m\u001b[33mA custom validator is returning a value other than `self`.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33m'\u001b[39m\n\u001b[32m 254\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mReturning anything other than `self` from a top level model validator isn\u001b[39m\u001b[33m'\u001b[39m\u001b[33mt supported when validating via `__init__`.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 255\u001b[39m \u001b[33m'\u001b[39m\u001b[33mSee the `model_validator` docs (https://docs.pydantic.dev/latest/concepts/validators/#model-validators) for more details.\u001b[39m\u001b[33m'\u001b[39m,\n\u001b[32m 256\u001b[39m stacklevel=\u001b[32m2\u001b[39m,\n\u001b[32m 257\u001b[39m )\n",
"\u001b[31mValidationError\u001b[39m: 2 validation errors for ArticleMetadata\ndate\n Input should be a valid string [type=string_type, input_value=datetime.date(2026, 1, 30), input_type=date]\n For further information visit https://errors.pydantic.dev/2.12/v/string_type\nlastmod\n Field required [type=missing, input_value={'title': 'Welcome', 'dat...shed': True, 'tags': []}, input_type=dict]\n For further information visit https://errors.pydantic.dev/2.12/v/missing"
]
}
],
"source": [
"metadata, content = load_markdown('pages/home.md')\n",
"# content = content.replace('src=\"assets', 'src=\"../tmp/dogma-jimfinium/assets')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0bb15524",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "ed7b3b2f",
"metadata": {},
"outputs": [],
"source": [
"html = format_html_template('templates/pages/default.html', content = content, **{'metadata.'+k:v for k,v in metadata.items()}, **PARTIALS)\n",
"with open('dist/home.html', 'w') as f:\n",
" f.write(html)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b8c87620",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "57383c24",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2025-12-01\n"
]
},
{
"data": {
"text/plain": [
"CompletedProcess(args=['cp', 'build/resume/2025-12-01/shepich_resume.pdf', 'dist/shepich_resume.pdf'], returncode=0, stdout=b'', stderr=b'')"
]
},
"execution_count": 170,
"metadata": {},
"output_type": "execute_result"
}
],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "944a5efd",
"metadata": {},
"outputs": [],
"source": [
"shutil.rmtree('dist/dogma-jimfinium', ignore_errors=True)\n",
"os.makedirs('dist/dogma-jimfinium', exist_ok=True)\n",
"shutil.copytree('build/dogma-jimfinium/assets', 'dist/dogma-jimfinium/assets')\n",
"\n",
"index = {}\n",
"\n",
"for article in os.listdir('build/dogma-jimfinium'):\n",
" metadata, content = load_markdown(f'build/dogma-jimfinium/{article}')\n",
"\n",
" # Skip unpublished articles.\n",
" if not metadata.get('published'):\n",
" continue\n",
"\n",
" article_filestem = os.path.splitext(article)[0]\n",
"\n",
" # Add the article to the index.\n",
" index[article_filestem] = (metadata, content)\n",
"\n",
" # Interpolate the article contents into the webpage template.\n",
" article_html = format_html_template(\n",
" 'templates/components/blog_article.html',\n",
" content = content,\n",
" blog_tags = ' '.join(format_blog_tags(metadata['tags'])),\n",
" **{'metadata.'+k:v for k,v in metadata.items()}\n",
" )\n",
" html = format_html_template('templates/pages/default.html', content = article_html, **PARTIALS)\n",
" \n",
" # Write the HTML file to /dist/dogma-jimfinium.\n",
" with open(f'dist/dogma-jimfinium/{article_filestem}.html', 'w') as f:\n",
" f.write(html)\n",
"\n",
"\n",
"index_html = build_blog_archive(index, metadata.title = 'Dogma Jimfinium | Index', **PARTIALS)\n",
"# Write the HTML file to /dist/dogma-jimfinium.\n",
"with open(f'dist/dogma-jimfinium/index.html', 'w') as f:\n",
" f.write(index_html)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "132a32ec",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"datetime.date(2024, 7, 12)"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"metadata['date']"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d48110fc",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"datetime.datetime(2024, 7, 12, 0, 0)"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"datetime(metadata['date'].year, metadata['date'].month, metadata['date'].day)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e32458c7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<rss version=\"2.0\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"><channel><title>Dogma Jimfinium</title><link>http://localhost:8000/dogma-jimfinium/rss</link><description>Dogma Jimfinium</description><language>en-US</language><lastBuildDate>Thu, 29 Jan 2026 16:29:57 GMT</lastBuildDate><generator>rfeed v1.1.1</generator><docs>https://github.com/svpino/rfeed/blob/master/README.md</docs><item><title>Superlock</title><link>http://localhost:8000/dogma-jimfinium/superlock</link><author>Jim Shepich III</author><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><guid isPermaLink=\"true\">superlock</guid></item><item><title>Sustainable Living</title><link>http://localhost:8000/dogma-jimfinium/sustainable-living</link><author>Jim Shepich III</author><pubDate>Thu, 20 Nov 2025 00:00:00 GMT</pubDate><guid isPermaLink=\"true\">sustainable-living</guid></item><item><title>Stocking Up</title><link>http://localhost:8000/dogma-jimfinium/stocking-up</link><author>Jim Shepich III</author><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><guid isPermaLink=\"true\">stocking-up</guid></item><item><title>Set Up the Toys</title><link>http://localhost:8000/dogma-jimfinium/set-up-the-toys</link><author>Jim Shepich III</author><pubDate>Wed, 14 Jan 2026 00:00:00 GMT</pubDate><guid isPermaLink=\"true\">set-up-the-toys</guid></item><item><title>Do What You Love</title><link>http://localhost:8000/dogma-jimfinium/do-what-you-love</link><author>Jim Shepich III</author><pubDate>Tue, 10 Jun 2025 00:00:00 GMT</pubDate><guid isPermaLink=\"true\">do-what-you-love</guid></item><item><title>Self-Care is not Selfish</title><link>http://localhost:8000/dogma-jimfinium/self-care-is-not-selfish</link><author>Jim Shepich III</author><pubDate>Sun, 18 May 2025 00:00:00 GMT</pubDate><guid isPermaLink=\"true\">self-care-is-not-selfish</guid></item><item><title>Blowouts</title><link>http://localhost:8000/dogma-jimfinium/blowouts</link><author>Jim Shepich III</author><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><guid isPermaLink=\"true\">blowouts</guid></item><item><title>Vitamins &amp; Supplements</title><link>http://localhost:8000/dogma-jimfinium/vitamins</link><author>Jim Shepich III</author><pubDate>Sun, 18 May 2025 00:00:00 GMT</pubDate><guid isPermaLink=\"true\">vitamins</guid></item><item><title>Gear for New Parents</title><link>http://localhost:8000/dogma-jimfinium/gear-for-new-parents</link><author>Jim Shepich III</author><pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate><guid isPermaLink=\"true\">gear-for-new-parents</guid></item></channel></rss>\n"
]
}
],
"source": [
"rss_feed = rfeed.Feed(\n",
" title = \"Dogma Jimfinium\",\n",
" link = \"http://localhost:8000/dogma-jimfinium/rss\",\n",
" description = \"Dogma Jimfinium\",\n",
" language = \"en-US\",\n",
" lastBuildDate = datetime.now(),\n",
" items = [\n",
" rfeed.Item(\n",
" title = metadata['title'],\n",
" link = f\"http://localhost:8000/dogma-jimfinium/{filestem}\", \n",
" description = metadata.get('description'),\n",
" author = metadata.get('author', 'Jim Shepich III'),\n",
" guid = rfeed.Guid(filestem),\n",
" pubDate = datetime(metadata['date'].year, metadata['date'].month, metadata['date'].day)\n",
" )\n",
" for filestem, (metadata, _) in index.items()\n",
" ]\n",
")\n",
"\n",
"print(rss_feed.rss())"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6c160693",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "57ef8185",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "b068c448",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "e3171afd",
"metadata": {},
"outputs": [],
"source": [
"def build_site(site_config: SiteConfig):\n",
" "
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}