annotate piecrust/serving.py @ 298:b7ab1b503510

data: Fix incorrect next/previous page URLs in pagination data. Consolidate splitting an URL between its first URL and its sub page number. Be careful about the index page's URL not losing its slash.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 11 Mar 2015 23:46:42 -0700
parents 8c0c53a315ae
children 65e6d72f3877
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 (
280
8c0c53a315ae data: Correctly build pagination filters when we know items are pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 279
diff changeset
20 PaginationFilter, HasFilterClause, IsFilterClause,
8c0c53a315ae data: Correctly build pagination filters when we know items are pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 279
diff changeset
21 page_value_accessor)
111
208c652551a3 Quick fix for making the server correctly update referenced pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 110
diff changeset
22 from piecrust.environment import StandardEnvironment
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
23 from piecrust.processing.base import ProcessorPipeline
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
24 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
25 from piecrust.sources.base import PageFactory, MODE_PARSING
298
b7ab1b503510 data: Fix incorrect next/previous page URLs in pagination data.
Ludovic Chabant <ludovic@chabant.com>
parents: 280
diff changeset
26 from piecrust.uriutil import split_sub_uri
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
27
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 logger = logging.getLogger(__name__)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
30
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
31
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
32 _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
33
4f00bb99400e serve: Fix exiting the server with `CTRL+C` when the SSE response is running.
Ludovic Chabant <ludovic@chabant.com>
parents: 223
diff changeset
34
111
208c652551a3 Quick fix for making the server correctly update referenced pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 110
diff changeset
35 class ServingEnvironment(StandardEnvironment):
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
36 pass
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
37
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
38
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
39 class ServeRecord(object):
111
208c652551a3 Quick fix for making the server correctly update referenced pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 110
diff changeset
40 def __init__(self):
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
41 self.entries = {}
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
42
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
43 def addEntry(self, entry):
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
44 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
45 self.entries[key] = entry
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
46
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
47 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
48 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
49 return self.entries.get(key)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
50
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
51 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
52 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
53
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
54
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
55 class ServeRecordPageEntry(object):
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
56 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
57 self.uri = uri
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
58 self.sub_num = sub_num
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
59 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
60
208c652551a3 Quick fix for making the server correctly update referenced pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 110
diff changeset
61
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
62 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
63 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
64 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
65
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
66 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
67 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
68
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
69
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
70 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
71 def __init__(self, root_dir,
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
72 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
73 self.root_dir = root_dir
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
74 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
75 self.use_reloader = use_reloader
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
76 self.static_preview = static_preview
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
77 self._out_dir = None
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
78 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
79 self._proc_loop = None
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
80 self._mimetype_map = load_mimetype_map()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
81
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
82 def getWsgiApp(self):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
83 # 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
84 # 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
85 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
86 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
87 self._page_record = ServeRecord()
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
88
214
09e350db7f8f serve: Don't have 2 processing loops running when using `--use-reloader`.
Ludovic Chabant <ludovic@chabant.com>
parents: 209
diff changeset
89 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
90 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
91 # 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
92 # 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
93 # 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
94 # 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
95 # 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
96 # `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
97 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
98 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
99 self._proc_loop.start()
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
100
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
101 # 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
102 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
103 return wsgi_wrapper
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
104
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
105 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
106 try:
200
76e459d48c43 serve: Correctly pass on the HTTP status code when an error occurs.
Ludovic Chabant <ludovic@chabant.com>
parents: 190
diff changeset
107 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
108 except Exception as ex:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
109 if self.debug:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
110 raise
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
111 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
112
200
76e459d48c43 serve: Correctly pass on the HTTP status code when an error occurs.
Ludovic Chabant <ludovic@chabant.com>
parents: 190
diff changeset
113 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
114 request = Request(environ)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
115
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
116 # 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
117 # 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
118 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
119 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
120 request.method)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
121 raise MethodNotAllowed()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
122
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
123 # 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
124 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
125 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
126 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
127
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
128 # 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
129 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
130 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
131 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
132
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
133 # 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
134 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
135 app.config.set('site/root', '/')
73956224eb67 Setup the server better.
Ludovic Chabant <ludovic@chabant.com>
parents: 39
diff changeset
136 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
137 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
138 '!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
139 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
140
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
141 # 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
142 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
143
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
144 # 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
145 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
146 if response is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
147 return response(environ, start_response)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
148
133
9e4c2e68a129 Optimize server for files that already exist.
Ludovic Chabant <ludovic@chabant.com>
parents: 130
diff changeset
149 # 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
150 try:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
151 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
152 return response(environ, start_response)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
153 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
154 raise NotFound(str(ex)) from ex
133
9e4c2e68a129 Optimize server for files that already exist.
Ludovic Chabant <ludovic@chabant.com>
parents: 130
diff changeset
155 except HTTPException:
9e4c2e68a129 Optimize server for files that already exist.
Ludovic Chabant <ludovic@chabant.com>
parents: 130
diff changeset
156 raise
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
157 except Exception as ex:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
158 if app.debug:
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
159 logger.exception(ex)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
160 raise
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
161 msg = str(ex)
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
162 logger.error(msg)
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
163 raise InternalServerError(msg) from ex
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
164
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
165 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
166 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
167 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
168 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
169 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
170 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
171 '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
172 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
173 try:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
174 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
175 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
176 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
177 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
178 pass
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
179
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
180 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
181 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
182 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
183 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
184 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
185 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
186 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
187 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
188 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
189 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
190 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
191 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
192 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
193 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
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 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
196
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
197 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
198 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
199 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
200 # 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
201 # 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
202 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
203 else:
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 232
diff changeset
204 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
205
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
206 try:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
207 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
208 environ, request, full_path)
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
209 return response
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
210 except OSError:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
211 pass
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
212 return None
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
213
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
214 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
215 if not request.path.startswith('/_asset/'):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
216 return None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
217
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
218 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
219 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
220 return None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
221
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
222 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
223
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
224 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
225 # Try to find what matches the requested URL.
298
b7ab1b503510 data: Fix incorrect next/previous page URLs in pagination data.
Ludovic Chabant <ludovic@chabant.com>
parents: 280
diff changeset
226 req_path, page_num = split_sub_uri(app, request.path)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
227
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
228 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
229 if len(routes) == 0:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
230 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
231
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
232 taxonomy = None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
233 for route, route_metadata in routes:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
234 source = app.getSource(route.source_name)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
235 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
236 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
237 route_metadata, MODE_PARSING)
11
617191dec18e Fixes for Windows, make `findPagePath` return a ref path.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
238 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
239 break
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
240 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
241 taxonomy = app.getTaxonomy(route.taxonomy)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
242 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
243 if term_value is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
244 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
245 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
246 source = tax_page_ref.source
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
247 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
248 break
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
249 else:
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
250 raise SourceNotFoundError(
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
251 "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
252 (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
253
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
254 # Build the page.
11
617191dec18e Fixes for Windows, make `findPagePath` return a ref path.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
255 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
256 page = fac.buildPage()
174
e9a3d405e18f serve: Always force render the page being previewed.
Ludovic Chabant <ludovic@chabant.com>
parents: 173
diff changeset
257 # 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
258 # 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
259 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
260 force_render=True)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
261 if taxonomy is not None:
280
8c0c53a315ae data: Correctly build pagination filters when we know items are pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 279
diff changeset
262 flt = PaginationFilter(value_accessor=page_value_accessor)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
263 if taxonomy.is_multiple:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
264 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
265 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
266 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
267 render_ctx.pagination_filter = flt
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
268 render_ctx.custom_data = {
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
269 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
270
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
271 # 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
272 # 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
273 # 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
274 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
275 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
276 entry.used_source_names):
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
277 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
278 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
279
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
280 # Render the page.
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
281 rendered_page = render_page(render_ctx)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
282 rp_content = rendered_page.content
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
283
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
284 if taxonomy is not None:
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
285 paginator = rendered_page.data.get('pagination')
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
286 if (paginator and paginator.is_loaded and
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
287 len(paginator.items) == 0):
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
288 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
289 "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
290 "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
291 raise NotFound(message)
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
292
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
293 if entry is None:
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
294 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
295 self._page_record.addEntry(entry)
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
296 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
297
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
298 # Profiling.
279
980bbbd0705e serve: Correctly show timing info even when not in debug mode.
Ludovic Chabant <ludovic@chabant.com>
parents: 258
diff changeset
299 if app.config.get('site/show_debug_info'):
7
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
300 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
301 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
302 ((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
303 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
304 timing_info)
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
305
113
de257cc40ce1 Re-enable proper caching of rendered segments in server.
Ludovic Chabant <ludovic@chabant.com>
parents: 111
diff changeset
306 # Build the response.
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
307 response = Response()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
308
7
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
309 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
310 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
311 response.status_code = 304
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
312 return response
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
313
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
314 response.set_etag(etag)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
315 response.content_md5 = etag
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
316
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
317 cache_control = response.cache_control
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
318 if app.debug:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
319 cache_control.no_cache = True
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
320 cache_control.must_revalidate = True
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
321 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
322 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
323 app.config.get('site/cache_time'))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
324 if cache_time:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
325 cache_control.public = True
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
326 cache_control.max_age = cache_time
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
327
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
328 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
329 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
330 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
331 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
332 mimetype = content_type
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
333 if mimetype:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
334 response.mimetype = mimetype
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
335
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
336 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
337 app.config.get('site/enable_gzip')):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
338 try:
7
343d08ef5668 More PieCrust 3 fixes, and a couple of miscellaneous bug fixes.
Ludovic Chabant <ludovic@chabant.com>
parents: 5
diff changeset
339 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
340 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
341 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
342 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
343 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
344 response.content_encoding = 'gzip'
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
345 except Exception:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
346 logger.exception("Error compressing response, "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
347 "falling back to uncompressed.")
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
348 response.set_data(rp_content)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
349
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
350 return response
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
351
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
352 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
353 logger.debug("Serving %s" % path)
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
354
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
355 # 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
356 mtime = os.path.getmtime(path)
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
357 etag_str = '%s$$%s' % (path, mtime)
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
358 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
359 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
360 response = Response()
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
361 response.status_code = 304
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
362 return response
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
363
190
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
364 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
365 response = Response(wrapper)
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
366 _, ext = os.path.splitext(path)
258
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
367 response.set_etag(etag)
7ec06ec14247 serve: Use Etags and 304 responses for assets.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
368 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
369 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
370 ext.lstrip('.'), 'text/plain')
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
371 return response
430ee5b80962 serve: Make the server find assets generated by external tools.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
372
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
373 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
374 code = 500
128
28444014ce7d Fix error reporting and counting of lines.
Ludovic Chabant <ludovic@chabant.com>
parents: 113
diff changeset
375 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
376 code = exception.code
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
377
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
378 path = 'error'
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
379 if isinstance(exception, NotFound):
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
380 path += '404'
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 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
383
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
384 env = Environment(loader=ErrorMessageLoader())
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
385 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
386 context = {'details': descriptions}
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
387 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
388 response.status_code = code
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
389 return response(environ, start_response)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
390
229
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
391 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
392 desc = []
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
393 while exception is not None:
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
394 if isinstance(exception, HTTPException):
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
395 desc.append(exception.description)
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
396 else:
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
397 desc.append(str(exception))
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
398
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
399 inner_ex = exception.__cause__
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
400 if inner_ex is None:
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
401 inner_ex = exception.__context__
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
402 exception = inner_ex
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
403 return desc
a951cd4ef361 serve: Print nested exception messages in the dev server.
Ludovic Chabant <ludovic@chabant.com>
parents: 224
diff changeset
404
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
405
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
406 class RouteNotFoundError(Exception):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
407 pass
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
408
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 SourceNotFoundError(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 content_type_map = {
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
415 'html': 'text/html',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
416 'xml': 'text/xml',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
417 'txt': 'text/plain',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
418 'text': 'text/plain',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
419 'css': 'text/css',
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
420 'xhtml': 'application/xhtml+xml',
232
e534d2bc657c cosmetic: Fix PEP8 spacing.
Ludovic Chabant <ludovic@chabant.com>
parents: 231
diff changeset
421 'atom': 'application/atom+xml', # or 'text/xml'?
e534d2bc657c cosmetic: Fix PEP8 spacing.
Ludovic Chabant <ludovic@chabant.com>
parents: 231
diff changeset
422 '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
423 'json': 'application/json'}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
424
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
425
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
426 def find_routes(routes, uri):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
427 uri = uri.lstrip('/')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
428 res = []
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
429 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
430 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
431 if metadata is not None:
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
432 res.append((route, metadata))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
433 return res
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
434
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
435
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
436 class ErrorMessageLoader(FileSystemLoader):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
437 def __init__(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
438 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
439 'messages')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
440 super(ErrorMessageLoader, self).__init__(base_dir)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
441
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
442 def get_source(self, env, template):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
443 template += '.html'
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
444 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
445
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
446
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
447 def load_mimetype_map():
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
448 mimetype_map = {}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
449 sep_re = re.compile(r'\s+')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
450 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
451 with open(path, 'r') as f:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
452 for line in f:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
453 tokens = sep_re.split(line)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
454 if len(tokens) > 1:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
455 for t in tokens[1:]:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
456 mimetype_map[t] = tokens[0]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
457 return mimetype_map
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
458
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
459
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
460 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
461 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
462 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
463 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
464 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
465 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
466
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
467 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
468 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
469 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
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 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
472 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
473
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
474 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
475 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
476 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
477 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
478 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
479 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
480 break
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
481
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
482 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
483 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
484
219
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
485 try:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
486 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
487 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
488 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
489 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
490 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
491 continue
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 = {'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
493 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
494
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
495 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
496 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
497 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
498 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
499 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
500
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
501 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
502 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
503
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
504
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
505 class ProcessingLoop(threading.Thread):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
506 def __init__(self, pipeline):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
507 super(ProcessingLoop, self).__init__(
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
508 name='pipeline-reloader', daemon=True)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
509 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
510 self.status_queue = queue.Queue()
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
511 self.interval = 1
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
512 self._paths = set()
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
513 self._record = None
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
514 self._last_bake = 0
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
515
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
516 def run(self):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
517 # 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
518 app = self.pipeline.app
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
519 roots = [os.path.join(app.root_dir, r)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
520 for r in self.pipeline.mounts.keys()]
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
521 for root in roots:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
522 for dirpath, dirnames, filenames in os.walk(root):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
523 self._paths |= set([os.path.join(dirpath, f)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
524 for f in filenames])
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
525 self._last_bake = time.time()
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
526 self._record = self.pipeline.run(save_record=False)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
527
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
528 while True:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
529 for root in roots:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
530 # 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
531 # 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
532 # that mount.
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
533 found_new_or_modified = False
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
534 for dirpath, dirnames, filenames in os.walk(root):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
535 for filename in filenames:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
536 path = os.path.join(dirpath, filename)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
537 if path not in self._paths:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
538 logger.debug("Found new asset: %s" % path)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
539 self._paths.add(path)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
540 found_new_or_modified = True
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
541 break
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
542 if os.path.getmtime(path) > self._last_bake:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
543 logger.debug("Found modified asset: %s" % 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
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
547 if found_new_or_modified:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
548 break
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
549
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
550 if found_new_or_modified:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
551 self._runPipeline(root)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
552
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
553 time.sleep(self.interval)
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
554
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
555 def _runPipeline(self, root):
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
556 self._last_bake = time.time()
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
557 try:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
558 self._record = self.pipeline.run(
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
559 root,
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
560 previous_record=self._record,
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
561 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
562
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
563 # 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
564 # (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
565 # 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
566 # 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
567 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
568 try:
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
569 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
570 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
571 break
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
572
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
573 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
574 item = {
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
575 '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
576 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
577 else:
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_error',
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
580 'assets': []}
d7a548ebcd58 serve: Add server sent events for showing pipeline errors in the debug window.
Ludovic Chabant <ludovic@chabant.com>
parents: 214
diff changeset
581 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
582 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
583 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
584 '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
585 '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
586 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
587 self.status_queue.put_nowait(item)
209
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
588 except:
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
589 pass
7a5a7a7e8cee serve: Run the asset pipeline asynchronously.
Ludovic Chabant <ludovic@chabant.com>
parents: 205
diff changeset
590