Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """Simple Markdown browser for a Git checkout.""" | |
| 6 | |
| 7 import SimpleHTTPServer | |
| 8 import SocketServer | |
| 9 import argparse | |
| 10 import codecs | |
| 11 import os | |
| 12 import socket | |
| 13 import sys | |
| 14 | |
| 15 | |
| 16 SRC_DIR = os.path.dirname(os.path.dirname( | |
| 17 os.path.dirname(os.path.abspath(__file__)))) | |
| 18 sys.path.append(os.path.join(SRC_DIR, 'third_party', 'Python-Markdown')) | |
| 19 import markdown | |
| 20 | |
| 21 | |
| 22 def main(argv): | |
| 23 parser = argparse.ArgumentParser(prog='md_browser') | |
|
scottmg
2015/09/22 04:58:01
+4 like an animal! :)
Dirk Pranke
2015/09/22 21:16:27
will fix. stupid chromium coding standards :).
| |
| 24 parser.add_argument('-p', '--port', type=int, default=8080, | |
| 25 help='port to run on (default = %(default)s)') | |
| 26 args = parser.parse_args(argv) | |
| 27 | |
| 28 try: | |
| 29 s = Server(args.port, SRC_DIR) | |
| 30 s.serve_forever() | |
| 31 s.shutdown() | |
| 32 return 0 | |
| 33 except KeyboardInterrupt: | |
| 34 return 130 | |
| 35 | |
| 36 | |
| 37 class Server(SocketServer.TCPServer): | |
| 38 def __init__(self, port, top_level): | |
| 39 SocketServer.TCPServer.__init__(self, ('0.0.0.0', port), Handler) | |
| 40 self.port = port | |
| 41 self.top_level = top_level | |
| 42 | |
| 43 def server_bind(self): | |
| 44 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
| 45 self.socket.bind(self.server_address) | |
| 46 | |
| 47 | |
| 48 class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): | |
| 49 def do_GET(self): | |
| 50 full_path = os.path.abspath(os.path.join(self.server.top_level, | |
| 51 self.path[1:])) | |
|
scottmg
2015/09/22 04:58:01
I guess it doesn't matter for this usage, but you
nodir
2015/09/22 16:38:18
os.path.abspath returns a normalized path, so the
scottmg
2015/09/22 17:32:46
(I meant that by entering localhost:8080/../../../
Dirk Pranke
2015/09/22 21:16:27
Right, but Nodir's saying (correctly, I believe) t
scottmg
2015/09/22 21:26:39
Oh, you're right. Sorry.
| |
| 52 if not full_path.startswith(self.server.top_level): | |
| 53 self._do_unknown() | |
| 54 elif self.path == '/doc.css': | |
| 55 self._write_file('doc.css') | |
| 56 elif not os.path.exists(full_path): | |
| 57 self._do_not_found() | |
| 58 elif self.path.endswith('.md'): | |
|
nodir
2015/09/22 16:38:18
self.path.lower()... JIC
Dirk Pranke
2015/09/22 21:16:27
Done, though I worry about what other sorts of wei
| |
| 59 self._do_md() | |
| 60 else: | |
| 61 self._do_unknown() | |
| 62 | |
| 63 def _do_md(self): | |
| 64 extensions = [ | |
| 65 'markdown.extensions.fenced_code', | |
| 66 'markdown.extensions.tables', | |
| 67 'markdown.extensions.toc', | |
| 68 ] | |
| 69 | |
| 70 contents = self._read(self.path[1:]) | |
|
scottmg
2015/09/22 04:58:01
it seems like this is already stripping the leadin
Dirk Pranke
2015/09/22 21:16:27
Made things more consistent.
| |
| 71 md_fragment = markdown.markdown(contents, | |
| 72 extensions=extensions, | |
| 73 output_format='html4').encode('utf-8') | |
| 74 try: | |
| 75 self._write_file('header.html') | |
| 76 self.wfile.write(md_fragment) | |
| 77 self._write_file('footer.html') | |
| 78 except: | |
| 79 raise | |
| 80 | |
| 81 def _do_not_found(self): | |
| 82 self.wfile.write('<html><body>%s not found</body></html>' % self.path) | |
| 83 | |
| 84 def _do_unknown(self): | |
| 85 self.wfile.write('<html><body>I do not know how to serve %s.</body>' | |
| 86 '</html>' % self.path) | |
| 87 | |
| 88 def _read(self, path): | |
| 89 if not path.startswith('/'): | |
|
nodir
2015/09/22 16:38:18
this if is unnecessary: os.path.join('/foo', '/bar
Dirk Pranke
2015/09/22 21:16:27
true, but the code was confusing regardless. Made
| |
| 90 path = os.path.join(self.server.top_level, path) | |
| 91 return codecs.open(path, mode='r', encoding='utf-8').read() | |
|
nodir
2015/09/22 16:38:18
mode='r' is unnecessary, it is default
nodir
2015/09/22 16:38:18
This seems to leave the fd open?
Shouldn't you
wi
Dirk Pranke
2015/09/22 21:16:27
Done, and good catch on the fd.
| |
| 92 | |
| 93 def _write_file(self, path): | |
| 94 assert os.sep not in path | |
| 95 contents = self._read(os.path.join(SRC_DIR, 'tools', 'md_browser', | |
|
nodir
2015/09/22 16:38:18
nit: I think moving the line break to the position
Dirk Pranke
2015/09/22 21:16:27
Once I switch to 2-space indents the whole thing f
| |
| 96 path)) | |
| 97 self.wfile.write(contents.encode('utf-8')) | |
| 98 | |
| 99 | |
| 100 if __name__ == '__main__': | |
| 101 sys.exit(main(sys.argv[1:])) | |
| OLD | NEW |