Code

Fix issue2550493: hide 'hidden' files.
[roundup.git] / frontends / ZRoundup / ZRoundup.py
index 0be45f38af4c7934432921d4c75ac0d2038b1691..e2a7d4b826475d92013bd71133bba8e63d007270 100644 (file)
@@ -14,7 +14,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: ZRoundup.py,v 1.10 2002-09-04 02:05:19 richard Exp $
+# $Id: ZRoundup.py,v 1.23 2008-02-07 01:03:39 richard Exp $
 #
 ''' ZRoundup module - exposes the roundup web interface to Zope
 
@@ -26,11 +26,6 @@ This means that the regular CGI interface does all authentication quite
 independently of Zope. The roundup code is kept in memory though, and it
 runs in the same server as all your other Zope stuff, so it does have _some_
 advantages over regular CGI :)
-
-It also means that any requests which specify :filter, :columns or :sort
-_must_ be done using a GET, so that this interface can re-parse the
-QUERY_STRING. Zope interprets the ':' as a special character, and the special
-args are lost to it.
 '''
 
 import urlparse
@@ -38,14 +33,14 @@ import urlparse
 from Globals import InitializeClass, HTMLFile
 from OFS.SimpleItem import Item
 from OFS.PropertyManager import PropertyManager
-from Acquisition import Implicit
+from Acquisition import Explicit, Implicit
 from Persistence import Persistent
 from AccessControl import ClassSecurityInfo
 from AccessControl import ModuleSecurityInfo
 modulesecurity = ModuleSecurityInfo()
 
 import roundup.instance
-from roundup.cgi import NotFound
+from roundup.cgi import client
 
 modulesecurity.declareProtected('View management screens',
     'manage_addZRoundupForm')
@@ -72,6 +67,11 @@ class RequestWrapper:
     def end_headers(self):
         # not needed - the RESPONSE object handles this internally on write()
         pass
+    def start_response(self, headers, response):
+        self.send_response(response)
+        for key, value in headers:
+            self.send_header(key, value)
+        self.end_headers()
 
 class FormItem:
     '''Make a Zope form item look like a cgi.py one
@@ -80,19 +80,34 @@ class FormItem:
         self.value = value
         if hasattr(self.value, 'filename'):
             self.filename = self.value.filename
-            self.file = self.value
+            self.value = self.value.read()
 
 class FormWrapper:
     '''Make a Zope form dict look like a cgi.py one
     '''
     def __init__(self, form):
-        self.form = form
+        self.__form = form
     def __getitem__(self, item):
-        return FormItem(self.form[item])
+        entry = self.__form[item]
+        if isinstance(entry, type([])):
+            entry = map(FormItem, entry)
+        else:
+            entry = FormItem(entry)
+        return entry
+    def __iter__(self):
+        return iter(self.__form)
+    def getvalue(self, key, default=None):
+        if self.__form.has_key(key):
+            return self.__form[key]
+        else:
+            return default
     def has_key(self, item):
-        return self.form.has_key(item)
+        return self.__form.has_key(item)
     def keys(self):
-        return self.form.keys()
+        return self.__form.keys()
+
+    def __repr__(self):
+        return '<ZRoundup.FormWrapper %r>'%self.__form
 
 class ZRoundup(Item, PropertyManager, Implicit, Persistent):
     '''An instance of this class provides an interface between Zope and
@@ -119,11 +134,11 @@ class ZRoundup(Item, PropertyManager, Implicit, Persistent):
 
     icon = "misc_/ZRoundup/icon"
 
-    security.declarePrivate('_opendb')
-    def _opendb(self):
+    security.declarePrivate('roundup_opendb')
+    def roundup_opendb(self):
         '''Open the roundup instance database for a transaction.
         '''
-        instance = roundup.instance.open(self.instance_home)
+        tracker = roundup.instance.open(self.instance_home)
         request = RequestWrapper(self.REQUEST['RESPONSE'])
         env = self.REQUEST.environ
 
@@ -131,41 +146,29 @@ class ZRoundup(Item, PropertyManager, Implicit, Persistent):
         url = urlparse.urlparse( self.absolute_url() )
         path = url[2]
         path_components = path.split( '/' )
