annotate piecrust/serving.py @ 264:74bea91c9630

bake: Don't store internal config values in the bake record. We sometimes store actual objects in the page config (like for instance page linkers) and we don't want that to be pickled.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 24 Feb 2015 23:18:23 -0800
parents 7ec06ec14247
children 980bbbd0705e
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.
7
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
303 if app.debug:
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