mirror of
https://github.com/cotes2020/jekyll-theme-chirpy.git
synced 2025-12-18 05:41:31 +00:00
Replace python with bash.
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Automatic invokes all initial scripts for project.
|
||||
v2.0
|
||||
https://github.com/cotes2020/jekyll-theme-chirpy
|
||||
© 2018-2019 Cotes Chung
|
||||
Licensed under MIT
|
||||
"""
|
||||
|
||||
import update_posts_lastmod
|
||||
import pages_generator
|
||||
|
||||
|
||||
update_posts_lastmod
|
||||
|
||||
pages_generator
|
||||
@@ -1,205 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
Generates HTML pages for Categories and Tags in posts.
|
||||
|
||||
Dependencies:
|
||||
- git
|
||||
- ruamel.yaml
|
||||
|
||||
v2.0
|
||||
https://github.com/cotes2020/jekyll-theme-chirpy
|
||||
© 2018-2019 Cotes Chung
|
||||
MIT License
|
||||
'''
|
||||
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
from ruamel.yaml import YAML
|
||||
from utils.common import get_yaml
|
||||
from utils.common import get_makrdown_files
|
||||
from utils.common import check_py_version
|
||||
|
||||
|
||||
DRAFTS_DIR = '_drafts'
|
||||
POSTS_DIR = ['_posts']
|
||||
|
||||
CATEGORIES_DIR = 'categories'
|
||||
CATEGORY_LAYOUT = 'category'
|
||||
|
||||
TAG_DIR = 'tags'
|
||||
TAG_LAYOUT = 'tag'
|
||||
|
||||
LEVEL = 3 # Tree level for current script file.
|
||||
|
||||
|
||||
def help():
|
||||
print("Usage: "
|
||||
" python pages_generator.py [Option]\n\n"
|
||||
"Options:\n"
|
||||
" -d, --drafts Enable drafts\n"
|
||||
" -v, --verbose Print verbose logs\n")
|
||||
|
||||
|
||||
def get_path(dir):
|
||||
path = os.path.abspath(__file__)
|
||||
count = LEVEL
|
||||
r_index = len(path)
|
||||
while r_index > 0:
|
||||
r_index -= 1
|
||||
if (path[r_index] == '/' or path[r_index] == '\\'):
|
||||
count -= 1
|
||||
if count == 0:
|
||||
return path[:r_index + 1] + dir
|
||||
|
||||
|
||||
def get_categories():
|
||||
all_categories = []
|
||||
yaml = YAML()
|
||||
|
||||
for dir in POSTS_DIR:
|
||||
path = get_path(dir)
|
||||
posts = get_makrdown_files(path)
|
||||
|
||||
for file in posts:
|
||||
|
||||
meta = yaml.load(get_yaml(file)[0])
|
||||
|
||||
if 'category' in meta:
|
||||
if type(meta['category']) == list:
|
||||
err_msg = (
|
||||
"[Error] File {} 'category' type"
|
||||
" can not be LIST!").format(file)
|
||||
raise Exception(err_msg)
|
||||
else:
|
||||
if meta['category'] not in all_categories:
|
||||
all_categories.append(meta['category'])
|
||||
else:
|
||||
if 'categories' in meta:
|
||||
if type(meta['categories']) == str:
|
||||
error_msg = (
|
||||
"[Error] File {} 'categories' type"
|
||||
" can not be STR!").format(file)
|
||||
raise Exception(error_msg)
|
||||
|
||||
for ctg in meta['categories']:
|
||||
if ctg not in all_categories:
|
||||
all_categories.append(ctg)
|
||||
else:
|
||||
err_msg = (
|
||||
"[Error] File:{} at least "
|
||||
"have one category.").format(file)
|
||||
print(err_msg)
|
||||
|
||||
return all_categories
|
||||
|
||||
|
||||
def generate_category_pages(is_verbose):
|
||||
categories = get_categories()
|
||||
|
||||
if len(categories) <= 0:
|
||||
return
|
||||
|
||||
path = get_path(CATEGORIES_DIR)
|
||||
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
os.makedirs(path)
|
||||
|
||||
for category in categories:
|
||||
new_page = path + '/' + category.replace(' ', '-').lower() + '.html'
|
||||
with open(new_page, 'w+', encoding='utf-8') as html:
|
||||
html.write("---\n")
|
||||
html.write("layout: {}\n".format(CATEGORY_LAYOUT))
|
||||
html.write("title: {}\n".format(category))
|
||||
html.write("category: {}\n".format(category))
|
||||
html.write("---")
|
||||
|
||||
if is_verbose:
|
||||
print("[INFO] Created page: " + new_page)
|
||||
|
||||
change = subprocess.getoutput("git status categories -s")
|
||||
if change:
|
||||
print("[INFO] Succeed! {} category-pages created."
|
||||
.format(len(categories)))
|
||||
|
||||
|
||||
def get_all_tags():
|
||||
all_tags = []
|
||||
yaml = YAML()
|
||||
|
||||
for dir in POSTS_DIR:
|
||||
path = get_path(dir)
|
||||
posts = get_makrdown_files(path)
|
||||
|
||||
for file in posts:
|
||||
meta = yaml.load(get_yaml(file)[0])
|
||||
|
||||
if 'tags' in meta:
|
||||
for tag in meta['tags']:
|
||||
if tag not in all_tags:
|
||||
all_tags.append(tag)
|
||||
else:
|
||||
raise Exception("Didn't find 'tags' in post '{}' !"
|
||||
.format(file))
|
||||
|
||||
return all_tags
|
||||
|
||||
|
||||
def generate_tag_pages(is_verbose):
|
||||
all_tags = get_all_tags()
|
||||
|
||||
if len(all_tags) <= 0:
|
||||
return
|
||||
|
||||
tag_path = get_path(TAG_DIR)
|
||||
|
||||
if os.path.exists(tag_path):
|
||||
shutil.rmtree(tag_path)
|
||||
|
||||
os.makedirs(tag_path)
|
||||
|
||||
for tag in all_tags:
|
||||
tag_page = tag_path + '/' + tag.replace(' ', '-').lower() + '.html'
|
||||
with open(tag_page, 'w+', encoding='utf-8') as html:
|
||||
html.write("---\n")
|
||||
html.write("layout: {}\n".format(TAG_LAYOUT))
|
||||
html.write("title: {}\n".format(tag))
|
||||
html.write("tag: {}\n".format(tag))
|
||||
html.write("---")
|
||||
|
||||
if is_verbose:
|
||||
print("[INFO] Created page: " + tag_page)
|
||||
|
||||
change = subprocess.getoutput("git status tags -s")
|
||||
if change:
|
||||
print("[INFO] Succeed! {} tag-pages created.".format(len(all_tags)))
|
||||
|
||||
|
||||
def main():
|
||||
check_py_version()
|
||||
|
||||
is_verbose = False
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
for arg in sys.argv:
|
||||
if arg != sys.argv[0]:
|
||||
if arg == '-d' or arg == '--drafts':
|
||||
POSTS_DIR.insert(0, DRAFTS_DIR)
|
||||
elif arg == '-v' or arg == '--verbose':
|
||||
is_verbose = True
|
||||
else:
|
||||
help()
|
||||
return
|
||||
|
||||
generate_category_pages(is_verbose)
|
||||
generate_tag_pages(is_verbose)
|
||||
|
||||
|
||||
main()
|
||||
@@ -1,2 +0,0 @@
|
||||
ruamel.yaml==0.16.5
|
||||
ruamel.yaml.clib==0.1.2
|
||||
@@ -1,174 +0,0 @@
|
||||
#!/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
|
||||
|
||||
v2.0
|
||||
https://github.com/cotes2020/jekyll-theme-chirpy
|
||||
© 2018-2019 Cotes Chung
|
||||
Licensed under MIT
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import getopt
|
||||
import subprocess
|
||||
import shutil
|
||||
import datetime
|
||||
import time
|
||||
|
||||
from enum import Enum
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
from utils.common import get_yaml
|
||||
from utils.common import get_makrdown_files
|
||||
from utils.common import check_py_version
|
||||
|
||||
|
||||
Date = Enum('Date', ('GIT', 'FS'))
|
||||
|
||||
POSTS_PATH = '_posts'
|
||||
|
||||
|
||||
def help():
|
||||
print("Usage: "
|
||||
" python update_posts_lastmod.py [options]\n"
|
||||
"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")
|
||||
|
||||
|
||||
def update_lastmod(posts, verbose, date):
|
||||
count = 0
|
||||
yaml = YAML()
|
||||
|
||||
for post in posts:
|
||||
|
||||
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))
|
||||
|
||||
if not git_lastmod:
|
||||
continue
|
||||
|
||||
lates_commit = subprocess.check_output(
|
||||
['git', 'log', '-1', '--pretty=%B', post]).decode('utf-8')
|
||||
|
||||
if "[Automation]" in lates_commit and "Lastmod" in lates_commit:
|
||||
continue
|
||||
|
||||
lastmod = git_lastmod
|
||||
|
||||
elif date == Date.FS:
|
||||
t = os.path.getmtime(post)
|
||||
dt = datetime.datetime.fromtimestamp(t)
|
||||
lastmod = dt.strftime('%F %T') + time.strftime(' %z')
|
||||
|
||||
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):
|
||||
continue
|
||||
else:
|
||||
meta['seo']['date_modified'] = lastmod
|
||||
else:
|
||||
meta.insert(line_num, 'seo', dict(date_modified=lastmod))
|
||||
|
||||
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):
|
||||
check_py_version()
|
||||
|
||||
specific = False
|
||||
posts = []
|
||||
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':
|
||||
posts.append(arg)
|
||||
specific = True
|
||||
|
||||
elif opt == '-d' or opt == '--dir':
|
||||
posts = get_makrdown_files(arg)
|
||||
specific = True
|
||||
|
||||
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
|
||||
else:
|
||||
help()
|
||||
sys.exit(2)
|
||||
|
||||
if not specific:
|
||||
posts = get_makrdown_files(POSTS_PATH)
|
||||
|
||||
update_lastmod(posts, verbose, date)
|
||||
|
||||
|
||||
main(sys.argv[1:])
|
||||
@@ -1,57 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
Common functions to other scripts.
|
||||
|
||||
v2.0
|
||||
https://github.com/cotes2020/jekyll-theme-chirpy
|
||||
© 2018-2019 Cotes Chung
|
||||
MIT License
|
||||
'''
|
||||
|
||||
import sys
|
||||
import os
|
||||
import glob
|
||||
|
||||
|
||||
def get_yaml(path):
|
||||
"""
|
||||
Return the Yaml block of a post and the linenumbers of it.
|
||||
"""
|
||||
end = False
|
||||
yaml = ""
|
||||
num = 0
|
||||
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
for line in f.readlines():
|
||||
if line.strip() == '---':
|
||||
if end:
|
||||
break
|
||||
else:
|
||||
end = True
|
||||
continue
|
||||
else:
|
||||
num += 1
|
||||
|
||||
yaml += line
|
||||
|
||||
return yaml, num
|
||||
|
||||
|
||||
def get_makrdown_files(path):
|
||||
MD_EXTENSIONS = ["md", "markdown", "markdn", "mdown"]
|
||||
ret_files = []
|
||||
|
||||
for extension in MD_EXTENSIONS:
|
||||
ret_files.extend(glob.glob(os.path.join(path, "*." + extension)))
|
||||
|
||||
return ret_files
|
||||
|
||||
|
||||
def check_py_version():
|
||||
if not sys.version_info.major == 3 and sys.version_info.minor >= 5:
|
||||
print("WARNING: This script requires Python 3.5 or higher, "
|
||||
"however you are using Python {}.{}."
|
||||
.format(sys.version_info.major, sys.version_info.minor))
|
||||
sys.exit(1)
|
||||
142
_scripts/sh/create_pages.sh
Executable file
142
_scripts/sh/create_pages.sh
Executable file
@@ -0,0 +1,142 @@
|
||||
#!/usr/local/bin/bash
|
||||
#
|
||||
# Create HTML pages for Categories and Tags in posts.
|
||||
#
|
||||
# Usage:
|
||||
# Call from the '_posts' sibling directory.
|
||||
#
|
||||
# v2.2
|
||||
# https://github.com/cotes2020/jekyll-theme-chirpy
|
||||
# © 2020 Cotes Chung
|
||||
# Published under MIT License
|
||||
|
||||
set -eu
|
||||
|
||||
TYPE_CATEGORY=0
|
||||
TYPE_TAG=1
|
||||
|
||||
category_count=0
|
||||
tag_count=0
|
||||
|
||||
read_categories() {
|
||||
if [[ $(grep "categories:" $1) ]]; then
|
||||
grep "categories:" $1 | head -1 | sed 's/categories: *//;s/\[//;s/\]//;s/, */,/g;s/"//g'
|
||||
elif [[ $(grep "category:" $1) ]]; then
|
||||
grep "category:" $1 | head -1 | sed 's/category: *//;s/\[//;s/\]//;s/, */,/g;s/"//g'
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
read_tags() {
|
||||
grep "tags:" $1 | head -1 | sed 's/tags: *//;s/\[//;s/\]//;s/, */,/g;s/"//g'
|
||||
}
|
||||
|
||||
|
||||
init() {
|
||||
if [[ -d categories ]]; then
|
||||
rm -rf categories
|
||||
fi
|
||||
|
||||
if [[ -d tags ]]; then
|
||||
rm -rf tags
|
||||
fi
|
||||
|
||||
mkdir categories tags
|
||||
}
|
||||
|
||||
|
||||
create_category() {
|
||||
local _name=$1
|
||||
local _filepath="categories/$(echo $_name | sed 's/ /-/g' | awk '{print tolower($0)}').html"
|
||||
|
||||
if [[ ! -f $_filepath ]]; then
|
||||
echo "---" > $_filepath
|
||||
echo "layout: category" >> $_filepath
|
||||
echo "title: $_name" >> $_filepath
|
||||
echo "category: $_name" >> $_filepath
|
||||
echo "---" >> $_filepath
|
||||
|
||||
((category_count=category_count+1))
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
create_tag() {
|
||||
local _name=$1
|
||||
local _filepath="tags/$( echo $_name | sed "s/ /-/g;s/'//g" | awk '{print tolower($0)}' ).html"
|
||||
|
||||
if [[ ! -f $_filepath ]]; then
|
||||
|
||||
echo "---" > $_filepath
|
||||
echo "layout: tag" >> $_filepath
|
||||
echo "title: $_name" >> $_filepath
|
||||
echo "tag: $_name" >> $_filepath
|
||||
echo "---" >> $_filepath
|
||||
|
||||
((tag_count=tag_count+1))
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#########################################
|
||||
# Create HTML pages for Categories/Tags.
|
||||
# Arguments:
|
||||
# $1 - an array string
|
||||
# $2 - type specified option
|
||||
#########################################
|
||||
create_pages() {
|
||||
if [[ $1 == '' ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# split string to array
|
||||
IFS_BAK=$IFS
|
||||
IFS=','
|
||||
local _string=$1
|
||||
|
||||
case $2 in
|
||||
|
||||
$TYPE_CATEGORY)
|
||||
for i in ${_string#,}; do
|
||||
create_category $i
|
||||
done
|
||||
;;
|
||||
|
||||
$TYPE_TAG)
|
||||
for i in ${_string#,}; do
|
||||
create_tag $i
|
||||
done
|
||||
;;
|
||||
|
||||
*)
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
IFS=$IFS_BAK
|
||||
}
|
||||
|
||||
|
||||
main() {
|
||||
init
|
||||
|
||||
for _file in $(ls "_posts")
|
||||
do
|
||||
local _path="_posts/$_file"
|
||||
local _categories=$(read_categories "$_path")
|
||||
local _tags=$(read_tags "$_path")
|
||||
|
||||
create_pages "$_categories" $TYPE_CATEGORY
|
||||
create_pages "$_tags" $TYPE_TAG
|
||||
done
|
||||
|
||||
if [[ $category_count -gt 0 ]]; then
|
||||
echo "[INFO] Succeed! $category_count category-pages created."
|
||||
fi
|
||||
|
||||
if [[ $tag_count -gt 0 ]]; then
|
||||
echo "[INFO] Succeed! $tag_count tag-pages created."
|
||||
fi
|
||||
}
|
||||
|
||||
main
|
||||
89
_scripts/sh/dump_lastmod.sh
Executable file
89
_scripts/sh/dump_lastmod.sh
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Find out the posts that have been modified and record
|
||||
# its lastmod information to file '_data/updates.yml'
|
||||
#
|
||||
# Usage:
|
||||
# Call from the '_posts' sibling directory.
|
||||
#
|
||||
# v2.2
|
||||
# https://github.com/cotes2020/jekyll-theme-chirpy
|
||||
# © 2020 Cotes Chung
|
||||
# Published under MIT License
|
||||
|
||||
set -eu
|
||||
|
||||
POST_DIR=_posts
|
||||
OUTPUT_DIR=_data
|
||||
OUTPUT_FILE=updates.yml
|
||||
|
||||
|
||||
_init() {
|
||||
if [[ ! -d "$OUTPUT_DIR" ]]; then
|
||||
mkdir "$OUTPUT_DIR"
|
||||
fi
|
||||
|
||||
if [[ -f "$OUTPUT_DIR/$OUTPUT_FILE" ]]; then
|
||||
rm -f "$OUTPUT_DIR/$OUTPUT_FILE"
|
||||
fi
|
||||
|
||||
touch "$OUTPUT_DIR/$OUTPUT_FILE"
|
||||
}
|
||||
|
||||
|
||||
_has_changed() {
|
||||
local _log_count=`git log --pretty=%ad $1 | wc -l | sed 's/ *//'`
|
||||
_log_count=$(($_log_count + 0))
|
||||
|
||||
if [[ $_log_count > 1 ]]; then
|
||||
return 0 # true
|
||||
fi
|
||||
|
||||
return 1 # false
|
||||
}
|
||||
|
||||
|
||||
###################################
|
||||
# Storage the posts' lastmod.
|
||||
#
|
||||
# Args:
|
||||
# - $1 the post's filename
|
||||
# - $2 the post's filepath
|
||||
# Output:
|
||||
# the file '_data/updates.yml'
|
||||
###################################
|
||||
_dump() {
|
||||
local _lasmod="`git log -1 --pretty=%ad --date=iso $2`"
|
||||
|
||||
echo "-" >> "$OUTPUT_DIR/$OUTPUT_FILE"
|
||||
echo " filename: '$1'" >> "$OUTPUT_DIR/$OUTPUT_FILE"
|
||||
echo " lastmod: '$_lasmod'" >> "$OUTPUT_DIR/$OUTPUT_FILE"
|
||||
}
|
||||
|
||||
|
||||
main() {
|
||||
|
||||
_init
|
||||
|
||||
local _count=0
|
||||
|
||||
for _file in $(ls -r "$POST_DIR")
|
||||
do
|
||||
_filepath="$POST_DIR/$_file"
|
||||
_filename="${_file%.*}" # jekyll cannot read the extension of a file, so omit it.
|
||||
_filename=${_filename:11} # remove the date
|
||||
|
||||
if _has_changed "$_filepath"; then
|
||||
_dump "$_filename" "$_filepath"
|
||||
((_count=_count+1))
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
if [[ $_count > 0 ]]; then
|
||||
echo "[INFO] Success to update lastmod for $_count post(s)."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
main
|
||||
@@ -33,6 +33,6 @@ if [[ -f "$1" ]]; then
|
||||
fi
|
||||
|
||||
if [[ $related_dir == "_posts" ]]; then
|
||||
python $3/_scripts/py/init_all.py
|
||||
python $3/_scripts/py/update_posts_lastmod.py -f "$dest/$(basename $1)" -t fs
|
||||
bash $3/_scripts/sh/create_pages.sh
|
||||
bash $3/_scripts/sh/dump_lastmod.sh
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user