web/_scripts/py/update_posts_lastmod.py

167 lines
4.1 KiB
Python
Raw Normal View History

2019-09-30 15:38:41 +03:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Update (or create if not existed) field 'seo.date_modified'
in posts' Front Matter by their latest git commit date.
Dependencies:
- git
- ruamel.yaml
© 2018-2019 Cotes Chung
Licensed under MIT
"""
import sys
import glob
import os
import getopt
2019-09-30 15:38:41 +03:00
import subprocess
import shutil
import datetime
import time
2019-09-30 15:38:41 +03:00
from enum import Enum
2019-09-30 15:38:41 +03:00
from ruamel.yaml import YAML
2019-09-30 15:38:41 +03:00
from utils.common import get_yaml
from utils.common import check_py_version
Date = Enum('Date', ('GIT', 'FS'))
POSTS_PATH = '_posts'
2019-09-30 15:38:41 +03:00
def help():
print("Usage: "
" python update_posts_lastmod.py [options]\n"
2019-09-30 15:38:41 +03:00
"Options:\n"
" -f, --file <file path> Read a file.\n"
" -d, --dir <directory path> Read from a directory.\n"
" -h, --help Print help information\n"
" -v, --verbose Print verbose logs\n"
" -t, --datetime < git | fs > Chose post's datetime source, "
"'git' for git-log, 'fs' for filesystem, default to 'git'.\n")
2019-09-30 15:38:41 +03:00
def update_lastmod(path, verbose, date):
2019-09-30 15:38:41 +03:00
count = 0
yaml = YAML()
for post in glob.glob(path):
lastmod = ''
if date == Date.GIT:
git_log_count = subprocess.getoutput(
"git log --pretty=%ad \"{}\" | wc -l".format(post))
if git_log_count == "1":
continue
git_lastmod = subprocess.getoutput(
"git log -1 --pretty=%ad --date=iso \"{}\"".format(post))
2019-09-30 15:38:41 +03:00
if not git_lastmod:
continue
2019-09-30 15:38:41 +03:00
lates_commit = subprocess.check_output(
['git', 'log', '-1', '--pretty=%B', post]).decode('utf-8')
2019-09-30 15:38:41 +03:00
if "[Automation]" in lates_commit and "Lastmod" in lates_commit:
continue
2019-09-30 15:38:41 +03:00
lastmod = git_lastmod
2019-09-30 15:38:41 +03:00
elif date == Date.FS:
t = os.path.getmtime(post)
dt = datetime.datetime.fromtimestamp(t)
lastmod = dt.strftime('%F %T') + time.strftime(' %z')
2019-09-30 15:38:41 +03:00
frontmatter, line_num = get_yaml(post)
meta = yaml.load(frontmatter)
if 'seo' in meta:
if ('date_modified' in meta['seo'] and
meta['seo']['date_modified'] == lastmod):
2019-09-30 15:38:41 +03:00
continue
else:
meta['seo']['date_modified'] = lastmod
2019-09-30 15:38:41 +03:00
else:
meta.insert(line_num, 'seo', dict(date_modified=lastmod))
2019-09-30 15:38:41 +03:00
output = 'new.md'
if os.path.isfile(output):
os.remove(output)
with open(output, 'w', encoding='utf-8') as new, \
open(post, 'r', encoding='utf-8') as old:
new.write("---\n")
yaml.dump(meta, new)
new.write("---\n")
line_num += 2
lines = old.readlines()
for line in lines:
if line_num > 0:
line_num -= 1
continue
else:
new.write(line)
shutil.move(output, post)
count += 1
if verbose:
print("[INFO] update 'lastmod' for:" + post)
if count > 0:
print("[INFO] Success to update lastmod for {} post(s).".format(count))
def main(argv):
2019-09-30 15:38:41 +03:00
check_py_version()
path = os.path.join(POSTS_PATH, "*.md")
2019-09-30 15:38:41 +03:00
verbose = False
date = Date.GIT
try:
opts, args = getopt.getopt(
argv, "hf:d:vt:",
["file=", "dir=", "help", "verbose", "datetime="])
except getopt.GetoptError:
help()
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
help()
sys.exit()
elif opt == '-f' or opt == '--file':
path = arg
elif opt == '-d' or opt == '--dir':
path = os.path.join(arg, "*.md")
elif opt == '-v' or opt == '--verbose':
verbose = True
elif opt == '-t' or opt == '--datetime':
if arg == 'git':
date = Date.GIT
elif arg == 'fs':
date = Date.FS
2019-09-30 15:38:41 +03:00
else:
help()
sys.exit(2)
2019-09-30 15:38:41 +03:00
update_lastmod(path, verbose, date)
2019-09-30 15:38:41 +03:00
main(sys.argv[1:])