Files
pyrom/app/routes/guides.py

112 lines
3.2 KiB
Python

from flask import Blueprint, render_template, render_template_string, current_app, abort
from pathlib import Path
import re
bp = Blueprint('guides', __name__, url_prefix='/guides/')
def parse_guide_title(content: str):
lines = content.strip().split('\n', 1)
fline = lines[0].strip()
if fline.startswith('#'):
title = fline[2:].strip()
content = lines[1] if len(lines) > 1 else ''
return title, content.strip()
return None, content.strip()
def get_guides_by_category():
guides_dir = Path(current_app.root_path) / 'templates' / 'guides'
categories = {}
for item in guides_dir.iterdir():
if item.is_dir() and not item.name.startswith('_'):
category = item.name
categories[category] = []
for guide_file in sorted(item.glob('*.html')):
if guide_file.name.startswith('_'):
continue
m = re.match(r'(\d+)-(.+)\.html', guide_file.name)
if not m:
continue
sort_num = int(m.group(1))
slug = m.group(2)
try:
with open(guide_file, 'r') as f:
content = f.read()
title, template = parse_guide_title(content)
if not title:
title = slug.replace('-', ' ').title()
categories[category].append(({
'sort': sort_num,
'slug': slug,
'filename': guide_file.name,
'title': title,
'path': f'{category}/{guide_file.name}',
'url': f'/guides/{category}/{slug}',
'template': template,
}))
except Exception as e:
current_app.logger.warning(f'failed to read {guide_file}: {e}')
continue
categories[category].sort(key=lambda x: x['sort'])
return categories
@bp.get('/babycode')
def babycode():
# print(get_guides_by_category())
return '<h1>no</h1>'
@bp.get('/<category>/<slug>')
def guide_page(category, slug):
categories = get_guides_by_category()
if category not in categories:
abort(404)
return
for i, guide in enumerate(categories[category]):
if guide['slug'] != slug:
continue
next_guide = None
prev_guide = None
if i != 0:
prev_guide = categories[category][i - 1]
if i + 1 < len(categories[category]):
next_guide = categories[category][i + 1]
return render_template_string(guide['template'], next_guide=next_guide, prev_guide=prev_guide, category=category, guide=guide)
abort(404)
@bp.get('/<category>/')
def category_index(category):
categories = get_guides_by_category()
if category not in categories:
abort(404)
return
return render_template('guides/category_index.html', category=category, pages=categories[category])
@bp.get('/')
def guides_index():
return render_template('guides/guides_index.html', categories=get_guides_by_category())
@bp.get('/contact')
def contact():
return render_template('guides/contact.html')