Created
October 12, 2022 09:42
-
-
Save Lightblues/c80533ffc29f901eecfd859eeb72abde to your computer and use it in GitHub Desktop.
Markdow文件增量同步. 用于笔记文件同步到个人博客.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python3 | |
""" @220325 | |
增量同步. 根据 filename_map 所定义的文件映射, 增量同步md文件和图片文件夹. | |
需求: 在个人笔记中书写, 部分同步到个人博客. (前者实时更新, 后者仅作同步) | |
同步规则: | |
从下面定义 document_dir 同步到 technote_dir. | |
同步文件列表根据 filename_map.py 所定义 | |
filename_map 格式例子 | |
```python | |
filemap = { | |
"Python-note": ["420-Python", "Python"], | |
} | |
``` | |
以下代码思路: | |
1. 构建 {文件夹: 路径} 的字典. 约束所有子文件夹不重名 | |
2. 增量同步 | |
3. 对应同步图片文件下, 对于没有的文件夹, 创建文件夹 | |
""" | |
import os | |
import glob | |
import filecmp # 比较文件是否相同 | |
import subprocess | |
# 定义了文件名映射, 例如 "Python-note": ["510-Python", "Python"], | |
from filename_map import filemap | |
# 定义同步文件夹 source, target | |
document_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
technote_dir = os.path.join(os.environ['HOME'], "Projects/z-blogs/techNotes/docs") | |
# basedir = "../../.." | |
# document_dir = f"{basedir}/PersonalNotes" | |
# technote_dir = f"{basedir}/techNotes/docs" | |
def get_dir2path(path, dir2path={}): | |
""" 构建 {文件夹名: 文件夹路径} 的map """ | |
# for root, dirs, files in os.walk(path): | |
# for dir in dirs: | |
# if dir.startswith(".") or dir in ["meida"]: | |
# continue | |
# dir2path[dir] = os.path.join(root, dir) | |
for name in os.listdir(path): | |
# 遍历所有的目录 1. 非隐藏; 2. 非 media文件夹; | |
p = f"{path}/{name}" | |
if os.path.isfile(p): | |
continue | |
if name.startswith(".") or name in ["media"]: | |
continue | |
# md文件夹的条件: 其中有 md文件 | |
items = os.listdir(p) | |
if len(items)==0 or any(i.endswith(".md") for i in items): | |
# 要求文件夹不同名! | |
assert name not in dir2path | |
dir2path[name] = p | |
# 递归 | |
dir2path = get_dir2path(p, dir2path) | |
return dir2path | |
def incr_sync(name, src_dir, dest_dir): | |
# 增量同步 | |
# 1. 文件 | |
src = f"{doc_dir2path[src_dir]}/{name}.md" | |
dest = f"{tech_dir2path[dest_dir]}/{name}.md" | |
# 若目标 md 文件已存在, 检查是否完全相同 | |
if os.path.exists(dest): | |
if filecmp.cmp(src, dest): return | |
# 比较 most recent content modification 时间 | |
tsrc, tdest = os.stat(src).st_mtime, os.stat(dest).st_mtime | |
assert tdest<tsrc, f"{dest} is newer than {src}" | |
print(f"[sync] {name}") | |
subprocess.run(["rsync", "-av", src, dest]) | |
# 2. 图片文件夹 | |
src, dest = f"{doc_dir2path[src_dir]}/media/{name}", f"{tech_dir2path[dest_dir]}/media/" | |
if not os.path.exists(src): return | |
os.makedirs(dest, exist_ok=True) | |
subprocess.run(["rsync", "-av", src, dest]) | |
if __name__=="__main__": | |
doc_dir2path = get_dir2path(document_dir, {}) | |
tech_dir2path = get_dir2path(technote_dir, {}) | |
for name, (src_dir, dest_dir) in filemap.items(): | |
# 同步文件 | |
incr_sync(name, src_dir, dest_dir) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment