1
0
mirror of https://github.com/cotes2020/jekyll-theme-chirpy.git synced 2025-12-18 05:41:31 +00:00

Import the framework.

This commit is contained in:
Cotes Chung
2019-09-30 20:38:41 +08:00
parent 5d0e72d5da
commit b845c829f6
103 changed files with 4640 additions and 0 deletions

16
_scripts/py/init_all.py Executable file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Automatic invokes all initial scripts for project.
© 2018-2019 Cotes Chung
Licensed under MIT
"""
import update_posts_lastmod
import pages_generator
update_posts_lastmod
pages_generator

190
_scripts/py/pages_generator.py Executable file
View File

@@ -0,0 +1,190 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Generates HTML pages for Categories and Tags in posts.
Dependencies:
- git
- ruamel.yaml
© 2018-2019 Cotes Chung
MIT License
'''
import os
import glob
import shutil
import sys
import subprocess
from ruamel.yaml import YAML
from utils.common import get_yaml
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)
for file in glob.glob(os.path.join(path, '*.md')):
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()
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)
for file in glob.glob(os.path.join(path, '*.md')):
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()
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()

View File

@@ -0,0 +1,121 @@
#!/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 subprocess
import shutil
from ruamel.yaml import YAML
from utils.common import get_yaml
from utils.common import check_py_version
POSTS_PATH = "_posts"
def help():
print("Usage: "
" python update_posts_lastmod.py [option]\n"
"Options:\n"
" -v, --verbose Print verbose logs\n")
def update_lastmod(verbose):
count = 0
yaml = YAML()
for post in glob.glob(os.path.join(POSTS_PATH, "*.md")):
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
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'] == git_lastmod):
continue
else:
meta['seo']['date_modified'] = git_lastmod
else:
meta.insert(line_num, 'seo', dict(date_modified=git_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():
check_py_version()
verbose = False
if len(sys.argv) > 1:
for arg in sys.argv:
if arg == sys.argv[0]:
continue
else:
if arg == '-v' or arg == '--verbose':
verbose = True
else:
help()
return
update_lastmod(verbose)
main()

View File

@@ -0,0 +1,43 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Common functions to other scripts.
© 2018-2019 Cotes Chung
MIT License
'''
import sys
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 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)