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