You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.1 KiB

  1. #!/usr/bin/env python3
  2. # Assumes that there's a directory named ~/src/www-home which is a git repo
  3. # that the contents of output/ can be copied to, committed, & pushed to the
  4. # production server.
  5. # TODO: replace gallery.tinyletterapp.com images with locally hosted content.
  6. # TODO: in template.html, add apple touch icon, maybe other favicon sizes.
  7. # TODO: local mirrors of all papers in publications.html
  8. import argparse
  9. import glob
  10. import markdown
  11. import os
  12. import re
  13. import shutil
  14. input_directory = 'content'
  15. static_directory = 'static'
  16. output_directory = 'output'
  17. deploy_directory = '~/src/www-home'
  18. md_extensions = [
  19. 'fenced_code', 'codehilite', 'nl2br', 'toc', 'smarty', 'tables', 'linkify']
  20. def print_file(in_file, out_file):
  21. print('%-62s -> %s' % (in_file, out_file))
  22. def copy_static_files():
  23. for (dirpath, _, filenames) in os.walk(static_directory):
  24. for filename in filenames:
  25. source = os.path.join(dirpath, filename)
  26. out_path = dirpath.replace(static_directory, '', 1)
  27. out_path = out_path.lstrip('/')
  28. dest_dir = os.path.join(output_directory, out_path)
  29. os.makedirs(dest_dir, exist_ok=True)
  30. dest = os.path.join(dest_dir, filename)
  31. print_file(source, dest)
  32. shutil.copy2(source, dest)
  33. def process_markdown_files():
  34. template = open('template.html').read()
  35. for (dirpath, _, filenames) in os.walk(input_directory):
  36. for filename in filenames:
  37. markdown_filename = os.path.join(dirpath, filename)
  38. if not markdown_filename.endswith('.md'):
  39. continue
  40. markdown_file = open(markdown_filename)
  41. text = markdown_file.read()
  42. markdown_file.close()
  43. if not text.startswith('# '):
  44. text = '# ' + text
  45. match = re.match(r'^(.*?)\n', text)
  46. if match:
  47. title = match.group(1).lstrip('# ')
  48. else:
  49. title = text
  50. title += ' | Colin McMillen'
  51. if markdown_filename == os.path.join(input_directory, 'index.md'):
  52. title = 'Colin McMillen'
  53. out_filename = os.path.basename(markdown_filename).replace('.md', '.html')
  54. out_dirpath = os.path.join(output_directory, dirpath)
  55. out_dirpath = out_dirpath.replace('/content', '', 1)
  56. out_fullpath = os.path.join(out_dirpath, out_filename)
  57. page_url = out_fullpath.replace('output/', '', 1)
  58. if page_url.endswith('index.html'): # strip off index.html
  59. page_url = page_url[:-len('index.html')]
  60. html = markdown.markdown(
  61. text, extensions=md_extensions, output_format='html5')
  62. output = template.format(title=title, content=html, page_url=page_url)
  63. os.makedirs(out_dirpath, exist_ok=True)
  64. print_file(markdown_filename, out_fullpath)
  65. out_file = open(out_fullpath, 'w')
  66. out_file.write(output)
  67. out_file.close()
  68. def make_sitemap():
  69. sitemap_command = ' '.join("""
  70. find output -regextype posix-extended -regex '.*.(html|pdf)$' |
  71. grep -v ^output/google |
  72. grep -v ^output/drafts |
  73. perl -pe 's|output|https://www.mcmillen.dev|'
  74. > output/sitemap.txt""".split('\n'))
  75. os.system(sitemap_command)
  76. def make_rss(): # TODO: implement.
  77. pass
  78. def deploy_site():
  79. os.system('cp -r output/* %s' % deploy_directory)
  80. os.chdir(os.path.expanduser(deploy_directory))
  81. os.system('git add .')
  82. os.system('git commit -m "automated update from build.py"')
  83. os.system('git push')
  84. def main():
  85. parser = argparse.ArgumentParser()
  86. parser.add_argument(
  87. '--clean', action='store_true',
  88. help='wipe the output directory before running')
  89. parser.add_argument(
  90. '--fast', action='store_true',
  91. help='only rebuild content files')
  92. parser.add_argument(
  93. '--deploy', action='store_true',
  94. help='deploy the site by pushing to the www-home git repo')
  95. args = parser.parse_args()
  96. if args.clean:
  97. shutil.rmtree(output_directory)
  98. os.makedirs(output_directory, exist_ok=True)
  99. if not args.fast:
  100. copy_static_files()
  101. process_markdown_files()
  102. make_sitemap()
  103. make_rss()
  104. if args.deploy:
  105. if args.fast:
  106. print('cowardly refusing to deploy a site that was built with --fast')
  107. else:
  108. deploy_site()
  109. if __name__ == '__main__':
  110. main()