Mercurial > piecrust2
comparison foodtruck/pubutil.py @ 602:c6bc0ef03f82
admin: Better UI for publishing websites.
* Support multiple publish targets.
* Dedicated UI for publishing.
* Some UI polish.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 27 Jan 2016 18:02:25 -0800 |
parents | |
children | 978d8bca9fb3 |
comparison
equal
deleted
inserted
replaced
601:effbc78b5528 | 602:c6bc0ef03f82 |
---|---|
1 import os | |
2 import os.path | |
3 import time | |
4 import signal | |
5 import logging | |
6 from .web import app | |
7 | |
8 | |
9 logger = logging.getLogger(__name__) | |
10 | |
11 server_shutdown = False | |
12 | |
13 | |
14 def _shutdown_server_and_raise_sigint(): | |
15 if not app.debug or os.environ.get('WERKZEUG_RUN_MAIN') == 'true': | |
16 # This is needed when hitting CTRL+C to shutdown the Werkzeug server, | |
17 # otherwise SSE generators will keep it alive. | |
18 logger.debug("Shutting down SSE generators...") | |
19 global server_shutdown | |
20 server_shutdown = True | |
21 raise KeyboardInterrupt() | |
22 | |
23 | |
24 if app.config['FOODTRUCK_CMDLINE_MODE']: | |
25 # Make sure CTRL+C works correctly. | |
26 signal.signal(signal.SIGINT, | |
27 lambda *args: _shutdown_server_and_raise_sigint()) | |
28 | |
29 | |
30 class PublishLogReader(object): | |
31 _pub_max_time = 10 * 60 # Don't bother about pubs older than 10mins. | |
32 _poll_interval = 2 # Check the PID file every 2 seconds. | |
33 _ping_interval = 30 # Send a ping message every 30 seconds. | |
34 | |
35 def __init__(self, pid_path, log_path): | |
36 self.pid_path = pid_path | |
37 self.log_path = log_path | |
38 self._pub_pid_mtime = 0 | |
39 self._last_seek = 0 | |
40 self._last_ping_time = 0 | |
41 | |
42 def run(self): | |
43 logger.debug("Opening publish log...") | |
44 | |
45 try: | |
46 while not server_shutdown: | |
47 # PING! | |
48 interval = time.time() - self._last_ping_time | |
49 if interval > self._ping_interval: | |
50 logger.debug("Sending ping...") | |
51 self._last_ping_time = time.time() | |
52 yield bytes("event: ping\ndata: 1\n\n", 'utf8') | |
53 | |
54 # Check pid file. | |
55 prev_mtime = self._pub_pid_mtime | |
56 try: | |
57 self._pub_pid_mtime = os.path.getmtime(self.pid_path) | |
58 if time.time() - self._pub_pid_mtime > \ | |
59 self._pub_max_time: | |
60 self._pub_pid_mtime = 0 | |
61 except OSError: | |
62 self._pub_pid_mtime = 0 | |
63 | |
64 # Send data. | |
65 new_data = None | |
66 if self._pub_pid_mtime > 0 or prev_mtime > 0: | |
67 if self._last_seek == 0: | |
68 outstr = 'event: message\ndata: Publish started.\n\n' | |
69 yield bytes(outstr, 'utf8') | |
70 | |
71 try: | |
72 with open(self.log_path, 'r', encoding='utf8') as fp: | |
73 fp.seek(self._last_seek) | |
74 new_data = fp.read() | |
75 self._last_seek = fp.tell() | |
76 except OSError: | |
77 pass | |
78 if self._pub_pid_mtime == 0: | |
79 self._last_seek = 0 | |
80 | |
81 if new_data: | |
82 logger.debug("SSE: %s" % outstr) | |
83 for line in new_data.split('\n'): | |
84 outstr = 'event: message\ndata: %s\n\n' % line | |
85 yield bytes(outstr, 'utf8') | |
86 | |
87 time.sleep(self._poll_interval) | |
88 | |
89 except GeneratorExit: | |
90 pass | |
91 | |
92 logger.debug("Closing publish log...") | |
93 |