Skip to content

Update: 解决问题 #438

Update: 解决问题

Update: 解决问题 #438

Workflow file for this run

name: Auto Fix Frontmatter & Fill Images
on:
push:
paths:
- 'XHBlogs/moments/**/*.md'
- 'XHBlogs/posts/**/*.md'
- 'XHBlogs/chatters/**/*.md'
- 'XHBlogs/public/moments/**'
- 'XHBlogs/public/posts/**'
- 'XHBlogs/public/chatters/**'
workflow_dispatch:
jobs:
fix-and-fill:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install python-frontmatter pyyaml Pillow
- name: Auto convert images to WebP, delete originals, fill and fix frontmatter
run: |
python << 'EOF'
import os
from datetime import datetime, timezone, timedelta
import glob
import re
from pathlib import Path
from PIL import Image
# ==================== 第零部分:自动将图片转为 WebP 并删除原图 ====================
image_dirs = [
Path("XHBlogs/public/moments"),
Path("XHBlogs/public/posts"),
Path("XHBlogs/public/chatters")
]
for img_base in image_dirs:
if img_base.exists() and img_base.is_dir():
for img_path in list(img_base.glob("**/*")):
if img_path.is_file() and img_path.suffix.lower() in ['.jpg', '.jpeg', '.png']:
try:
webp_path = img_path.with_suffix('.webp')
if not webp_path.exists():
with Image.open(img_path) as im:
im.save(webp_path, 'WEBP', quality=85)
print(f"🔄 Converted to WebP: {img_path.name} -> {webp_path.name}")
# 转换成功后,安全删除原图
img_path.unlink()
print(f"🗑️ Deleted original image: {img_path.name}")
except Exception as e:
print(f"⚠️ Failed to process {img_path}: {e}")
# ==================== 第一部分:自动填充图片路径(支持 moments 和 posts/chatters 的 cover/images) ====================
# 1. 处理 moments 目录
moments_dir = Path("XHBlogs/moments")
public_moments_dir = Path("XHBlogs/public/moments")
if moments_dir.exists() and moments_dir.is_dir():
for md_file in moments_dir.glob("*.md"):
try:
match = re.match(r'^(\d{4})-(\d{2})-(\d{2})-(.+)\.md$', md_file.name)
if not match:
continue
year, month, day, title = match.groups()
img_folder = public_moments_dir / title / year / month / day
if not img_folder.exists() or not img_folder.is_dir():
continue
images = []
for f in sorted(img_folder.iterdir(), key=lambda x: x.name):
if f.suffix.lower() == '.webp':
rel_path = f"/moments/{title}/{year}/{month}/{day}/{f.name}"
images.append(rel_path)
if not images:
continue
content = md_file.read_text(encoding='utf-8')
images_yaml = "images:\n" + "\n".join(f"- {img}" for img in images)
if re.search(r'^images:\s*', content, re.MULTILINE):
new_content = re.sub(
r'^images:.*?(?=\n\w|\n---|\Z)',
images_yaml,
content,
flags=re.MULTILINE | re.DOTALL
)
else:
new_content = re.sub(
r'(date:.*\n)',
r'\1' + images_yaml + '\n',
content,
count=1
)
if new_content != content:
md_file.write_text(new_content, encoding='utf-8')
print(f"✅ Filled WebP images into moments: {md_file.name}")
except Exception as e:
print(f"⚠️ Error filling images for {md_file}: {e}")
# 2. 自动修正所有 markdown 文件里的图片后缀为 .webp(包括 cover、images 等)
all_md_files = glob.glob('XHBlogs/**/*.md', recursive=True)
for md_path in all_md_files:
try:
with open(md_path, 'r', encoding='utf-8') as f:
md_text = f.read()
# 将路径中的 .jpg / .jpeg / .png 统一改成 .webp
updated_text = re.sub(r'(\.(?:jpg|jpeg|png))', '.webp', md_text, flags=re.IGNORECASE)
if updated_text != md_text:
with open(md_path, 'w', encoding='utf-8') as f:
f.write(updated_text)
print(f"🔗 Updated image extension to .webp in: {md_path}")
except Exception as e:
print(f"⚠️ Error updating image extension in {md_path}: {e}")
# ==================== 第二部分:修复格式、标签、日期与空行 ====================
patterns = [
'XHBlogs/moments/**/*.md',
'XHBlogs/posts/**/*.md',
'XHBlogs/chatters/**/*.md',
]
files = []
for p in patterns:
files.extend(glob.glob(p, recursive=True))
changed = False
beijing_tz = timezone(timedelta(hours=8))
now = datetime.now(beijing_tz).strftime("%Y-%m-%d %H:%M:%S")
correct_line = f"date: '{now}'"
valid_re = re.compile(
r"^date:\s*'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})'\s*$",
re.MULTILINE
)
for path in files:
if not os.path.isfile(path):
continue
try:
with open(path, 'r', encoding='utf-8') as f:
content = f.read()
original = content
file_changed = False
# 1. 修复 images 格式
content = re.sub(
r'^images:\s*(?!$)(?!-\s)(.+)$',
r'images:\n- \1',
content,
flags=re.MULTILINE
)
if content != original:
file_changed = True
# 1.3 修复 tags 格式
def fix_tags(match):
tag_val = match.group(1).strip()
if not tag_val or tag_val.startswith('-') or tag_val.startswith('\n'):
return match.group(0)
tags = [t.strip() for t in re.split(r'[,,]+', tag_val) if t.strip() and t.strip() != '-']
if not tags:
return match.group(0)
formatted_tags = "tags:\n" + "\n".join(f"- {t}" for t in tags)
return formatted_tags
content = re.sub(
r'^tags:\s*([^\r\n\-].*?)$',
fix_tags,
content,
flags=re.MULTILINE
)
if content != original:
file_changed = True
# 1.5 删除图片路径中的 /XHBlogs/public
new_content = re.sub(
r'(/XHBlogs/public)(/[^\s]*)',
r'\2',
content
)
if new_content != content:
content = new_content
file_changed = True
# 2. 修复 date
if not valid_re.search(content):
new_content = re.sub(
r'^date:\s*.*$',
correct_line,
content,
flags=re.MULTILINE
)
if new_content != content:
content = new_content
file_changed = True
else:
content = re.sub(
r'^(---\s*\n)',
f"\\1{correct_line}\n",
content,
count=1,
flags=re.MULTILINE
)
file_changed = True
# 3. 处理结尾的 --- 空行
if content.count('---') >= 2:
parts = content.split('---', 2)
front = parts[0] + '---' + parts[1] + '---'
body = parts[2]
if body.startswith('\n\n'):
pass
elif body.startswith('\n'):
content = front + '\n' + body
file_changed = True
else:
content = front + '\n\n' + body
file_changed = True
if file_changed:
with open(path, 'w', encoding='utf-8') as f:
f.write(content)
changed = True
except Exception as e:
print(f"⚠️ Skip {path}: {e}")
if not changed:
print("✅ No files need fixing.")
else:
print("✅ All fixes and image fills applied.")
EOF
- name: Commit changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "chore: auto convert webp, delete originals, update paths and fix frontmatter"
git push
fi