Code

Added a Zope frontend for roundup.
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 12 Dec 2001 23:27:14 +0000 (23:27 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 12 Dec 2001 23:27:14 +0000 (23:27 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@458 57a73879-2fb5-44c3-a270-3262357dd7e2

CHANGES.txt
frontends/README.txt [new file with mode: 0644]
frontends/ZRoundup/ZRoundup.py [new file with mode: 0644]
frontends/ZRoundup/__init__.py [new file with mode: 0644]
frontends/ZRoundup/dtml/manage_addZRoundupForm.dtml [new file with mode: 0644]
frontends/ZRoundup/icons/tick_symbol.gif [new file with mode: 0644]
roundup/cgi_client.py

index dd83622290435d7892bad00e46e99a0d5ce4960d..027debad760555b2e2e4b225234cdcea07c8957a 100644 (file)
@@ -22,6 +22,7 @@ Feature:
  . Added the "display" command to the admin tool - displays a node's values
  . Message author's name appears in From: instead of roundup instance name
    (which still appears in the Reply-To:)
+ . Added a Zope frontend for roundup.
 
 Fixed:
  . Lots of bugs, thanks Roché and others on the devel mailing list!
diff --git a/frontends/README.txt b/frontends/README.txt
new file mode 100644 (file)
index 0000000..c202676
--- /dev/null
@@ -0,0 +1,9 @@
+This directory contains alternate front-ends for Roundup.
+
+Zope - ZRoundup
+---------------
+ Install roundup as usual (see INSTALL.txt in the directory above this one.)
+ Install as a regular product - copy the ZRoundup directory to your Products directory
+ either in an INSTANCE_HOME/Products or the Zope code tree lib/python/Products.
+
+
diff --git a/frontends/ZRoundup/ZRoundup.py b/frontends/ZRoundup/ZRoundup.py
new file mode 100644 (file)
index 0000000..354b8ad
--- /dev/null
@@ -0,0 +1,158 @@
+# Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+# 
+# $Id: ZRoundup.py,v 1.1 2001-12-12 23:27:13 richard Exp $
+#
+''' ZRoundup module - exposes the roundup web interface to Zope
+'''
+from Globals import InitializeClass, HTMLFile
+from OFS.SimpleItem import Item
+from OFS.PropertyManager import PropertyManager
+from Acquisition import Implicit
+from Persistence import Persistent
+from AccessControl import ClassSecurityInfo
+from AccessControl import ModuleSecurityInfo
+modulesecurity = ModuleSecurityInfo()
+
+import roundup.instance
+from roundup import cgi_client
+
+modulesecurity.declareProtected('View management screens', 'manage_addZRoundupForm')
+manage_addZRoundupForm = HTMLFile('dtml/manage_addZRoundupForm', globals())
+
+modulesecurity.declareProtected('Add Z Roundups', 'manage_addZRoundup')
+def manage_addZRoundup(self, id, instance_home, REQUEST):
+    """Add a ZRoundup product """
+    # validate the instance_home
+    roundup.instance.open(instance_home)
+    self._setObject(id, ZRoundup(id, instance_home))
+    return self.manage_main(self, REQUEST)
+
+class RequestWrapper:
+    '''Make the Zope RESPONSE look like a BaseHTTPServer
+    '''
+    def __init__(self, RESPONSE):
+        self.RESPONSE = RESPONSE
+        self.wfile = self.RESPONSE
+    def send_response(self, status):
+        self.RESPONSE.setStatus(status)
+    def send_header(self, header, value):
+        self.RESPONSE.addHeader(header, value)
+    def end_headers(self):
+        # not needed - the RESPONSE object handles this internally on write()
+        pass
+
+class FormItem:
+    '''Make a Zope form item look like a cgi.py one
+    '''
+    def __init__(self, value):
+        self.value = value
+        if hasattr(self.value, 'filename'):
+            self.filename = self.value.filename
+            self.file = self.value
+
+class FormWrapper:
+    '''Make a Zope form dict look like a cgi.py one
+    '''
+    def __init__(self, form):
+        self.form = form
+    def __getitem__(self, item):
+        return FormItem(self.form[item])
+    def has_key(self, item):
+        return self.form.has_key(item)
+    def keys(self):
+        return self.form.keys()
+
+class ZRoundup(Item, PropertyManager, Implicit, Persistent):
+    '''An instance of this class provides an interface between Zope and roundup for one
+       roundup instance
+    '''
+    meta_type =  'Z Roundup'
+    security = ClassSecurityInfo()
+
+    def __init__(self, id, instance_home):
+        self.id = id
+        self.instance_home = instance_home
+
+    # define the properties that define this object
+    _properties = (
+        {'id':'id', 'type': 'string', 'mode': 'w'},
+        {'id':'instance_home', 'type': 'string', 'mode': 'w'},
+    )
+    property_extensible_schema__ = 0
+
+    # define the tabs for the management interface
+    manage_options= PropertyManager.manage_options + (
+        {'label': 'View', 'action':'index_html'},
+    ) + Item.manage_options
+
+    icon = "misc_/ZRoundup/icon"
+
+    security.declarePrivate('_opendb')
+    def _opendb(self):
+        '''Open the roundup instnace database for a transaction
+        '''
+        instance = roundup.instance.open(self.instance_home)
+        request = RequestWrapper(self.REQUEST['RESPONSE'])
+        env = self.REQUEST.environ
+        env['INSTANCE_NAME'] = self.id
+        if env['REQUEST_METHOD'] == 'GET':
+            # force roundup to re-parse the request because Zope fiddles
+            # with it and we lose all the :filter, :columns, etc goodness
+            form = None
+        else:
+            form = FormWrapper(self.REQUEST.form)
+        return instance.Client(instance, request, env, form)
+
+    security.declareProtected('View', 'index_html')
+    def index_html(self):
+        '''Alias index_html to roundup's index
+        '''
+        client = self._opendb()
+        # fake the path that roundup should use
+        client.split_path = ['index']
+        return client.main()
+
+    def __getitem__(self, item):
+        '''All other URL accesses are passed throuh to roundup
+        '''
+        try:
+            client = self._opendb()
+            # fake the path that roundup should use
+            client.split_path = [item]
+            # and call roundup to do something 
+            client.main()
+            return ''
+        except cgi_client.NotFound:
+            raise 'NotFound', self.REQUEST.URL
+            pass
+        except:
+            import traceback
+            traceback.print_exc()
+            # all other exceptions in roundup are valid
+            raise
+        raise KeyError, item
+
+
+InitializeClass(ZRoundup)
+modulesecurity.apply(globals())
+
+
+#
+# $Log: not supported by cvs2svn $
+#
+#
+# vim: set filetype=python ts=4 sw=4 et si
diff --git a/frontends/ZRoundup/__init__.py b/frontends/ZRoundup/__init__.py
new file mode 100644 (file)
index 0000000..1cda208
--- /dev/null
@@ -0,0 +1,60 @@
+# Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+# 
+# $Id: __init__.py,v 1.1 2001-12-12 23:27:14 richard Exp $
+#
+__version__='1.0'
+
+import os
+# figure where ZRoundup is installed
+here = None
+if os.environ.has_key('INSTANCE_HOME'):
+    here = os.environ['INSTANCE_HOME']
+    path = os.path.join(here, 'Products', 'ZRoundup')
+    if not os.path.exists(path):
+        path = os.path.join(here, 'lib', 'python', 'Products', 'ZRoundup')
+        if not os.path.exists(path):
+            here = None
+if here is None:
+    from __main__ import here
+    path = os.path.join(here, 'Products', 'ZRoundup')
+    if not os.path.exists(path):
+        path = os.path.join(here, 'lib', 'python', 'Products', 'ZRoundup')
+        if not os.path.exists(path):
+            raise ValueError, "Can't determine where ZRoundup is installed"
+
+# product initialisation
+import ZRoundup
+def initialize(context):
+    context.registerClass(
+        ZRoundup, meta_type = 'Z Roundup',
+        constructors = (
+            ZRoundup.manage_addZRoundupForm, ZRoundup.manage_addZRoundup
+        )
+    )
+
+# set up the icon
+from ImageFile import ImageFile
+misc_ = {
+    'icon': ImageFile('icons/tick_symbol.gif', path), 
+}
+
+
+#
+# $Log: not supported by cvs2svn $
+#
+#
+# vim: set filetype=python ts=4 sw=4 et si
diff --git a/frontends/ZRoundup/dtml/manage_addZRoundupForm.dtml b/frontends/ZRoundup/dtml/manage_addZRoundupForm.dtml
new file mode 100644 (file)
index 0000000..a7a52ef
--- /dev/null
@@ -0,0 +1,5 @@
+<form action="manage_addZRoundup">
+ID: <input type="text" name="id"><br>
+Instance Home: <input type="text" name="instance_home"><br>
+<input type="submit">
+</form>
diff --git a/frontends/ZRoundup/icons/tick_symbol.gif b/frontends/ZRoundup/icons/tick_symbol.gif
new file mode 100644 (file)
index 0000000..c21ad1e
Binary files /dev/null and b/frontends/ZRoundup/icons/tick_symbol.gif differ
index 6fe8b288cede65e623c1c9d0baf8472655b55cd2..59b587b33aff973c225554a5cf5761a9796485bf 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: cgi_client.py,v 1.79 2001-12-10 22:20:01 richard Exp $
+# $Id: cgi_client.py,v 1.80 2001-12-12 23:27:14 richard Exp $
 
 __doc__ = """
 WWW request handler (also used in the stand-alone server).
@@ -60,14 +60,17 @@ class Client:
     ANONYMOUS_ACCESS = 'deny'        # one of 'deny', 'allow'
     ANONYMOUS_REGISTER = 'deny'      # one of 'deny', 'allow'
 
-    def __init__(self, instance, request, env):
+    def __init__(self, instance, request, env, form=None):
         self.instance = instance
         self.request = request
         self.env = env
         self.path = env['PATH_INFO']
         self.split_path = self.path.split('/')
 
-        self.form = cgi.FieldStorage(environ=env)
+        if form is None:
+            self.form = cgi.FieldStorage(environ=env)
+        else:
+            self.form = form
         self.headers_done = 0
         try:
             self.debug = int(env.get("ROUNDUP_DEBUG", 0))
@@ -1087,6 +1090,13 @@ def parsePropsFromForm(db, cl, form, nodeid=0):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.79  2001/12/10 22:20:01  richard
+# Enabled transaction support in the bsddb backend. It uses the anydbm code
+# where possible, only replacing methods where the db is opened (it uses the
+# btree opener specifically.)
+# Also cleaned up some change note generation.
+# Made the backends package work with pydoc too.
+#
 # Revision 1.78  2001/12/07 05:59:27  rochecompaan
 # Fixed small bug that prevented adding issues through the web.
 #