{e(p["title"])}
{e(p.get("summary", ""))}
"""Small static publisher. Content and application registry are the source of truth."""
from pathlib import Path
from datetime import datetime
from html import escape
from urllib.parse import quote, urlsplit, unquote
import json
import re
import shutil
import hashlib
import xml.etree.ElementTree as ET
import mistune
import yaml
ROOT = Path(__file__).resolve().parent
OUT = ROOT / 'public'
BASE = 'https://famzheng.me'
DESCRIPTION = '软件工程师。系统、AI,造点有意思的东西。'
ICONS = {
'music': '
{e(code)}\n'
return super().block_code(code, info)
markdown = mistune.create_markdown(renderer=Renderer(escape=False), plugins=['table', 'strikethrough', 'url'])
def load_post(path):
match = re.match(r'^---\s*\n(.*?)\n---\s*\n(.*)', path.read_text(), re.S)
if not match:
raise ValueError(f'Missing frontmatter: {path}')
meta = yaml.safe_load(match[1])
meta.update(slug=path.stem, body=markdown(match[2]), raw=match[2])
meta['url'] = '/about/' if path.stem == 'about' else f'/posts/{path.stem}/'
meta['date'] = str(meta.get('date', ''))[:10]
return meta
def layout(title, content, path='/', description=DESCRIPTION):
active = 'apps' if path == '/' else 'posts' if path.startswith('/posts') else 'about'
css_hash = hashlib.sha256((ROOT/'assets/site.css').read_bytes()).hexdigest()[:12]
return f'''
{e(p.get("summary", ""))}
{e(app["subtitle"])}
' if featured else ''}{e(app['description'])}
{e(app['category'])}''' def build(): # The only removable directory is this generated, repository-local output. if OUT.is_symlink(): raise ValueError('public must not be a symlink') if OUT.exists(): shutil.rmtree(OUT) OUT.mkdir() shutil.copytree(ROOT/'assets', OUT/'assets') shutil.copytree(ROOT/'static', OUT, dirs_exist_ok=True) apps = json.loads((ROOT/'apps.json').read_text()) assert len({a['url'] for a in apps}) == len(apps), 'Duplicate application URL' for app in apps: assert app['url'].startswith('https://') or app['url'].startswith('/'), 'Unsafe URL' assert not urlsplit(app['url']).fragment, 'Never publish access tokens in links' posts = sorted((load_post(p) for p in (ROOT/'content/posts').glob('*.md')), key=lambda p:p['date'], reverse=True) posts = [p for p in posts if not p.get('draft')] featured = ''.join(app_card(a, i, True) for i,a in enumerate(apps) if a.get('featured')) all_apps = ''.join(app_card(a, i) for i,a in enumerate(apps)) categories = ''.join(f'' for c in dict.fromkeys(a['category'] for a in apps)) home = f'''暂时没有找到,换个关键词试试。
部分应用仍在实验中,私人应用和内测入口需要相应的访问权限。
NOTES FROM THE WORKBENCH
系统、工具、AI,以及造东西时留下的思考。
{e(p.get("summary", ""))}
HELLO, I’M FAM
这里收着一些自己用的小应用和实验,也记录我在造什么、在想什么。想法是我的,大部分文章由 AI 代笔整理。
404
这个地址暂时没有内容。回到首页 →