目录

笔记自动发布

# 笔记自动发布

开始使用 note 做笔记后,大事小事都记录在笔记里,已经不怎么屁大点事都会发博客了。

痛点在于,需要手动同步文章和关联的图片到博客项目,push 到 github 后,触发自动部署更新静态页面。

想做一个类似点击公开,自动分享到博客项目的持续继承功能。

设想如下:

  • 本身 markdown 有 attribute 数据。
  • 增加 article: true 表示是需要发表到博客的项目。
  • 每次提交的时候,通过 github 提供的免费的 CI 功能 actions,扫描带有 article: true 的 markdown 文件,发送到博客项目单独分支。
  • 博客项目生成一个 pr , 方便检查文章格式等,通过人工审核后,同意合并至 master 分支,更新静态页面。

下面讲讲各个步骤细节,方便大佬们抄作业。

# 博客项目 同步相关

# 博客相关 actions 配置

name: sync-note
on:
  push:
    branches:
      - develop # Change this to your default branch
    paths:
      - "note/docs/articles/*.md"
jobs:
  make-html-send-email:
    name: make-time-file
    runs-on: ubuntu-latest
    steps:
      - name: get blog repository
        uses: actions/checkout@master
      - run: |
          cd ..
          git config --global user.email "z740713651@outlook.com"
          git config --global user.name "AngusWG"
          git config --global credential.helper cache
          git clone https://${{secrets.blog_sync}}@github.com/AngusWG/AngusWG
          cd AngusWG
          git checkout dev_auto 2>/dev/null || git checkout -b dev_auto

      - name: cd into note repo
        run: cd ../WG & pwd

      - name: install python script requirement
        run: pip install .

      - name: run the script sync note to blog repo 
        run: python wg sync_note note /home/runner/work/WG/AngusWG/docs

      - name: commit note
        run: |
          cd /home/runner/work/WG/AngusWG
          git add .
          git commit -m "sync note $(date +"%Y-%m-%d %H:%M:%S")" || true
          git push origin dev_auto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 同步博客的 python 脚本

  • 直接用的话 需要做入参适当修改。
  • 设置 article: true 的文章会自动发表到博客。
  • 当 date 不一样时,会自动同步笔记的内容到博客。

需要笔记文件夹和博客有以下目录结构

  • sorce_note_dir: 笔记文件夹
    • articles: 可以发布的文章文件夹
      • a.md (article: true)
      • b.md (article: true)
      • c.md (article: false)
    • images: 笔记图片文件夹
      • a1.png
      • a2.png
      • c1.png
  • target_note_dir: 笔记文件夹
    • articles: 已经发布的博客文件夹
      • a.md (article: true)
      • b.md (article: true)
    • images: 博客图片文件夹
      • a1.png
      • a2.png
#!/usr/bin/env python
# encoding: utf-8
# @Time   : 2022/04/18 18:22:22
# @author : zza
# @Email  : z740713651@outlook.com
# @File   : sync_markdown_note.py
"""同步笔记用"""

import os
import frontmatter
import re
import shutil

default_dir = "articles"
article_attribute = "article"

def _need_sync(file_path: str, output_dir: str) -> bool:
    """
    判断是否要同步笔记

    1 笔记里存在 属性 publish:true
    2 笔记日期 > 已发布笔记日期
    """
    post = frontmatter.load(file_path)
    # publish
    if not post.get(article_attribute):
        return False
    # update date
    old_file = os.path.join(output_dir, default_dir, os.path.basename(file_path))
    if os.path.exists(old_file):
        current_date = post.get("date")
        old_date = frontmatter.load(old_file).get("date")
        if current_date == old_date:
            return False
    return True

def sync_pic(file_path: str, output_dir: str) -> None:
    """copy pic to output dir"""
    # find pic in markdown file
    with open(file_path, "r", encoding="utf-8") as f:
        markdown_body = f.read()
    pic_str_list = re.findall(r"\!\[.*\]\((.*)\)", markdown_body)
    for pic_str in pic_str_list:
        print(f"  find pic {pic_str}")
        pic_file = os.path.join(os.path.dirname(file_path), pic_str)
        if not os.path.exists(pic_file):
            continue
        # copy pic
        output_pic_file = os.path.join(output_dir, "images", os.path.basename(pic_file))
        print(f"  copy {os.path.abspath(pic_file)} to {output_pic_file}")
        shutil.copyfile(pic_file, output_pic_file)
    return

def handler_file(root: str, file: str, output_dir: str) -> None:
    """处理单个 markdown 文件"""
    file_path = os.path.join(root, file)
    if not _need_sync(file_path, output_dir):
        return
    # copy file
    output_file_path = os.path.join(output_dir, default_dir, file)
    print(f"copy {file_path} to {output_file_path}")
    shutil.copyfile(file_path, output_file_path)
    # copy pic
    sync_pic(file_path, output_dir)

def main(
    markdown_path: str = r"E:\PycharmProjects\WG\note",
    output_dir: str = r"E:\PycharmProjects\AngusWG\docs",
) -> None:
    """
    遍历 note 文件夹 articles 文件夹下所有的 md 文件

    并同步到另一边文件夹下的 articles 文件夹下
    - sorce_note_dir: 笔记文件夹
      - articles: 可以发布的文章文件夹
        - a.md (article: true)
        - b.md (article: true)
        - c.md (article: false)
      - images: 笔记图片文件夹
        - a1.png
        - a2.png
        - c1.png
    - target_note_dir: 笔记文件夹
      - articles: 已经发布的博客文件夹
        - a.md (article: true)
        - b.md (article: true)
      - images: 博客图片文件夹
        - a1.png
        - a2.png
    """
    # walk directory
    root = os.path.join(markdown_path, default_dir)
    for file  in os.listdir(root):
        if file.endswith(".md"):
            handler_file(root, file, output_dir)

if __name__ == "__main__":
    main()
    # handler_file(
    #     r"E:\PycharmProjects\WG\note\docs\创作",
    #     "笔记自动发布。md",
    #     r"E:\PycharmProjects\AngusWG\docs",
    # )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

# 博客项目生成 pr

name: SYNC NOTE
on:
  push:
    branches:
      - dev_auto
jobs:
  SYNC_NOTE:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          ref: master
      - run: ls
      - name: Reset main branch
        run: |
          git fetch origin dev_auto:dev_auto
          git reset --hard dev_auto
      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v4
        id: cpr
        with:
          commit-message: publish note to blog
          title: sync note pull request
          body: $(date +"%Y-%m-%dT%H:%M:%S%z")
          branch: dev_auto
          base: master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

小坑:

报错 Branch 'X' no longer differs from base branch 'Y'

actions 好像将本地的分支提交一次,最开始的时候写错了, 导致反向 master 覆盖了 dev_auto 分支, 然后因为没有 git fetch ,认为无修改不生成 pr。 看 action 日志+看 issus (opens new window) 解决的。 action 的运行方式有点想当然了。

# 总结

最开始想用 tag: publish 去识别是否要发布,但是刷 attribute 的脚本不支持增加,支持覆盖, 想了想还是新弄个属性,反正人也看不到。

目前还有一个问题是,这个 action 是每次提交就会检测一遍,然后装 python 依赖的时候,其实挺慢的, 找了一下,并没有限制最小部署间隔的参数(有知道的小伙伴请告诉我)想想机器又不累,不要在乎这么多。

上次更新: 2024-01-10 16:01:00
最近更新
01
自建 RSS 订阅
01-05
02
搭建私人 docker hub
01-02
03
关于 SSH 攻击
10-12
更多文章>