-                                                
+
         # special case when roundup is '/' in this virtual host,
         if path == "/" :
             env['SCRIPT_NAME'] = "/"
-            env['INSTANCE_NAME'] = ''
+            env['TRACKER_NAME'] = ''
         else :
             # all but the last element is the path
             env['SCRIPT_NAME'] = '/'.join( path_components[:-1] )
             # the last element is the name
-            env['INSTANCE_NAME'] = path_components[-1]
-
-        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:
-            # For some reason, CRs are embeded in multiline notes.
-            # It doesn't occur with apache/roundup.cgi, though.
-            form = self.REQUEST.form 
-            if form.has_key( '__note' ) :
-                form['__note'] = form['__note'].replace( '\r' , '' )
-            form = FormWrapper(form)
-
-        return instance.Client(instance, request, env, form)
+            env['TRACKER_NAME'] = path_components[-1]
 
+        form = FormWrapper(self.REQUEST.form)
+        if hasattr(tracker, 'Client'):
+            return tracker.Client(tracker, request, env, form)
+        return client.Client(tracker, request, env, form)
 
     security.declareProtected('View', 'index_html')
     def index_html(self):
         '''Alias index_html to roundup's index
         '''
-
         # Redirect misdirected requests -- bugs 558867 , 565992
-       
         # PATH_INFO, as defined by the CGI spec, has the *real* request path
-        orig_path = self.REQUEST.environ[ 'PATH_INFO' ]
+        orig_path = self.REQUEST.environ['PATH_INFO']
         if orig_path[-1] != '/' : 
             url = urlparse.urlparse( self.absolute_url() )
             url = list( url ) # make mutable
@@ -176,7 +179,7 @@ class ZRoundup(Item, PropertyManager, Implicit, Persistent):
             RESPONSE.setHeader( "Location" , url )
             return RESPONSE
 
-        client = self._opendb()
+        client = self.roundup_opendb()
         # fake the path that roundup should use
         client.split_path = ['index']
         return client.main()
@@ -184,58 +187,39 @@ class ZRoundup(Item, PropertyManager, Implicit, Persistent):
     def __getitem__(self, item):
         '''All other URL accesses are passed throuh to roundup
         '''
+        return PathElement(self, item).__of__(self)
+
+class PathElement(Item, Implicit):
+    def __init__(self, zr, path):
+        self.zr = zr
+        self.path = path
+
+    def __getitem__(self, item):
+        ''' Get a subitem.
+        '''
+        return PathElement(self.zr, self.path + '/' + item).__of__(self)
+
+    def index_html(self, REQUEST=None):
+        ''' Actually call through to roundup to handle the request.
+        '''
         try:
-            client = self._opendb()
+            client = self.zr.roundup_opendb()
             # fake the path that roundup should use
-            client.split_path = [item]
+            client.path = self.path
             # and call roundup to do something 
             client.main()
             return ''
-        except NotFound:
-            raise 'NotFound', self.REQUEST.URL
+        except client.NotFound:
+            raise 'NotFound', 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 $
-# Revision 1.9  2002/07/04 01:25:22  dman13
-# fixed #576086 (dumb copying mistake)
-#
-# Revision 1.8  2002/06/16 01:01:42  dman13
-# remove CR characters embedded in messages (ZRoundup)
-#
-# Revision 1.7  2002/06/14 01:25:46  dman13
-# Fixed bug #558867 by redirecting /instance requests to /instance/
-#
-# Revision 1.6  2002/06/12 00:59:44  dman13
-# Fixed the logic for determing the cookie path.  (Closes #562130.)
-#
-# Revision 1.5  2002/05/14 23:36:25  richard
-#  . fixed SCRIPT_NAME in ZRoundup for instances not at top level of Zope
-#    (thanks dman)
-#
-# Revision 1.4  2002/01/10 03:38:16  richard
-# reformatting for 80 cols
-#
-# Revision 1.3  2001/12/12 23:55:00  richard
-# Fixed some problems with user editing
-#
-# Revision 1.2  2001/12/12 23:33:58  richard
-# added some implementation notes
-#
-# Revision 1.1  2001/12/12 23:27:13  richard
-# Added a Zope frontend for roundup.
-#
-#
-#
 # vim: set filetype=python ts=4 sw=4 et si