diff options
-rw-r--r-- | generators/generators.py | 140 | ||||
-rwxr-xr-x | pyblog | 146 |
2 files changed, 144 insertions, 142 deletions
diff --git a/generators/generators.py b/generators/generators.py index adfe819a..3122f9c8 100644 --- a/generators/generators.py +++ b/generators/generators.py @@ -18,6 +18,8 @@ import copy import email.utils import time +import shutil + from rss import * from config.config import * @@ -689,3 +691,141 @@ def generate_index_and_feed(): sys.stderr.write("wrote rss.xml\n") generate_sitemap(feed) + + +# exclude_list is only inialized once to avoid constant disk IO +@utils.static_vars(exclude_list=None) +def generate_blog(fresh=False, report_total_errors=True): + """Generate the blog in BUILDDIR. + + Parameters + ---------- + fresh : bool + If True, remove all existing build artifects and start afresh; + otherwise, only copy or build new or modified files. Default is + False. + report_total_errors : bool + If True, a line will be printed to stderr at the end of build + (assuming the function doesn't raise early) reporting the total + number of errors, e.g., "build finished with 0 errors". This is + turned on by default, but pass False to turn it off, which will + result in a completely silent session if nothing changed. This + is useful for auto-regen, for instance. + + Returns + ------- + failed_builds : int + Number of build failures. + + """ + + # pylint: disable=too-many-branches,too-many-locals,too-many-statements + + if not os.path.isdir(SOURCEDIR): + raise OSError("source directory %s does not exist" % SOURCEDIR) + if not os.path.exists(HTMLTEMPLATE): + raise OSError("HTML template %s not found" % HTMLTEMPLATE) + + if not os.path.isdir(BUILDDIR): + if os.path.exists(BUILDDIR): + os.remove(BUILDDIR) + os.mkdir(BUILDDIR, mode=0o755) + if fresh: + for name in os.listdir(BUILDDIR): + if name == ".git": + continue + obj = os.path.join(BUILDDIR, name) + if os.path.isdir(obj): + shutil.rmtree(obj) + else: + os.remove(obj) + + # nojekyll: https://help.github.com/articles/files-that-start-with-an-underscore-are-missing/ + if not os.path.exists(os.path.join(BUILDDIR, ".nojekyll")): + with open(os.path.join(BUILDDIR, ".nojekyll"), "w") as fileobj: + pass + + if CUSTOM_DOMAIN and not os.path.exists(os.path.join(BUILDDIR, "CNAME")): + with open(os.path.join(BUILDDIR, "CNAME"), "w") as fileobj: + fileobj.write(CUSTOM_DOMAIN) + + failed_builds = 0 + generator_mtime = os.path.getmtime(GENERATORSOURCE) + template_mtime = os.path.getmtime(HTMLTEMPLATE) + fundamental_mtime = max(generator_mtime, template_mtime) + anything_modified = False + + exclude_list = generate_blog.exclude_list # get value of static variable + if exclude_list is None: + try: + with open(EXCLUDELIST) as fp: + exclude_list = [os.path.abspath(os.path.join(SOURCEDIR, line.rstrip())) + for line in list(fp) + if line.strip() != "" and not line.startswith('#')] + except OSError: + exclude_list = [] + generate_blog.exclude_list = exclude_list # assign to static variable for the future + + for root, dirs, files in os.walk(SOURCEDIR): + # If root is in exclude list, skip all files and remove all subdirs from traversal list. + if root in exclude_list: + dirs[:] = [] + continue + + relroot = os.path.relpath(root, start=SOURCEDIR) + dstroot = os.path.join(BUILDDIR, relroot) + if not os.path.isdir(dstroot): + if os.path.exists(dstroot): + os.remove(dstroot) + os.mkdir(dstroot, mode=0o755) + + for name in files: + if name.startswith('.') or os.path.join(root, name) in exclude_list: + continue + + extension = name.split(".")[-1] + if extension not in ["css", "js", "asc", "html", "jpg", "md", "png", "svg", "ico", "txt", + "eot", "ttf", "woff", "woff2"]: + continue + + relpath = os.path.join(relroot, name) + srcpath = os.path.join(root, name) + if extension == "md": + dstpath = os.path.join(dstroot, re.sub(r'\.md$', '.html', name)) + else: + dstpath = os.path.join(dstroot, name) + if ((not os.path.exists(dstpath) or + os.path.getmtime(dstpath) <= + max(fundamental_mtime, os.path.getmtime(srcpath)))): + # new post or modified post + anything_modified = True + if srcpath == INDEXMD: + continue # index will be processed separately + if extension in ["css", "js", "asc", "html", "jpg", "png", "svg", "ico", "txt", + "eot", "ttf", "woff", "woff2"]: + sys.stderr.write("copying %s\n" % relpath) + shutil.copy(srcpath, dstpath) + elif extension == "md": + sys.stderr.write("compiling %s\n" % relpath) + pandoc_args = [ + "pandoc", srcpath, + "--template", HTMLTEMPLATE, + "--highlight-style=pygments", + "-o", dstpath, + ] + try: + subprocess.check_call(pandoc_args) + except subprocess.CalledProcessError: + failed_builds += 1 + sys.stderr.write("error: failed to generate %s" % + relpath) + # postprocess generated HTML file + utils.postprocess_html_file(dstpath) + + if anything_modified: + generate_index_and_feed() + sys.stderr.write("done\n") + + if report_total_errors: + sys.stderr.write("build finished with %d errors\n" % failed_builds) + return failed_builds @@ -51,154 +51,16 @@ from config.config import * from generators import generators -# exclude_list is only inialized once to avoid constant disk IO -@utils.static_vars(exclude_list=None) -def generate_blog(fresh=False, report_total_errors=True): - """Generate the blog in BUILDDIR. - - Parameters - ---------- - fresh : bool - If True, remove all existing build artifects and start afresh; - otherwise, only copy or build new or modified files. Default is - False. - report_total_errors : bool - If True, a line will be printed to stderr at the end of build - (assuming the function doesn't raise early) reporting the total - number of errors, e.g., "build finished with 0 errors". This is - turned on by default, but pass False to turn it off, which will - result in a completely silent session if nothing changed. This - is useful for auto-regen, for instance. - - Returns - ------- - failed_builds : int - Number of build failures. - - """ - - # pylint: disable=too-many-branches,too-many-locals,too-many-statements - - if not os.path.isdir(SOURCEDIR): - raise OSError("source directory %s does not exist" % SOURCEDIR) - if not os.path.exists(HTMLTEMPLATE): - raise OSError("HTML template %s not found" % HTMLTEMPLATE) - - if not os.path.isdir(BUILDDIR): - if os.path.exists(BUILDDIR): - os.remove(BUILDDIR) - os.mkdir(BUILDDIR, mode=0o755) - if fresh: - for name in os.listdir(BUILDDIR): - if name == ".git": - continue - obj = os.path.join(BUILDDIR, name) - if os.path.isdir(obj): - shutil.rmtree(obj) - else: - os.remove(obj) - - # nojekyll: https://help.github.com/articles/files-that-start-with-an-underscore-are-missing/ - if not os.path.exists(os.path.join(BUILDDIR, ".nojekyll")): - with open(os.path.join(BUILDDIR, ".nojekyll"), "w") as fileobj: - pass - - if CUSTOM_DOMAIN and not os.path.exists(os.path.join(BUILDDIR, "CNAME")): - with open(os.path.join(BUILDDIR, "CNAME"), "w") as fileobj: - fileobj.write(CUSTOM_DOMAIN) - - failed_builds = 0 - generator_mtime = os.path.getmtime(GENERATORSOURCE) - template_mtime = os.path.getmtime(HTMLTEMPLATE) - fundamental_mtime = max(generator_mtime, template_mtime) - anything_modified = False - - exclude_list = generate_blog.exclude_list # get value of static variable - if exclude_list is None: - try: - with open(EXCLUDELIST) as fp: - exclude_list = [os.path.abspath(os.path.join(SOURCEDIR, line.rstrip())) - for line in list(fp) - if line.strip() != "" and not line.startswith('#')] - except OSError: - exclude_list = [] - generate_blog.exclude_list = exclude_list # assign to static variable for the future - - for root, dirs, files in os.walk(SOURCEDIR): - # If root is in exclude list, skip all files and remove all subdirs from traversal list. - if root in exclude_list: - dirs[:] = [] - continue - - relroot = os.path.relpath(root, start=SOURCEDIR) - dstroot = os.path.join(BUILDDIR, relroot) - if not os.path.isdir(dstroot): - if os.path.exists(dstroot): - os.remove(dstroot) - os.mkdir(dstroot, mode=0o755) - - for name in files: - if name.startswith('.') or os.path.join(root, name) in exclude_list: - continue - - extension = name.split(".")[-1] - if extension not in ["css", "js", "asc", "html", "jpg", "md", "png", "svg", "ico", "txt", - "eot", "ttf", "woff", "woff2"]: - continue - - relpath = os.path.join(relroot, name) - srcpath = os.path.join(root, name) - if extension == "md": - dstpath = os.path.join(dstroot, re.sub(r'\.md$', '.html', name)) - else: - dstpath = os.path.join(dstroot, name) - if ((not os.path.exists(dstpath) or - os.path.getmtime(dstpath) <= - max(fundamental_mtime, os.path.getmtime(srcpath)))): - # new post or modified post - anything_modified = True - if srcpath == INDEXMD: - continue # index will be processed separately - if extension in ["css", "js", "asc", "html", "jpg", "png", "svg", "ico", "txt", - "eot", "ttf", "woff", "woff2"]: - sys.stderr.write("copying %s\n" % relpath) - shutil.copy(srcpath, dstpath) - elif extension == "md": - sys.stderr.write("compiling %s\n" % relpath) - pandoc_args = [ - "pandoc", srcpath, - "--template", HTMLTEMPLATE, - "--highlight-style=pygments", - "-o", dstpath, - ] - try: - subprocess.check_call(pandoc_args) - except subprocess.CalledProcessError: - failed_builds += 1 - sys.stderr.write("error: failed to generate %s" % - relpath) - # postprocess generated HTML file - utils.postprocess_html_file(dstpath) - - if anything_modified: - generators.generate_index_and_feed() - sys.stderr.write("done\n") - - if report_total_errors: - sys.stderr.write("build finished with %d errors\n" % failed_builds) - return failed_builds - - def generate(args): """Wrapper for generate_blog(fresh=False).""" # pylint: disable=unused-argument - exit(generate_blog(fresh=False)) + exit(generators.generate_blog(fresh=False)) def regenerate(args): """Wrapper for generate_blog(fresh=True).""" # pylint: disable=unused-argument - exit(generate_blog(fresh=True)) + exit(generators.generate_blog(fresh=True)) def sanitize(string): @@ -502,7 +364,7 @@ def gen_deploy(args): touch(latest_post) sys.stderr.write("\n") - generate_blog(fresh=True) + generators.generate_blog(fresh=True) deploy(None) @@ -570,7 +432,7 @@ def preview(args): # watches for modifications and only regens upon changes, and it is # completely silent when there's no change. while not sigint_raised: - generate_blog(fresh=False, report_total_errors=False) + generators.generate_blog(fresh=False, report_total_errors=False) time.sleep(0.5) sys.stderr.write("\nSIGINT received, cleaning up...\n") |