From 1bdfcb12a6ab3ea5b89d1e1dc8524ecbad953cd1 Mon Sep 17 00:00:00 2001 From: nathaniel smith Date: Wed, 30 Aug 2017 23:19:29 -0700 Subject: [PATCH] WIP: good progress on compilation --- tildewiki/main.py | 102 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 6 deletions(-) diff --git a/tildewiki/main.py b/tildewiki/main.py index 65ece55..cc4c343 100644 --- a/tildewiki/main.py +++ b/tildewiki/main.py @@ -1,5 +1,6 @@ """TODO""" import os +import re import sys from os.path import expanduser from os.path import exists as path_exists @@ -9,6 +10,7 @@ import click import pygit2 from click import ClickException from click.types import Path +from markdown import markdown # TODO support reading from env SITE_NAME = 'tilde.town' @@ -17,6 +19,7 @@ PREVIEW_PATH = expanduser('~/public_html/wiki') LOCAL_REPOSITORY_PATH = expanduser('~/wiki') REPOSITORY_PATH = '/wiki' +DOUBLE_NEWLINE_RE = re.compile(r'\n\n', flags=re.MULTILINE|re.DOTALL) DEFAULT_PATH_KWARGS = dict( exists=True, writable=True, @@ -104,10 +107,13 @@ def init(config, local_repo_path, preview_path): raise ClickException( '{} already exists. Have you already run wiki init?'.format( preview_path)) - pygit2.clone_repository( - config.repo_path, - local_repo_path - ) + click.echo('Cloning {} to {}...'.format(config.repo_path, local_repo_path)) + pygit2.clone_repository(config.repo_path, local_repo_path) + click.echo('Creating {}...'.format(preview_path)) + os.makedirs(preview_path) + click.echo('TODO once we have compliation, this will compile') + click.echo('~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~') + click.echo("Congrats, you are ready to contribute to {}'s wiki!") @main.command() @click.option('--local-repo-path', @@ -119,8 +125,13 @@ def init(config, local_repo_path, preview_path): help='Local path to wiki for previewing.', type=Path(**DEFAULT_PATH_KWARGS)) @pass_config -def preview(config, local_repo_path): - raise NotImplementedError() +def preview(config, preview_path, local_repo_path): + preview_prompt = 'This will wipe everything at {}. Proceed?' + click.confirm( + preview_prompt.format(preview_path), + abort=True) + compile_wiki(local_repo_path, preview_path) + # TODO print some stuff about what just happend @main.command() @click.option('--local-repo-path', @@ -144,3 +155,82 @@ def get(config): @pass_config def reset(config, local_repo_path): raise NotImplementedError() + + +def compile_wiki(source_path, dest_path): + """Given a source path (presumably a git repository) and a destination + path, compiles the files found in {source_path}/articles and compiles them all + to {dest_path}/. + + THIS FUNCTION CLEARS {dest_path}/! + + Be absolutely sure you know what you are doing when you call this ^_^ + """ + # TODO progress bar + # TODO recursively delete dest_path (maybe after gzipping, backing up) + # TODO lockfile on dest_path + + articles_root = path_join(source_path, 'src/articles') + + for root, dirs, files in os.walk(articles_root): + # given root, i need to "diff" it against articles_root to get whatever + # point i should be at in preview_root. + current_suffix = root.replace(articles_root, '') + if current_suffix and current_suffix[0] == '/': + current_suffix = current_suffix[1:] + preview_root = path_join(dest_path, current_suffix) + + for directory in dirs: + os.mkdir(path_join(preview_root, directory)) + + for source_filename in files: + source_file_path = path_join(root, source_filename) + output = compile_source_file(source_file_path) + dest_filename = source_filename.split('.')[0] + '.html' + with open(path_join(preview_root, dest_filename), 'w') as f: + f.write(output) + +def slurp(file_path): + content = None + with open(file_path, 'r') as f: + content = f.read() + return content + +def compile_source_file(source_file_path): + if not os.path.isabs(source_file_path): + raise ValueError( + '{} is not an absolute path.'.format(source_file_path)) + + compiler = None + if source_file_path.endswith('.md'): + compiler = compile_markdown + elif source_file_path.endswith('.txt'): + compiler = compile_plaintext + elif source_file_path.endswith('.html'): + compiler = slurp + + if compiler is None: + raise ValueError( + '{} is not a recognized file type.'.format(source_file_path)) + + content = compiler(source_file_path) + + # TODO wrap content with header/footer + # TODO regenerate sitemap? might be error in rfc here + + return content + +def compile_markdown(source_file_path): + return markdown( + slurp(source_file_path), + output_format='html5') + +def compile_plaintext(source_file_path): + output = '

\n' + output += re.sub( + DOUBLE_NEWLINE_RE, + '

', + slurp(source_file_path)) + output += '\n

\n' + return output +