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

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

Issue 1952533002: Generalize md_browser to work on other repos (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update toplevel doc Created 4 years, 7 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
« no previous file with comments | « docs/README.md ('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
1 #!/usr/bin/env python
1 # Copyright 2015 The Chromium Authors. All rights reserved. 2 # 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 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 4 # found in the LICENSE file.
4 5
5 """Simple Markdown browser for a Git checkout.""" 6 """Simple Markdown browser for a Git checkout."""
6 from __future__ import print_function 7 from __future__ import print_function
7 8
8 import SimpleHTTPServer 9 import SimpleHTTPServer
9 import SocketServer 10 import SocketServer
10 import argparse 11 import argparse
11 import codecs 12 import codecs
12 import os 13 import os
13 import re 14 import re
14 import socket 15 import socket
15 import sys 16 import sys
16 17
17 18
18 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) 19 THIS_DIR = os.path.abspath(os.path.dirname(__file__))
19 SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR)) 20 SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR))
20 sys.path.append(os.path.join(SRC_DIR, 'third_party', 'Python-Markdown')) 21 sys.path.append(os.path.join(SRC_DIR, 'third_party', 'Python-Markdown'))
21 import markdown 22 import markdown
22 23
23 24
24 def main(argv): 25 def main(argv):
25 parser = argparse.ArgumentParser(prog='md_browser') 26 parser = argparse.ArgumentParser(prog='md_browser')
26 parser.add_argument('-p', '--port', type=int, default=8080, 27 parser.add_argument('-p', '--port', type=int, default=8080,
27 help='port to run on (default = %(default)s)') 28 help='port to run on (default = %(default)s)')
29 parser.add_argument('-d', '--directory', type=str, default=SRC_DIR)
28 args = parser.parse_args(argv) 30 args = parser.parse_args(argv)
29 31
30 try: 32 try:
31 s = Server(args.port, SRC_DIR) 33 s = Server(args.port, args.directory)
32 print("Listening on http://localhost:%s/" % args.port) 34 print("Listening on http://localhost:%s/" % args.port)
33 print(" Try loading http://localhost:%s/docs/README.md" % args.port) 35 if os.path.isfile(os.path.join(args.directory, 'docs', 'README.md')):
36 print(" Try loading http://localhost:%s/docs/README.md" % args.port)
37 elif os.path.isfile(os.path.join(args.directory, 'README.md')):
38 print(" Try loading http://localhost:%s/README.md" % args.port)
34 s.serve_forever() 39 s.serve_forever()
35 s.shutdown() 40 s.shutdown()
36 return 0 41 return 0
37 except KeyboardInterrupt: 42 except KeyboardInterrupt:
38 return 130 43 return 130
39 44
40 45
41 def _gitiles_slugify(value, _separator): 46 def _gitiles_slugify(value, _separator):
42 """Convert a string (representing a section title) to URL anchor name. 47 """Convert a string (representing a section title) to URL anchor name.
43 48
(...skipping 20 matching lines...) Expand all
64 value = re.sub(r'[^- a-zA-Z0-9]', '_', value) # Non-alphanumerics to '_'. 69 value = re.sub(r'[^- a-zA-Z0-9]', '_', value) # Non-alphanumerics to '_'.
65 value = value.replace(u' ', u'-') 70 value = value.replace(u' ', u'-')
66 value = re.sub(r'([-_])[-_]+', r'\1', value) # Fold hyphens and underscores. 71 value = re.sub(r'([-_])[-_]+', r'\1', value) # Fold hyphens and underscores.
67 return value 72 return value
68 73
69 74
70 class Server(SocketServer.TCPServer): 75 class Server(SocketServer.TCPServer):
71 def __init__(self, port, top_level): 76 def __init__(self, port, top_level):
72 SocketServer.TCPServer.__init__(self, ('0.0.0.0', port), Handler) 77 SocketServer.TCPServer.__init__(self, ('0.0.0.0', port), Handler)
73 self.port = port 78 self.port = port
74 self.top_level = top_level 79 self.top_level = os.path.abspath(top_level)
75 80
76 def server_bind(self): 81 def server_bind(self):
77 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 82 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
78 self.socket.bind(self.server_address) 83 self.socket.bind(self.server_address)
79 84
80 85
81 class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): 86 class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
82 def do_GET(self): 87 def do_GET(self):
83 path = self.path 88 path = self.path
84 89
85 # strip off the repo and branch info, if present, for compatibility 90 # strip off the repo and branch info, if present, for compatibility
86 # with gitiles. 91 # with gitiles.
87 if path.startswith('/chromium/src/+/master'): 92 if path.startswith('/chromium/src/+/master'):
88 path = path[len('/chromium/src/+/master'):] 93 path = path[len('/chromium/src/+/master'):]
89 94
90 full_path = os.path.abspath(os.path.join(self.server.top_level, path[1:])) 95 full_path = os.path.abspath(os.path.join(self.server.top_level, path[1:]))
91 96
92 if not full_path.startswith(SRC_DIR): 97 if not full_path.startswith(self.server.top_level):
93 self._DoUnknown() 98 self._DoUnknown()
94 elif path == '/doc.css': 99 elif path == '/doc.css':
95 self._DoCSS('doc.css') 100 self._DoCSS('doc.css')
96 elif not os.path.exists(full_path): 101 elif not os.path.exists(full_path):
97 self._DoNotFound() 102 self._DoNotFound()
98 elif path.lower().endswith('.md'): 103 elif path.lower().endswith('.md'):
99 self._DoMD(path) 104 self._DoMD(path)
100 elif os.path.exists(full_path + '/README.md'): 105 elif os.path.exists(full_path + '/README.md'):
101 self._DoMD(path + '/README.md') 106 self._DoMD(path + '/README.md')
102 else: 107 else:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 140
136 def _DoNotFound(self): 141 def _DoNotFound(self):
137 self._WriteHeader('text/html') 142 self._WriteHeader('text/html')
138 self.wfile.write('<html><body>%s not found</body></html>' % self.path) 143 self.wfile.write('<html><body>%s not found</body></html>' % self.path)
139 144
140 def _DoUnknown(self): 145 def _DoUnknown(self):
141 self._WriteHeader('text/html') 146 self._WriteHeader('text/html')
142 self.wfile.write('<html><body>I do not know how to serve %s.</body>' 147 self.wfile.write('<html><body>I do not know how to serve %s.</body>'
143 '</html>' % self.path) 148 '</html>' % self.path)
144 149
145 def _Read(self, relpath): 150 def _Read(self, relpath, relative_to=None):
151 if relative_to is None:
152 relative_to = self.server.top_level
Dirk Pranke 2016/05/10 20:35:35 nit: it'd be a bit more idiomatic (and one less li
agable 2016/05/11 00:26:25 That disallows passing "relative_to=''", which wou
Dirk Pranke 2016/05/11 00:32:55 Hm. That seems like something I wouldn't want to s
146 assert not relpath.startswith(os.sep) 153 assert not relpath.startswith(os.sep)
147 path = os.path.join(self.server.top_level, relpath) 154 path = os.path.join(relative_to, relpath)
148 with codecs.open(path, encoding='utf-8') as fp: 155 with codecs.open(path, encoding='utf-8') as fp:
149 return fp.read() 156 return fp.read()
150 157
151 def _WriteHeader(self, content_type='text/plain'): 158 def _WriteHeader(self, content_type='text/plain'):
152 self.send_response(200) 159 self.send_response(200)
153 self.send_header('Content-Type', content_type) 160 self.send_header('Content-Type', content_type)
154 self.end_headers() 161 self.end_headers()
155 162
156 def _WriteTemplate(self, template): 163 def _WriteTemplate(self, template):
157 contents = self._Read(os.path.join('tools', 'md_browser', template)) 164 contents = self._Read(os.path.join('tools', 'md_browser', template),
165 relative_to=SRC_DIR)
158 self.wfile.write(contents.encode('utf-8')) 166 self.wfile.write(contents.encode('utf-8'))
159 167
160 168
161 if __name__ == '__main__': 169 if __name__ == '__main__':
162 sys.exit(main(sys.argv[1:])) 170 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « docs/README.md ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698