annotate piecrust/serving.py @ 279:980bbbd0705e

serve: Correctly show timing info even when not in debug mode.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 01 Mar 2015 21:38:24 -0800
parents 7ec06ec14247
children 8c0c53a315ae
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
1 import io
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
2 import os
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
3 import re
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
4 import json
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
5 import gzip
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
6 import time
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
7 import queue
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8 import os.path
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
9 import hashlib
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
10 import logging
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
11 import datetime
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
12 import threading
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
13 from werkzeug.exceptions import (
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
14 NotFound, MethodNotAllowed, InternalServerError, HTTPException)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
15 from werkzeug.wrappers import Request, Response
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
16 from werkzeug.wsgi import ClosingIterator, wrap_file
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
17 from jinja2 import FileSystemLoader, Environment
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
18 from piecrust.app import PieCrust
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
19 from piecrust.data.filters import (
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
20 PaginationFilter, HasFilterClause, IsFilterClause)
111
208c652551a3 Quick fix for making the server correctly update referenced pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 110
diff changeset
21 from piecrust.environment import StandardEnvironment
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
22 from piecrust.processing.base import ProcessorPipeline
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
23 from piecrust.rendering import PageRenderingContext, render_page
11
617191dec18e Fixes for Windows, make `findPagePath` return a ref path.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
24 from piecrust.sources.base import PageFactory, MODE_PARSING
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
25
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
26
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
27 logger = logging.getLogger(__name__)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
28
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
29
224
4f00bb99400e serve: Fix exiting the server with `CTRL+C` when the SSE response is running.
Ludovic Chabant <ludovic@chabant.com>
parents: 223
diff changeset
30 _sse_abort = threading.Event()
4f00bb99400e serve: Fix exiting the server with `CTRL+C` when the SSE response is running.
Ludovic Chabant <ludovic@chabant.com>
parents: 223
diff changeset
31
4f00bb99400e serve: Fix exiting the server with `CTRL+C` when the SSE response is running.
Ludovic Chabant <ludovic@chabant.com>
parents: 223
diff changeset
32
111
208c652551a3 Quick fix for making the server correctly update referenced pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 110
diff changeset
33 class ServingEnvironment(StandardEnvironment):
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
34 pass
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
35
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
36
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
37 class ServeRecord(object):
111
208c652551a3 Quick fix for making the server correctly update referenced pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 110
diff changeset
38 def __init__(self):
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
39 self.entries = {}
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
40
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
41 def addEntry(self, entry):
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
42 key = self._makeKey(entry.uri, entry.sub_num)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
43 self.entries[key] = entry
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
44
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
45 def getEntry(self, uri, sub_num):
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
46 key = self._makeKey(uri, sub_num)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
47 return self.entries.get(key)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
48
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
49 def _makeKey(self, uri, sub_num):
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
50 return "%s:%s" % (uri, sub_num)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
51
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
52
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
53 class ServeRecordPageEntry(object):
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
54 def __init__(self, uri, sub_num):
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
55 self.uri = uri
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
56 self.sub_num = sub_num
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
57 self.used_source_names = set()
111
208c652551a3 Quick fix for making the server correctly update referenced pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 110
diff changeset
58
208c652551a3 Quick fix for making the server correctly update referenced pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 110
diff changeset
59
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
60 class WsgiServerWrapper(object):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
61 def __init__(self, server):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
62 self.server = server
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
63
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
64 def __call__(self, environ, start_response):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
65 return self.server._run_request(environ, start_response)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
66
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
67
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
68 class Server(object):
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
69 def __init__(self, root_dir,
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
70 debug=False, use_reloader=False, static_preview=True):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
71 self.root_dir = root_dir
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
72 self.debug = debug
155
70b86e904b85 Properly use, or not, the debugging when using the chef server.
Ludovic Chabant <ludovic@chabant.com>
parents: 141
diff changeset
73 self.use_reloader = use_reloader
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
74 self.static_preview = static_preview
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
75 self._out_dir = None
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
76 self._page_record = None
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
77 self._proc_loop = None
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
78 self._mimetype_map = load_mimetype_map()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
79
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
80 def getWsgiApp(self):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
81 # Bake all the assets so we know what we have, and so we can serve
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
82 # them to the client. We need a temp app for this.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
83 app = PieCrust(root_dir=self.root_dir, debug=self.debug)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
84 self._out_dir = os.path.join(app.cache_dir, 'server')
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
85 self._page_record = ServeRecord()
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
86
214
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
87 if (not self.use_reloader or
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
88 os.environ.get('WERKZEUG_RUN_MAIN') == 'true'):
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
89 # We don't want to run the processing loop here if this isn't
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
90 # the actual process that does the serving. In most cases it is,
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
91 # but if we're using Werkzeug's reloader, then it won't be the
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
92 # first time we get there... it will only be the correct process
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
93 # the second time, when the reloading process is spawned, with the
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
94 # `WERKZEUG_RUN_MAIN` variable set.
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
95 pipeline = ProcessorPipeline(app, self._out_dir)
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
96 self._proc_loop = ProcessingLoop(pipeline)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
97 self._proc_loop.start()
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
98
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
99 # Run the WSGI app.
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
100 wsgi_wrapper = WsgiServerWrapper(self)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
101 return wsgi_wrapper
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
102
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
103 def _run_request(self, environ, start_response):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
104 try:
200
76e459d48c43 serve: Correctly pass on the HTTP status code when an error occurs.
Ludovic Chabant <ludovic@chabant.com>
parents: 190
diff changeset
105 return self._try_run_request(environ, start_response)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
106 except Exception as ex:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
107 if self.debug:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
108 raise
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
109 return self._handle_error(ex, environ, start_response)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
110
200
76e459d48c43 serve: Correctly pass on the HTTP status code when an error occurs.
Ludovic Chabant <ludovic@chabant.com>
parents: 190
diff changeset
111 def _try_run_request(self, environ, start_response):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
112 request = Request(environ)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
113
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
114 # We don't support anything else than GET requests since we're
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
115 # previewing something that will be static later.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
116 if self.static_preview and request.method != 'GET':
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
117 logger.error("Only GET requests are allowed, got %s" %
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
118 request.method)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
119 raise MethodNotAllowed()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
120
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
121 # Handle special requests right away.
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
122 response = self._try_special_request(environ, request)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
123 if response is not None:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
124 return response(environ, start_response)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
125
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
126 # Also handle requests to a pipeline-built asset right away.
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
127 response = self._try_serve_asset(environ, request)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
128 if response is not None:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
129 return response(environ, start_response)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
130
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
131 # Create the app for this request.
223
7decf00eee47 serve: Don't expose the debug info right away when running with `--debug`.
Ludovic Chabant <ludovic@chabant.com>
parents: 219
diff changeset
132 app = PieCrust(root_dir=self.root_dir, debug=self.debug)
53
73956224eb67 Setup the server better.
Ludovic Chabant <ludovic@chabant.com>
parents: 39
diff changeset
133 app.config.set('site/root', '/')
73956224eb67 Setup the server better.
Ludovic Chabant <ludovic@chabant.com>
parents: 39
diff changeset
134 app.config.set('server/is_serving', True)
223
7decf00eee47 serve: Don't expose the debug info right away when running with `--debug`.
Ludovic Chabant <ludovic@chabant.com>
parents: 219
diff changeset
135 if (app.config.get('site/enable_debug_info') and
7decf00eee47 serve: Don't expose the debug info right away when running with `--debug`.
Ludovic Chabant <ludovic@chabant.com>
parents: 219
diff changeset
136 '!debug' in request.args):
7decf00eee47 serve: Don't expose the debug info right away when running with `--debug`.
Ludovic Chabant <ludovic@chabant.com>
parents: 219
diff changeset
137 app.config.set('site/show_debug_info', True)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
138
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
139 # We'll serve page assets directly from where they are.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
140 app.env.base_asset_url_format = '/_asset/%path%'
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
141
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
142 # Let's see if it can be a page asset.
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
143 response = self._try_serve_page_asset(app, environ, request)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
144 if response is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
145 return response(environ, start_response)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
146
133
9e4c2e68a129 Optimize server for files that already exist.
Ludovic Chabant <ludovic@chabant.com>
parents: 130
diff changeset
147 # Nope. Let's see if it's an actual page.
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
148 try:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
149 response = self._try_serve_page(app, environ, request)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
150 return response(environ, start_response)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
151 except (RouteNotFoundError, SourceNotFoundError) as ex:
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
152 raise NotFound(str(ex)) from ex
133
9e4c2e68a129 Optimize server for files that already exist.
Ludovic Chabant <ludovic@chabant.com>
parents: 130
diff changeset
153 except HTTPException:
9e4c2e68a129 Optimize server for files that already exist.
Ludovic Chabant <ludovic@chabant.com>
parents: 130
diff changeset
154 raise
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
155 except Exception as ex:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
156 if app.debug:
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
157 logger.exception(ex)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
158 raise
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
159 msg = str(ex)
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
160 logger.error(msg)
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
161 raise InternalServerError(msg) from ex
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
162
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
163 def _try_special_request(self, environ, request):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
164 static_mount = '/__piecrust_static/'
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
165 if request.path.startswith(static_mount):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
166 rel_req_path = request.path[len(static_mount):]
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
167 mount = os.path.join(
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
168 os.path.dirname(__file__),
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
169 'resources', 'server')
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
170 full_path = os.path.join(mount, rel_req_path)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
171 try:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
172 response = self._make_wrapped_file_response(
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
173 environ, request, full_path)
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
174 return response
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
175 except OSError:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
176 pass
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
177
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
178 debug_mount = '/__piecrust_debug/'
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
179 if request.path.startswith(debug_mount):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
180 rel_req_path = request.path[len(debug_mount):]
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
181 if rel_req_path == 'pipeline_status':
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
182 provider = PipelineStatusServerSideEventProducer(
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
183 self._proc_loop.status_queue)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
184 it = ClosingIterator(provider.run(), [provider.close])
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
185 response = Response(it)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
186 response.headers['Cache-Control'] = 'no-cache'
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
187 if 'text/event-stream' in request.accept_mimetypes:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
188 response.mimetype = 'text/event-stream'
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
189 response.direct_passthrough = True
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
190 response.implicit_sequence_conversion = False
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
191 return response
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
192
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
193 return None
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
194
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
195 def _try_serve_asset(self, environ, request):
11
617191dec18e Fixes for Windows, make `findPagePath` return a ref path.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
196 rel_req_path = request.path.lstrip('/').replace('/', os.sep)
240
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 232
diff changeset
197 if request.path.startswith('/_cache/'):
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 232
diff changeset
198 # Some stuff needs to be served directly from the cache directory,
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 232
diff changeset
199 # like LESS CSS map files.
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 232
diff changeset
200 full_path = os.path.join(self.root_dir, rel_req_path)
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 232
diff changeset
201 else:
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 232
diff changeset
202 full_path = os.path.join(self._out_dir, rel_req_path)
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 232
diff changeset
203
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
204 try:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
205 response = self._make_wrapped_file_response(
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
206 environ, request, full_path)
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
207 return response
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
208 except OSError:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
209 pass
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
210 return None
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
211
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
212 def _try_serve_page_asset(self, app, environ, request):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
213 if not request.path.startswith('/_asset/'):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
214 return None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
215
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
216 full_path = os.path.join(app.root_dir, request.path[len('/_asset/'):])
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
217 if not os.path.isfile(full_path):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
218 return None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
219
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
220 return self._make_wrapped_file_response(environ, request, full_path)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
221
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
222 def _try_serve_page(self, app, environ, request):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
223 # Try to find what matches the requested URL.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
224 req_path = request.path
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
225 page_num = 1
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
226 pgn_suffix_re = app.config.get('__cache/pagination_suffix_re')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
227 pgn_suffix_m = re.search(pgn_suffix_re, request.path)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
228 if pgn_suffix_m:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
229 req_path = request.path[:pgn_suffix_m.start()]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
230 page_num = int(pgn_suffix_m.group('num'))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
231
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
232 routes = find_routes(app.routes, req_path)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
233 if len(routes) == 0:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
234 raise RouteNotFoundError("Can't find route for: %s" % req_path)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
235
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
236 taxonomy = None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
237 for route, route_metadata in routes:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
238 source = app.getSource(route.source_name)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
239 if route.taxonomy is None:
11
617191dec18e Fixes for Windows, make `findPagePath` return a ref path.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
240 rel_path, fac_metadata = source.findPagePath(
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
241 route_metadata, MODE_PARSING)
11
617191dec18e Fixes for Windows, make `findPagePath` return a ref path.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
242 if rel_path is not None:
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
243 break
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
244 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
245 taxonomy = app.getTaxonomy(route.taxonomy)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
246 term_value = route_metadata.get(taxonomy.term_name)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
247 if term_value is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
248 tax_page_ref = taxonomy.getPageRef(source.name)
11
617191dec18e Fixes for Windows, make `findPagePath` return a ref path.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
249 rel_path = tax_page_ref.rel_path
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
250 source = tax_page_ref.source
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
251 fac_metadata = {taxonomy.term_name: term_value}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
252 break
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
253 else:
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
254 raise SourceNotFoundError(
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
255 "Can't find path for: %s (looked in: %s)" %
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
256 (req_path, [r.source_name for r, _ in routes]))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
257
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
258 # Build the page.
11
617191dec18e Fixes for Windows, make `findPagePath` return a ref path.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
259 fac = PageFactory(source, rel_path, fac_metadata)
617191dec18e Fixes for Windows, make `findPagePath` return a ref path.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
260 page = fac.buildPage()
174
e9a3d405e18f serve: Always force render the page being previewed.
Ludovic Chabant <ludovic@chabant.com>
parents: 173
diff changeset
261 # We force the rendering of the page because it could not have
e9a3d405e18f serve: Always force render the page being previewed.
Ludovic Chabant <ludovic@chabant.com>
parents: 173
diff changeset
262 # changed, but include pages that did change.
e9a3d405e18f serve: Always force render the page being previewed.
Ludovic Chabant <ludovic@chabant.com>
parents: 173
diff changeset
263 render_ctx = PageRenderingContext(page, req_path, page_num,
e9a3d405e18f serve: Always force render the page being previewed.
Ludovic Chabant <ludovic@chabant.com>
parents: 173
diff changeset
264 force_render=True)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
265 if taxonomy is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
266 flt = PaginationFilter()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
267 if taxonomy.is_multiple:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
268 flt.addClause(HasFilterClause(taxonomy.name, term_value))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
269 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
270 flt.addClause(IsFilterClause(taxonomy.name, term_value))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
271 render_ctx.pagination_filter = flt
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
272 render_ctx.custom_data = {
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
273 taxonomy.term_name: term_value}
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
274
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
275 # See if this page is known to use sources. If that's the case,
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
276 # just don't use cached rendered segments for that page (but still
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
277 # use them for pages that are included in it).
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
278 entry = self._page_record.getEntry(req_path, page_num)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
279 if (taxonomy is not None or entry is None or
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
280 entry.used_source_names):
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
281 cache_key = '%s:%s' % (req_path, page_num)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
282 app.env.rendered_segments_repository.invalidate(cache_key)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
283
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
284 # Render the page.
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
285 rendered_page = render_page(render_ctx)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
286 rp_content = rendered_page.content
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
287
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
288 if taxonomy is not None:
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
289 paginator = rendered_page.data.get('pagination')
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
290 if (paginator and paginator.is_loaded and
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
291 len(paginator.items) == 0):
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
292 message = ("This URL matched a route for taxonomy '%s' but "
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
293 "no pages have been found to have it. This page "
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
294 "won't be generated by a bake." % taxonomy.name)
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
295 raise NotFound(message)
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
296
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
297 if entry is None:
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
298 entry = ServeRecordPageEntry(req_path, page_num)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
299 self._page_record.addEntry(entry)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
300 entry.used_source_names = set(render_ctx.used_source_names)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
301
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
302 # Profiling.
279
980bbbd0705e serve: Correctly show timing info even when not in debug mode.
Ludovic Chabant <ludovic@chabant.com>
parents: 258
diff changeset
303 if app.config.get('site/show_debug_info'):
7
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
304 now_time = time.clock()
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
305 timing_info = ('%8.1f ms' %
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
306 ((now_time - app.env.start_time) * 1000.0))
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
307 rp_content = rp_content.replace('__PIECRUST_TIMING_INFORMATION__',
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
308 timing_info)
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
309
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
310 # Build the response.
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
311 response = Response()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
312
7
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
313 etag = hashlib.md5(rp_content.encode('utf8')).hexdigest()
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
314 if not app.debug and etag in request.if_none_match:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
315 response.status_code = 304
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
316 return response
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
317
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
318 response.set_etag(etag)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
319 response.content_md5 = etag
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
320
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
321 cache_control = response.cache_control
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
322 if app.debug:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
323 cache_control.no_cache = True
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
324 cache_control.must_revalidate = True
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
325 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
326 cache_time = (page.config.get('cache_time') or
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
327 app.config.get('site/cache_time'))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
328 if cache_time:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
329 cache_control.public = True
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
330 cache_control.max_age = cache_time
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
331
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
332 content_type = page.config.get('content_type')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
333 if content_type and '/' not in content_type:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
334 mimetype = content_type_map.get(content_type, content_type)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
335 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
336 mimetype = content_type
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
337 if mimetype:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
338 response.mimetype = mimetype
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
339
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
340 if ('gzip' in request.accept_encodings and
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
341 app.config.get('site/enable_gzip')):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
342 try:
7
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
343 with io.BytesIO() as gzip_buffer:
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
344 with gzip.open(gzip_buffer, mode='wt',
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
345 encoding='utf8') as gzip_file:
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
346 gzip_file.write(rp_content)
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
347 rp_content = gzip_buffer.getvalue()
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
348 response.content_encoding = 'gzip'
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
349 except Exception:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
350 logger.exception("Error compressing response, "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
351 "falling back to uncompressed.")
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
352 response.set_data(rp_content)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
353
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
354 return response
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
355
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
356 def _make_wrapped_file_response(self, environ, request, path):
190
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
357 logger.debug("Serving %s" % path)
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
358
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
359 # Check if we can return a 304 status code.
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
360 mtime = os.path.getmtime(path)
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
361 etag_str = '%s$$%s' % (path, mtime)
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
362 etag = hashlib.md5(etag_str.encode('utf8')).hexdigest()
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
363 if etag in request.if_none_match:
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
364 response = Response()
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
365 response.status_code = 304
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
366 return response
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
367
190
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
368 wrapper = wrap_file(environ, open(path, 'rb'))
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
369 response = Response(wrapper)
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
370 _, ext = os.path.splitext(path)
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
371 response.set_etag(etag)
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
372 response.last_modified = datetime.datetime.fromtimestamp(mtime)
190
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
373 response.mimetype = self._mimetype_map.get(
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
374 ext.lstrip('.'), 'text/plain')
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
375 return response
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
376
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
377 def _handle_error(self, exception, environ, start_response):
200
76e459d48c43 serve: Correctly pass on the HTTP status code when an error occurs.
Ludovic Chabant <ludovic@chabant.com>
parents: 190
diff changeset
378 code = 500
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
379 if isinstance(exception, HTTPException):
200
76e459d48c43 serve: Correctly pass on the HTTP status code when an error occurs.
Ludovic Chabant <ludovic@chabant.com>
parents: 190
diff changeset
380 code = exception.code
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
381
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
382 path = 'error'
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
383 if isinstance(exception, NotFound):
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
384 path += '404'
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
385
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
386 descriptions = self._get_exception_descriptions(exception)
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
387
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
388 env = Environment(loader=ErrorMessageLoader())
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
389 template = env.get_template(path)
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
390 context = {'details': descriptions}
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
391 response = Response(template.render(context), mimetype='text/html')
200
76e459d48c43 serve: Correctly pass on the HTTP status code when an error occurs.
Ludovic Chabant <ludovic@chabant.com>
parents: 190
diff changeset
392 response.status_code = code
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
393 return response(environ, start_response)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
394
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
395 def _get_exception_descriptions(self, exception):
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
396 desc = []
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
397 while exception is not None:
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
398 if isinstance(exception, HTTPException):
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
399 desc.append(exception.description)
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
400 else:
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
401 desc.append(str(exception))
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
402
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
403 inner_ex = exception.__cause__
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
404 if inner_ex is None:
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
405 inner_ex = exception.__context__
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
406 exception = inner_ex
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
407 return desc
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
408
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
409
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
410 class RouteNotFoundError(Exception):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
411 pass
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
412
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
413
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
414 class SourceNotFoundError(Exception):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
415 pass
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
416
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
417
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
418 content_type_map = {
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
419 'html': 'text/html',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
420 'xml': 'text/xml',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
421 'txt': 'text/plain',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
422 'text': 'text/plain',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
423 'css': 'text/css',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
424 'xhtml': 'application/xhtml+xml',
232
e534d2bc657c cosmetic: Fix PEP8 spacing.
Ludovic Chabant <ludovic@chabant.com>
parents: 231
diff changeset
425 'atom': 'application/atom+xml', # or 'text/xml'?
e534d2bc657c cosmetic: Fix PEP8 spacing.
Ludovic Chabant <ludovic@chabant.com>
parents: 231
diff changeset
426 'rss': 'application/rss+xml', # or 'text/xml'?
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
427 'json': 'application/json'}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
428
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
429
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
430 def find_routes(routes, uri):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
431 uri = uri.lstrip('/')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
432 res = []
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
433 for route in routes:
176
d47d9493bb0a routes: When matching URIs, return metadata directly instead of the match object.
Ludovic Chabant <ludovic@chabant.com>
parents: 174
diff changeset
434 metadata = route.matchUri(uri)
231
137bcd498ef9 serve: Fix a bug where empty route metadata is not the same as invalid route.
Ludovic Chabant <ludovic@chabant.com>
parents: 229
diff changeset
435 if metadata is not None:
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
436 res.append((route, metadata))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
437 return res
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
438
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
439
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
440 class ErrorMessageLoader(FileSystemLoader):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
441 def __init__(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
442 base_dir = os.path.join(os.path.dirname(__file__), 'resources',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
443 'messages')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
444 super(ErrorMessageLoader, self).__init__(base_dir)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
445
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
446 def get_source(self, env, template):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
447 template += '.html'
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
448 return super(ErrorMessageLoader, self).get_source(env, template)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
449
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
450
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
451 def load_mimetype_map():
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
452 mimetype_map = {}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
453 sep_re = re.compile(r'\s+')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
454 path = os.path.join(os.path.dirname(__file__), 'mime.types')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
455 with open(path, 'r') as f:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
456 for line in f:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
457 tokens = sep_re.split(line)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
458 if len(tokens) > 1:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
459 for t in tokens[1:]:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
460 mimetype_map[t] = tokens[0]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
461 return mimetype_map
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
462
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
463
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
464 class PipelineStatusServerSideEventProducer(object):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
465 def __init__(self, status_queue):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
466 self.status_queue = status_queue
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
467 self.interval = 2
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
468 self.timeout = 60*10
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
469 self._start_time = 0
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
470
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
471 def run(self):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
472 logger.debug("Starting pipeline status SSE.")
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
473 self._start_time = time.time()
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
474
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
475 outstr = 'event: ping\ndata: started\n\n'
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
476 yield bytes(outstr, 'utf8')
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
477
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
478 count = 0
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
479 while True:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
480 if time.time() > self.timeout + self._start_time:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
481 logger.debug("Closing pipeline status SSE, timeout reached.")
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
482 outstr = 'event: pipeline_timeout\ndata: bye\n\n'
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
483 yield bytes(outstr, 'utf8')
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
484 break
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
485
224
4f00bb99400e serve: Fix exiting the server with `CTRL+C` when the SSE response is running.
Ludovic Chabant <ludovic@chabant.com>
parents: 223
diff changeset
486 if _sse_abort.is_set():
4f00bb99400e serve: Fix exiting the server with `CTRL+C` when the SSE response is running.
Ludovic Chabant <ludovic@chabant.com>
parents: 223
diff changeset
487 break
4f00bb99400e serve: Fix exiting the server with `CTRL+C` when the SSE response is running.
Ludovic Chabant <ludovic@chabant.com>
parents: 223
diff changeset
488
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
489 try:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
490 logger.debug("Polling pipeline status queue...")
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
491 count += 1
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
492 data = self.status_queue.get(True, self.interval)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
493 except queue.Empty:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
494 if count < 3:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
495 continue
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
496 data = {'type': 'ping', 'message': 'ping'}
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
497 count = 0
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
498
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
499 event_type = data['type']
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
500 outstr = 'event: %s\ndata: %s\n\n' % (
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
501 event_type, json.dumps(data))
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
502 logger.debug("Sending pipeline status SSE.")
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
503 yield bytes(outstr, 'utf8')
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
504
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
505 def close(self):
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
506 logger.debug("Closing pipeline status SSE.")
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
507
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
508
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
509 class ProcessingLoop(threading.Thread):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
510 def __init__(self, pipeline):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
511 super(ProcessingLoop, self).__init__(
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
512 name='pipeline-reloader', daemon=True)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
513 self.pipeline = pipeline
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
514 self.status_queue = queue.Queue()
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
515 self.interval = 1
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
516 self._paths = set()
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
517 self._record = None
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
518 self._last_bake = 0
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
519
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
520 def run(self):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
521 # Build the first list of known files and run the pipeline once.
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
522 app = self.pipeline.app
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
523 roots = [os.path.join(app.root_dir, r)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
524 for r in self.pipeline.mounts.keys()]
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
525 for root in roots:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
526 for dirpath, dirnames, filenames in os.walk(root):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
527 self._paths |= set([os.path.join(dirpath, f)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
528 for f in filenames])
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
529 self._last_bake = time.time()
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
530 self._record = self.pipeline.run(save_record=False)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
531
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
532 while True:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
533 for root in roots:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
534 # For each mount root we try to find the first new or
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
535 # modified file. If any, we just run the pipeline on
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
536 # that mount.
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
537 found_new_or_modified = False
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
538 for dirpath, dirnames, filenames in os.walk(root):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
539 for filename in filenames:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
540 path = os.path.join(dirpath, filename)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
541 if path not in self._paths:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
542 logger.debug("Found new asset: %s" % path)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
543 self._paths.add(path)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
544 found_new_or_modified = True
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
545 break
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
546 if os.path.getmtime(path) > self._last_bake:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
547 logger.debug("Found modified asset: %s" % path)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
548 found_new_or_modified = True
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
549 break
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
550
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
551 if found_new_or_modified:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
552 break
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
553
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
554 if found_new_or_modified:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
555 self._runPipeline(root)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
556
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
557 time.sleep(self.interval)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
558
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
559 def _runPipeline(self, root):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
560 self._last_bake = time.time()
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
561 try:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
562 self._record = self.pipeline.run(
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
563 root,
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
564 previous_record=self._record,
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
565 save_record=False)
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
566
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
567 # Update the status queue.
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
568 # (we need to clear it because there may not be a consumer
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
569 # on the other side, if the user isn't running with the
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
570 # debug window active)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
571 while True:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
572 try:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
573 self.status_queue.get_nowait()
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
574 except queue.Empty:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
575 break
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
576
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
577 if self._record.success:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
578 item = {
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
579 'type': 'pipeline_success'}
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
580 self.status_queue.put_nowait(item)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
581 else:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
582 item = {
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
583 'type': 'pipeline_error',
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
584 'assets': []}
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
585 for entry in self._record.entries:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
586 if entry.errors:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
587 asset_item = {
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
588 'path': entry.rel_input,
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
589 'errors': list(entry.errors)}
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
590 item['assets'].append(asset_item)
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
591 self.status_queue.put_nowait(item)
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
592 except:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
593 pass
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
594