2
0

tasks.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. # -*- coding: utf-8 -*-
  2. import os
  3. import shlex
  4. import shutil
  5. import sys
  6. import datetime
  7. from invoke import task
  8. from invoke.main import program
  9. from invoke.util import cd
  10. from pelican import main as pelican_main
  11. from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer
  12. from pelican.settings import DEFAULT_CONFIG, get_settings_from_file
  13. SETTINGS_FILE_BASE = 'pelicanconf.py'
  14. SETTINGS = {}
  15. SETTINGS.update(DEFAULT_CONFIG)
  16. LOCAL_SETTINGS = get_settings_from_file(SETTINGS_FILE_BASE)
  17. SETTINGS.update(LOCAL_SETTINGS)
  18. CONFIG = {
  19. 'settings_base': SETTINGS_FILE_BASE,
  20. 'settings_publish': 'publishconf.py',
  21. # Output path. Can be absolute or relative to tasks.py. Default: 'output'
  22. 'deploy_path': SETTINGS['OUTPUT_PATH'],
  23. # Github Pages configuration
  24. 'github_pages_branch': 'gh-pages',
  25. 'commit_message': "'Publish site on {}'".format(datetime.date.today().isoformat()),
  26. # Host and port for `serve`
  27. 'host': 'localhost',
  28. 'port': 8000,
  29. }
  30. @task
  31. def clean(c):
  32. """Remove generated files"""
  33. if os.path.isdir(CONFIG['deploy_path']):
  34. shutil.rmtree(CONFIG['deploy_path'])
  35. os.makedirs(CONFIG['deploy_path'])
  36. @task
  37. def build(c):
  38. """Build local version of site"""
  39. pelican_run('-s {settings_base}'.format(**CONFIG))
  40. @task
  41. def rebuild(c):
  42. """`build` with the delete switch"""
  43. pelican_run('-d -s {settings_base}'.format(**CONFIG))
  44. @task
  45. def regenerate(c):
  46. """Automatically regenerate site upon file modification"""
  47. pelican_run('-r -s {settings_base}'.format(**CONFIG))
  48. @task
  49. def serve(c):
  50. """Serve site at http://$HOST:$PORT/ (default is localhost:8000)"""
  51. class AddressReuseTCPServer(RootedHTTPServer):
  52. allow_reuse_address = True
  53. server = AddressReuseTCPServer(
  54. CONFIG['deploy_path'],
  55. (CONFIG['host'], CONFIG['port']),
  56. ComplexHTTPRequestHandler)
  57. sys.stderr.write('Serving at {host}:{port} ...\n'.format(**CONFIG))
  58. server.serve_forever()
  59. @task
  60. def reserve(c):
  61. """`build`, then `serve`"""
  62. build(c)
  63. serve(c)
  64. @task
  65. def preview(c):
  66. """Build production version of site"""
  67. pelican_run('-s {settings_publish}'.format(**CONFIG))
  68. @task
  69. def livereload(c):
  70. """Automatically reload browser tab upon file modification."""
  71. from livereload import Server
  72. def cached_build():
  73. cmd = '-s {settings_base} -e CACHE_CONTENT=True LOAD_CONTENT_CACHE=True'
  74. pelican_run(cmd.format(**CONFIG))
  75. cached_build()
  76. server = Server()
  77. theme_path = SETTINGS['THEME']
  78. watched_globs = [
  79. CONFIG['settings_base'],
  80. '{}/templates/**/*.html'.format(theme_path),
  81. ]
  82. content_file_extensions = ['.md', '.rst']
  83. for extension in content_file_extensions:
  84. content_glob = '{0}/**/*{1}'.format(SETTINGS['PATH'], extension)
  85. watched_globs.append(content_glob)
  86. static_file_extensions = ['.css', '.js']
  87. for extension in static_file_extensions:
  88. static_file_glob = '{0}/static/**/*{1}'.format(theme_path, extension)
  89. watched_globs.append(static_file_glob)
  90. for glob in watched_globs:
  91. server.watch(glob, cached_build)
  92. server.serve(host=CONFIG['host'], port=CONFIG['port'], root=CONFIG['deploy_path'])
  93. @task
  94. def publish(c):
  95. """Publish to production via rsync"""
  96. pelican_run('-s {settings_publish}'.format(**CONFIG))
  97. c.run(
  98. 'rsync --delete --exclude ".DS_Store" -pthrvz -c '
  99. '-e "ssh -p {ssh_port}" '
  100. '{} {ssh_user}@{ssh_host}:{ssh_path}'.format(
  101. CONFIG['deploy_path'].rstrip('/') + '/',
  102. **CONFIG))
  103. @task
  104. def gh_pages(c):
  105. """Publish to GitHub Pages"""
  106. preview(c)
  107. c.run('ghp-import -b {github_pages_branch} '
  108. '-m {commit_message} '
  109. '{deploy_path} -p'.format(**CONFIG))
  110. def pelican_run(cmd):
  111. cmd += ' ' + program.core.remainder # allows to pass-through args to pelican
  112. pelican_main(shlex.split(cmd))