Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Side by Side Diff: tools/md_browser/md_browser.py

Issue 1356203004: Check in a simple pure-python based Markdown previewer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@add
Patch Set: patch for review Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« tools/md_browser/README.md ('K') | « tools/md_browser/header.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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:]))
OLDNEW
« tools/md_browser/README.md ('K') | « tools/md_browser/header.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698