changeset 0:196f241286f7

initial import of clwapp, from https://svn.openplans.org/svn/standalone/clwapp/trunk/
author k0s <k0scist@gmail.com>
date Sun, 01 Nov 2009 18:24:35 -0500
parents
children 2f45e6ae75fc
files clwapp.ini clwapp/__init__.py clwapp/clwapp.py clwapp/factory.py clwapp/utils.py setup.py
diffstat 6 files changed, 140 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/clwapp.ini
@@ -0,0 +1,22 @@
+#!/usr/bin/env paster
+
+[DEFAULT]
+debug = true
+email_to = jhammel@openplans.org
+smtp_server = localhost
+error_email_from = paste@localhost
+
+[server:main]
+use = egg:Paste#http
+host = 0.0.0.0
+port = 9999
+
+[composite:main]
+use = egg:Paste#urlmap
+/ = clwapp
+
+set debug = false
+
+[app:clwapp]
+paste.app_factory = clwapp.factory:factory
+clwapp.command = echo
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/clwapp/__init__.py
@@ -0,0 +1,1 @@
+#
new file mode 100644
--- /dev/null
+++ b/clwapp/clwapp.py
@@ -0,0 +1,65 @@
+"""
+clwapp: Command Line Web APP
+
+clwapp is configured with clwapp.command in paste's .ini file
+arguments are passed in the query string.  That is, if clwapp.command = ls,
+one could do http://localhost:9999/?-l&-a to pass the '-l' and '-a' arguments.
+
+DO NOT USE THIS (WITHOUT AUTH) WITH PROGRAMS THAT CAN ADVERSELY AFFECT THE
+SYSTEM OR EXPOSE SENSITIVE DATA!  subprocess.Popen is used, so that limit to
+the shell is restricted, but programs that can alter your system can be
+exploited.  clwapp works well with programs that display information (provided
+their access is restricted from secure information), and less well with
+programs that change the state of the server.
+*NEVER* use with Popen(shell=True) unless you are sure of your security.
+
+"""
+
+import subprocess
+import utils
+
+from webob import Request, Response, exc
+
+class View(object):
+
+    ### class level variables
+    defaults = {}
+
+    def __init__(self, command, **kw):
+        self.command = utils.shargs(command)
+        print self.command
+        for key in self.defaults:
+            setattr(self, key, kw.get(key, self.defaults[key]))
+        self.response_functions = { 'GET': self.get }
+
+    ### methods dealing with HTTP
+    def __call__(self, environ, start_response):
+        self.request = Request(environ)
+        res = self.make_response(self.request.method)
+        return res(environ, start_response)
+                                
+    def make_response(self, method):
+        return self.response_functions.get(method, self.error)()
+
+    def get_response(self, text, content_type='text/html'):
+        res = Response(content_type=content_type, body=text)
+        res.content_length = len(res.body)
+        return res
+
+    def get(self):
+        """
+        return response to a GET requst
+        """
+        args = self.command + self.request.GET.keys()
+        process = subprocess.Popen(args, stdout=subprocess.PIPE)
+        output = process.communicate()[0]
+        title = ' '.join(args)
+        return self.get_response("""<html><head><title>%s</title></head><body><pre>
+%s
+</pre></body></html>
+        """ % (title, output) )
+
+    def error(self):
+        """deal with non-supported methods"""
+        return exc.HTTPMethodNotAllowed("Only %r operations are allowed" % self.response_functions.keys())
+        
new file mode 100644
--- /dev/null
+++ b/clwapp/factory.py
@@ -0,0 +1,13 @@
+from clwapp import View
+from paste.httpexceptions import HTTPExceptionHandler
+
+def factory(global_conf, **app_conf):
+    """create a webob view and wrap it in middleware"""
+
+    config = [ 'command' ]
+    key_str = 'clwapp.%s'
+    args = dict([(key, app_conf[ key_str % key]) for key in config
+                 if app_conf.has_key(key_str % key) ])
+    app = View(**args)
+    return HTTPExceptionHandler(app)
+    
new file mode 100644
--- /dev/null
+++ b/clwapp/utils.py
@@ -0,0 +1,8 @@
+import subprocess
+
+def shargs(args):
+    process = subprocess.Popen('for arg in %s; do echo $arg; done' % args,
+                               shell=True, stdout=subprocess.PIPE)
+    output = process.communicate()[0]
+    output = output[:-1] # last line will be blank
+    return output.split('\n')
new file mode 100644
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,31 @@
+from setuptools import setup, find_packages
+import sys, os
+
+version = "0.0"
+
+setup(name='clwapp',
+      version=version,
+      description="Command Line Web APP",
+      long_description="""
+""",
+      classifiers=[], # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      author='Jeff Hammel',
+      author_email='jhammel@openplans.org',
+      url='',
+      license="",
+      packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=[
+          # -*- Extra requirements: -*-
+         'WebOb',	
+         'Paste',
+         'PasteScript',
+      ],
+      entry_points="""
+      # -*- Entry points: -*-
+      [paste.app_factory]
+      main = clwapp.factory:factory
+      """,
+      )
+