##// END OF EJS Templates
rethrow upstream HTTP errors...
Min RK -
Show More
@@ -1,112 +1,105 b''
1 1 """PostProcessor for serving reveal.js HTML slideshows."""
2 from __future__ import print_function
3 #-----------------------------------------------------------------------------
4 #Copyright (c) 2013, the IPython Development Team.
5 #
6 #Distributed under the terms of the Modified BSD License.
7 #
8 #The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10 2
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 from __future__ import print_function
14 7
15 8 import os
16 9 import webbrowser
17 10
18 11 from tornado import web, ioloop, httpserver
19 12 from tornado.httpclient import AsyncHTTPClient
20 13
21 14 from IPython.utils.traitlets import Bool, Unicode, Int
22 15
23 16 from .base import PostProcessorBase
24 17
25 #-----------------------------------------------------------------------------
26 # Classes
27 #-----------------------------------------------------------------------------
28 18
29 19 class ProxyHandler(web.RequestHandler):
30 20 """handler the proxies requests from a local prefix to a CDN"""
31 21 @web.asynchronous
32 22 def get(self, prefix, url):
33 23 """proxy a request to a CDN"""
34 24 proxy_url = "/".join([self.settings['cdn'], url])
35 25 client = self.settings['client']
36 26 client.fetch(proxy_url, callback=self.finish_get)
37 27
38 28 def finish_get(self, response):
39 29 """finish the request"""
40 # copy potentially relevant headers
30 # rethrow errors
31 response.rethrow()
32
41 33 for header in ["Content-Type", "Cache-Control", "Date", "Last-Modified", "Expires"]:
42 34 if header in response.headers:
43 35 self.set_header(header, response.headers[header])
44 36 self.finish(response.body)
45 37
38
46 39 class ServePostProcessor(PostProcessorBase):
47 40 """Post processor designed to serve files
48 41
49 42 Proxies reveal.js requests to a CDN if no local reveal.js is present
50 43 """
51 44
52 45
53 46 open_in_browser = Bool(True, config=True,
54 47 help="""Should the browser be opened automatically?"""
55 48 )
56 49 reveal_cdn = Unicode("https://cdn.jsdelivr.net/reveal.js/2.6.2", config=True,
57 50 help="""URL for reveal.js CDN."""
58 51 )
59 52 reveal_prefix = Unicode("reveal.js", config=True, help="URL prefix for reveal.js")
60 53 ip = Unicode("127.0.0.1", config=True, help="The IP address to listen on.")
61 54 port = Int(8000, config=True, help="port for the server to listen on.")
62 55
63 56 def postprocess(self, input):
64 57 """Serve the build directory with a webserver."""
65 58 dirname, filename = os.path.split(input)
66 59 handlers = [
67 60 (r"/(.+)", web.StaticFileHandler, {'path' : dirname}),
68 61 (r"/", web.RedirectHandler, {"url": "/%s" % filename})
69 62 ]
70 63
71 64 if ('://' in self.reveal_prefix or self.reveal_prefix.startswith("//")):
72 65 # reveal specifically from CDN, nothing to do
73 66 pass
74 67 elif os.path.isdir(os.path.join(dirname, self.reveal_prefix)):
75 68 # reveal prefix exists
76 69 self.log.info("Serving local %s", self.reveal_prefix)
77 70 else:
78 71 self.log.info("Redirecting %s requests to %s", self.reveal_prefix, self.reveal_cdn)
79 72 handlers.insert(0, (r"/(%s)/(.*)" % self.reveal_prefix, ProxyHandler))
80 73
81 74 app = web.Application(handlers,
82 75 cdn=self.reveal_cdn,
83 76 client=AsyncHTTPClient(),
84 77 )
85 78 # hook up tornado logging to our logger
86 79 try:
87 80 from tornado import log
88 81 log.app_log = self.log
89 82 except ImportError:
90 83 # old tornado (<= 3), ignore
91 84 pass
92 85
93 86 http_server = httpserver.HTTPServer(app)
94 87 http_server.listen(self.port, address=self.ip)
95 88 url = "http://%s:%i/%s" % (self.ip, self.port, filename)
96 89 print("Serving your slides at %s" % url)
97 90 print("Use Control-C to stop this server")
98 91 if self.open_in_browser:
99 92 webbrowser.open(url, new=2)
100 93 try:
101 94 ioloop.IOLoop.instance().start()
102 95 except KeyboardInterrupt:
103 96 print("\nInterrupted")
104 97
105 98 def main(path):
106 99 """allow running this module to serve the slides"""
107 100 server = ServePostProcessor()
108 101 server(path)
109 102
110 103 if __name__ == '__main__':
111 104 import sys
112 105 main(sys.argv[1])
General Comments 0
You need to be logged in to leave comments. Login now