# HG changeset patch # User Jeff Hammel # Date 1388283136 28800 # Node ID 95820b36d7e3352bb32e9d1d021354fc30bd3e6f # Parent 78139c3cecfad90683fe90896e6093ff3399562b cli client diff -r 78139c3cecfa -r 95820b36d7e3 decoupage/cli.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/decoupage/cli.py Sat Dec 28 18:12:16 2013 -0800 @@ -0,0 +1,78 @@ +#!/usr/bin/env python + +""" +serve directory with decoupage, e.g. + +``decoupage --port 8080 /home/jhammel/tmp`` + +If the directory is not specified, the current working directory is used +""" + +import optparse +import os +import sys + +from .web import Decoupage +from wsgiref import simple_server + +here = os.path.dirname(os.path.realpath(__file__)) + +def DecoupageServer(object): + """serve locally with decoupage""" + def __init__(self): + raise NotImplementedError("Do I need this?") + +def main(args=sys.argv[1:]): + + # parse command line options + usage = '%prog [options]' + parser = optparse.OptionParser(usage=usage, description=__doc__) + parser.add_option('-p', '--port', dest='port', + type='int', default=1977, + help="port to serve on [DEFAULT: %default]") + parser.add_option('--no-reload', dest='auto_reload', + action='store_false', default=True, + help="do not dynamically refresh indices") + options, args = parser.parse_args(args) + if not args: + directory = os.getcwd() + elif len(args) == 1: + directory = args[0] + if len(args) > 1: + # TODO: + # allow multiple directories with mount points + # e.g. `decoupage [options] directory [directory2=/foo] [...]` + # This may be done by creating a temporary directory with appropriate + # symbolic links (on OSes that allow them) + + parser.print_help() + parser.exit(1) + + if not os.path.isdir(directory): + raise ("'%s' is not a directory" % directory) + + # TODO: + # - allow CLI specification of formatters + # - template specification + + # create WSGI app + app = Decoupage(directory=directory, + auto_reload=options.auto_reload) + + + # create server + # TODO: allow choice amongst server classes + address = '127.0.0.1' + server = simple_server.make_server(address, options.port, app) + print 'serving directory %s ( %s ) at \nhttp://%s:%d/' % (directory, + 'file://' + directory, # XXX + address, + options.port) + + try: + server.serve_forever() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main() diff -r 78139c3cecfa -r 95820b36d7e3 decoupage/web.py --- a/decoupage/web.py Sun Dec 15 12:38:24 2013 -0800 +++ b/decoupage/web.py Sat Dec 28 18:12:16 2013 -0800 @@ -30,13 +30,15 @@ transformers = transformers() +string = (str, unicode) + class Decoupage(object): ### class level variables - defaults = { 'auto_reload': 'False', + defaults = { 'auto_reload': False, 'configuration': None, 'directory': None, # directory to serve - 'cascade': 'True', # whether to cascade configuration + 'cascade': True, # whether to cascade configuration 'template': 'index.html', # XXX see below 'template_directories': '', # list of directories to look for templates 'charset': 'utf-8', # content encoding for index.html files; -> `Content-Type: text/html; charset=ISO-8859-1` @@ -45,13 +47,21 @@ def __init__(self, **kw): # set defaults from app configuration - for key in self.defaults: - setattr(self, key, kw.get(key, self.defaults[key])) + for key, default_value in self.defaults.items(): + + value = kw.get(key, default_value) + + # handle non-string bools + if isinstance(default_value, bool) and isinstance(value, string): + value = {'true': True, + 'false': False}[value.lower()] + # TODO: error handling for bad strings + + setattr(self, key, value) + # configure defaults assert self.directory, "Decoupage: directory not specified" - self.auto_reload = self.auto_reload.lower() == 'true' - self.cascade = self.cascade.lower() == 'true' self.directory = self.directory.rstrip(os.path.sep) assert os.path.isdir(self.directory), "'%s' is not a directory" % self.directory self.template_directories = self.template_directories.split() # no spaces in directory names, for now diff -r 78139c3cecfa -r 95820b36d7e3 setup.py --- a/setup.py Sun Dec 15 12:38:24 2013 -0800 +++ b/setup.py Sat Dec 28 18:12:16 2013 -0800 @@ -36,6 +36,7 @@ [console_scripts] decoupage-templates = decoupage.templates:main decoupage-formatters = decoupage.formatters:main + decoupage = decoupage.cli:main [paste.app_factory] main = decoupage.factory:factory