A fork of hyde, the static site generation. Some patches will be pushed upstream.
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.
 
 
 

124 lines
3.9 KiB

  1. """
  2. Contains classes and utilities for serving a site
  3. generated from hyde.
  4. """
  5. import os
  6. import urlparse
  7. import urllib
  8. from SimpleHTTPServer import SimpleHTTPRequestHandler
  9. from BaseHTTPServer import HTTPServer
  10. from hyde.fs import File, Folder
  11. from hyde.site import Site
  12. from hyde.generator import Generator
  13. import logging
  14. logger = logging.getLogger('hyde.server')
  15. import sys
  16. logger.addHandler(logging.StreamHandler(sys.stdout))
  17. class HydeRequestHandler(SimpleHTTPRequestHandler):
  18. """
  19. Serves files by regenerating the resource (or)
  20. everything when a request is issued.
  21. """
  22. def do_GET(self):
  23. """
  24. Idenitfy the requested path. If the query string
  25. contains `refresh`, regenerat the entire site.
  26. Otherwise, regenerate only the requested resource
  27. and serve.
  28. """
  29. logger.info("Processing request:[%s]" % self.path)
  30. result = urlparse.urlparse(self.path)
  31. query = urlparse.parse_qs(result.query)
  32. if 'refresh' in query:
  33. self.server.regenerate()
  34. del query['refresh']
  35. parts = tuple(result)
  36. parts[4] = urllib.urlencode(query)
  37. new_url = urlparse.urlunparse(parts)
  38. logger.info('Redirecting...[%s]' % new_url)
  39. self.redirect(new_url)
  40. else:
  41. try:
  42. SimpleHTTPRequestHandler.do_GET(self)
  43. except Exception, exception:
  44. logger.error(exception.message)
  45. site = self.server.site
  46. res = site.content.resource_from_relative_path(
  47. site.config.not_found)
  48. self.redirect("/" + res.relative_deploy_path)
  49. def translate_path(self, path):
  50. """
  51. Finds the absolute path of the requested file by
  52. referring to the `site` variable in the server.
  53. """
  54. site = self.server.site
  55. result = urlparse.urlparse(self.path)
  56. logger.info("Trying to load file based on request:[%s]" % result.path)
  57. path = result.path.lstrip('/')
  58. res = site.content.resource_from_relative_path(path)
  59. if not res:
  60. logger.info("Cannot load file:[%s]" % path)
  61. raise Exception("Cannot load file: [%s]" % path)
  62. else:
  63. self.server.generate_resource(res)
  64. new_path = site.config.deploy_root_path.child(
  65. res.relative_deploy_path)
  66. return new_path
  67. def redirect(self, path, temporary=True):
  68. """
  69. Sends a redirect header with the new location.
  70. """
  71. self.send_response(302 if temporary else 301)
  72. self.send_header('Location', path)
  73. self.end_headers()
  74. class HydeWebServer(HTTPServer):
  75. """
  76. The hyde web server that regenerates the resource, node or site when
  77. a request is issued.
  78. """
  79. def __init__(self, site, address, port):
  80. self.site = site
  81. self.site.load()
  82. self.generator = Generator(self.site)
  83. HTTPServer.__init__(self, (address, port),
  84. HydeRequestHandler)
  85. def __reinit__(self):
  86. self.generator = Generator(self.site)
  87. self.regenerate()
  88. def regenerate(self):
  89. """
  90. Regenerates the entire site.
  91. """
  92. try:
  93. logger.info('Regenerating the entire site')
  94. self.generator.generate_all()
  95. except Exception, exception:
  96. logger.error('Error occured when regenerating the site [%s]'
  97. % exception.message)
  98. self.__reinit__()
  99. def generate_resource(self, resource):
  100. """
  101. Regenerates the entire site.
  102. """
  103. try:
  104. logger.info('Generating resource [%]' % resource)
  105. self.generator.generate_resource(resource)
  106. except Exception, exception:
  107. logger.error('Error [%s] occured when generating the resource [%s]'
  108. % (resource, repr(exception)))
  109. self.__reinit__()