Le blog de Victor Héry https://blog.victor-hery.com
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.

117 lines
3.5 KiB

  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. # Host and port for `serve`
  24. 'host': 'localhost',
  25. 'port': 8000,
  26. }
  27. @task
  28. def clean(c):
  29. """Remove generated files"""
  30. if os.path.isdir(CONFIG['deploy_path']):
  31. shutil.rmtree(CONFIG['deploy_path'])
  32. os.makedirs(CONFIG['deploy_path'])
  33. @task
  34. def build(c):
  35. """Build local version of site"""
  36. pelican_run('-s {settings_base}'.format(**CONFIG))
  37. @task
  38. def rebuild(c):
  39. """`build` with the delete switch"""
  40. pelican_run('-d -s {settings_base}'.format(**CONFIG))
  41. @task
  42. def regenerate(c):
  43. """Automatically regenerate site upon file modification"""
  44. pelican_run('-r -s {settings_base}'.format(**CONFIG))
  45. @task
  46. def serve(c):
  47. """Serve site at http://$HOST:$PORT/ (default is localhost:8000)"""
  48. class AddressReuseTCPServer(RootedHTTPServer):
  49. allow_reuse_address = True
  50. server = AddressReuseTCPServer(
  51. CONFIG['deploy_path'],
  52. (CONFIG['host'], CONFIG['port']),
  53. ComplexHTTPRequestHandler)
  54. sys.stderr.write('Serving at {host}:{port} ...\n'.format(**CONFIG))
  55. server.serve_forever()
  56. @task
  57. def reserve(c):
  58. """`build`, then `serve`"""
  59. build(c)
  60. serve(c)
  61. @task
  62. def preview(c):
  63. """Build production version of site"""
  64. pelican_run('-s {settings_publish}'.format(**CONFIG))
  65. @task
  66. def livereload(c):
  67. """Automatically reload browser tab upon file modification."""
  68. from livereload import Server
  69. build(c)
  70. server = Server()
  71. # Watch the base settings file
  72. server.watch(CONFIG['settings_base'], lambda: build(c))
  73. # Watch content source files
  74. content_file_extensions = ['.md', '.rst']
  75. for extension in content_file_extensions:
  76. content_blob = '{0}/**/*{1}'.format(SETTINGS['PATH'], extension)
  77. server.watch(content_blob, lambda: build(c))
  78. # Watch the theme's templates and static assets
  79. theme_path = SETTINGS['THEME']
  80. server.watch('{}/templates/*.html'.format(theme_path), lambda: build(c))
  81. static_file_extensions = ['.css', '.js']
  82. for extension in static_file_extensions:
  83. static_file = '{0}/static/**/*{1}'.format(theme_path, extension)
  84. server.watch(static_file, lambda: build(c))
  85. # Serve output path on configured host and port
  86. server.serve(host=CONFIG['host'], port=CONFIG['port'], root=CONFIG['deploy_path'])
  87. @task
  88. def publish(c):
  89. """Publish to production via rsync"""
  90. pelican_run('-s {settings_publish}'.format(**CONFIG))
  91. c.run(
  92. 'rsync --delete --exclude ".DS_Store" -pthrvz -c '
  93. '-e "ssh -p {ssh_port}" '
  94. '{} {ssh_user}@{ssh_host}:{ssh_path}'.format(
  95. CONFIG['deploy_path'].rstrip('/') + '/',
  96. **CONFIG))
  97. def pelican_run(cmd):
  98. cmd += ' ' + program.core.remainder # allows to pass-through args to pelican
  99. pelican_main(shlex.split(cmd))