summaryrefslogtreecommitdiff
path: root/tools/scan-view/scan-view
blob: fb27da698882e7447906a24f70e99fcc627f1d57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python

"""The clang static analyzer results viewer.
"""

import sys
import posixpath
import thread
import time
import urllib
import webbrowser

# How long to wait for server to start.
kSleepTimeout = .05
kMaxSleeps = int(60 / kSleepTimeout)

# Default server parameters

kDefaultHost = '127.0.0.1'
kDefaultPort = 8181
kMaxPortsToTry = 100

###

def url_is_up(url):
    try:
        o = urllib.urlopen(url)
    except IOError:
        return False
    o.close()
    return True

def start_browser(port, options):
    import urllib, webbrowser

    url = 'http://%s:%d'%(options.host, port)
    
    # Wait for server to start...
    if options.debug:
        sys.stderr.write('%s: Waiting for server.' % sys.argv[0])
        sys.stderr.flush()
    for i in range(kMaxSleeps):
        if url_is_up(url):
            break
        if options.debug:
            sys.stderr.write('.')
            sys.stderr.flush()
        time.sleep(kSleepTimeout)
    else:
        print >>sys.stderr,'WARNING: Unable to detect that server started.'

    if options.debug:
        print >>sys.stderr,'%s: Starting webbrowser...' % sys.argv[0]
    webbrowser.open(url)

def run(port, options, root):
    import ScanView
    try:
        print 'Starting scan-view at: http://%s:%d'%(options.host,
                                                     port)
        print '  Use Ctrl-C to exit.'
        httpd = ScanView.create_server((options.host, port),
                                       options, root)
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass

def port_is_open(port):
    import SocketServer
    try:
        t = SocketServer.TCPServer((kDefaultHost,port),None)
    except:
        return False
    t.server_close()
    return True

def main():    
    from optparse import OptionParser
    parser = OptionParser('usage: %prog [options] <results directory>')
    parser.set_description(__doc__)
    parser.add_option(
        '--host', dest="host", default=kDefaultHost, type="string",
        help="Host interface to listen on. (default=%s)" % kDefaultHost)
    parser.add_option(
        '--port', dest="port", default=None, type="int",
        help="Port to listen on. (default=%s)" % kDefaultPort)
    parser.add_option("--debug", dest="debug", default=0, 
                      action="count",
                      help="Print additional debugging information.")
    parser.add_option("--auto-reload", dest="autoReload", default=False, 
                      action="store_true",
                      help="Automatically update module for each request.")
    parser.add_option("--no-browser", dest="startBrowser", default=True, 
                      action="store_false",
                      help="Don't open a webbrowser on startup.")
    parser.add_option("--allow-all-hosts", dest="onlyServeLocal", default=True, 
                      action="store_false",
                      help='Allow connections from any host (access restricted to "127.0.0.1" by default)')
    (options, args) = parser.parse_args()

    if len(args) != 1:
        parser.error('No results directory specified.')
    root, = args

    # Make sure this directory is in a reasonable state to view.
    if not posixpath.exists(posixpath.join(root,'index.html')):
        parser.error('Invalid directory, analysis results not found!')

    # Find an open port. We aren't particularly worried about race
    # conditions here. Note that if the user specified a port we only
    # use that one.
    if options.port is not None:
        port = options.port
    else:    
        for i in range(kMaxPortsToTry):
            if port_is_open(kDefaultPort + i):
                port = kDefaultPort + i
                break
        else:
            parser.error('Unable to find usable port in [%d,%d)'%(kDefaultPort,
                                                                  kDefaultPort+kMaxPortsToTry))

    # Kick off thread to wait for server and start web browser, if
    # requested.
    if options.startBrowser:
        t = thread.start_new_thread(start_browser, (port,options))

    run(port, options, root)

if __name__ == '__main__':
    main()