112 lines
3.2 KiB
Python
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')
|