Mercurial > hg > decoupage
comparison decoupage/cli.py @ 85:3262010f7f79
add command line serving
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Sat, 28 Dec 2013 21:56:06 -0800 |
parents | 95820b36d7e3 |
children | a9f5b60006ba |
comparison
equal
deleted
inserted
replaced
84:95820b36d7e3 | 85:3262010f7f79 |
---|---|
8 If the directory is not specified, the current working directory is used | 8 If the directory is not specified, the current working directory is used |
9 """ | 9 """ |
10 | 10 |
11 import optparse | 11 import optparse |
12 import os | 12 import os |
13 import socket | |
13 import sys | 14 import sys |
14 | 15 |
16 from .formatters import Sort, Up | |
15 from .web import Decoupage | 17 from .web import Decoupage |
16 from wsgiref import simple_server | 18 from wsgiref import simple_server |
17 | 19 |
18 here = os.path.dirname(os.path.realpath(__file__)) | 20 here = os.path.dirname(os.path.realpath(__file__)) |
19 | 21 |
20 def DecoupageServer(object): | 22 class DecoupageServer(Decoupage): |
21 """serve locally with decoupage""" | 23 """serve locally with decoupage""" |
22 def __init__(self): | 24 # TODO: deprecate; move Decoupage to a few classes |
23 raise NotImplementedError("Do I need this?") | 25 # with more flexible formatters |
26 def __init__(self, *args, **kwargs): | |
27 Decoupage.__init__(self, **kwargs) | |
28 # default formatters | |
29 # TODO: make configurable | |
30 self._formatters = [Sort(), Up('..')] | |
31 def get_formatters(self, path): | |
32 return self._formatters | |
33 | |
24 | 34 |
25 def main(args=sys.argv[1:]): | 35 def main(args=sys.argv[1:]): |
26 | 36 |
27 # parse command line options | 37 # parse command line options |
28 usage = '%prog [options]' | 38 usage = '%prog [options]' |
29 parser = optparse.OptionParser(usage=usage, description=__doc__) | 39 parser = optparse.OptionParser(usage=usage, description=__doc__) |
30 parser.add_option('-p', '--port', dest='port', | 40 parser.add_option('-p', '--port', dest='port', |
31 type='int', default=1977, | 41 type='int', default=1977, |
32 help="port to serve on [DEFAULT: %default]") | 42 help="port to serve on [DEFAULT: %default]") |
43 parser.add_option('-a', '--address', dest='address', | |
44 default='0.0.0.0', | |
45 help="address to serve on [DEFAULT: %default]") | |
33 parser.add_option('--no-reload', dest='auto_reload', | 46 parser.add_option('--no-reload', dest='auto_reload', |
34 action='store_false', default=True, | 47 action='store_false', default=True, |
35 help="do not dynamically refresh indices") | 48 help="do not dynamically refresh indices") |
49 parser.add_option('--no-print-ip', dest='print_ip', | |
50 action='store_false', default=True, | |
51 help="do not print resolvable IP address") | |
36 options, args = parser.parse_args(args) | 52 options, args = parser.parse_args(args) |
37 if not args: | 53 if not args: |
38 directory = os.getcwd() | 54 directory = os.getcwd() |
39 elif len(args) == 1: | 55 elif len(args) == 1: |
40 directory = args[0] | 56 directory = args[0] |
45 # This may be done by creating a temporary directory with appropriate | 61 # This may be done by creating a temporary directory with appropriate |
46 # symbolic links (on OSes that allow them) | 62 # symbolic links (on OSes that allow them) |
47 | 63 |
48 parser.print_help() | 64 parser.print_help() |
49 parser.exit(1) | 65 parser.exit(1) |
66 if not os.path.isdir(directory): | |
67 raise OSError("'%s' is not a directory" % directory) | |
50 | 68 |
51 if not os.path.isdir(directory): | 69 # create WSGI app |
52 raise ("'%s' is not a directory" % directory) | |
53 | |
54 # TODO: | 70 # TODO: |
55 # - allow CLI specification of formatters | 71 # - allow CLI specification of formatters |
56 # - template specification | 72 # - template specification |
57 | 73 app = DecoupageServer(directory=directory, |
58 # create WSGI app | 74 auto_reload=options.auto_reload) |
59 app = Decoupage(directory=directory, | |
60 auto_reload=options.auto_reload) | |
61 | 75 |
62 | 76 |
63 # create server | 77 # create server |
64 # TODO: allow choice amongst server classes | 78 # TODO: allow choice amongst server classes |
65 address = '127.0.0.1' | 79 printable_address = '127.0.0.1' if options.address == '0.0.0.0' else options.address |
66 server = simple_server.make_server(address, options.port, app) | 80 server = simple_server.make_server(options.address, options.port, app) |
67 print 'serving directory %s ( %s ) at \nhttp://%s:%d/' % (directory, | 81 print 'serving directory %s ( %s ) at \nhttp://%s:%d/' % (directory, |
68 'file://' + directory, # XXX | 82 'file://' + directory, # XXX |
69 address, | 83 printable_address, |
70 options.port) | 84 options.port) |
85 if options.print_ip: | |
86 # from http://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib | |
87 hostname = "google.com" | |
88 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
89 s.connect((hostname,80)) | |
90 hostname = s.getsockname()[0] | |
91 print "http://%s:%s/" % (hostname, options.port) | |
92 s.close() | |
71 | 93 |
94 # serve directory contents via decoupage | |
72 try: | 95 try: |
73 server.serve_forever() | 96 server.serve_forever() |
74 except KeyboardInterrupt: | 97 except KeyboardInterrupt: |
75 pass | 98 pass |
76 | 99 |