Code

more modernisation
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Fri, 26 Feb 2010 00:38:53 +0000 (00:38 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Fri, 26 Feb 2010 00:38:53 +0000 (00:38 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/roundup/trunk@4468 57a73879-2fb5-44c3-a270-3262357dd7e2

12 files changed:
2to3-done.txt
roundup/anypy/cookie_.py [new file with mode: 0644]
roundup/anypy/http_.py [new file with mode: 0644]
roundup/anypy/io_.py [new file with mode: 0644]
roundup/anypy/urllib_.py [new file with mode: 0644]
roundup/backends/indexer_dbm.py
roundup/backends/sessions_dbm.py
roundup/backends/sessions_rdbms.py
roundup/cgi/accept_language.py
roundup/cgi/actions.py
roundup/cgi/cgitb.py
roundup/cgi/client.py

index b9cac19f325994c08c53c2922f8288695e935cb8..5aeb5fa0cb5ff50f212b86dccd14926a07baa0e1 100644 (file)
@@ -2,19 +2,9 @@ CAN'T VERIFY
 
 ./roundup/backends/back_mysql.py
 ./roundup/backends/back_tsearch2.py
 
 ./roundup/backends/back_mysql.py
 ./roundup/backends/back_tsearch2.py
-./roundup/backends/indexer_xapian.py
 
 TODO
 
 
 TODO
 
-./roundup/backends/sessions_dbm.py
-./roundup/backends/sessions_rdbms.py
-./roundup/backends/tsearch2_setup.py
-./roundup/cgi/__init__.py
-./roundup/cgi/accept_language.py
-./roundup/cgi/actions.py
-./roundup/cgi/apache.py
-./roundup/cgi/cgitb.py
-./roundup/cgi/client.py
 ./roundup/cgi/exceptions.py
 ./roundup/cgi/form_parser.py
 ./roundup/cgi/MultiMapping.py
 ./roundup/cgi/exceptions.py
 ./roundup/cgi/form_parser.py
 ./roundup/cgi/MultiMapping.py
@@ -133,24 +123,37 @@ TODO
 ./frontends/ZRoundup/ZRoundup.py
 
 
 ./frontends/ZRoundup/ZRoundup.py
 
 
-
 DONE
 
 ./doc/conf.py
 DONE
 
 ./doc/conf.py
-./roundup/__init__.py
 ./roundup/admin.py
 ./roundup/admin.py
-./roundup/actions.py
-./roundup/anypy/__init__.py
-./roundup/anypy/hashlib_.py
-./roundup/anypy/sets_.py
 ./roundup/backends/__init__.py
 ./roundup/backends/back_anydbm.py
 ./roundup/backends/back_postgresql.py
 ./roundup/backends/back_sqlite.py
 ./roundup/backends/__init__.py
 ./roundup/backends/back_anydbm.py
 ./roundup/backends/back_postgresql.py
 ./roundup/backends/back_sqlite.py
-./roundup/backends/blobfiles.py
 ./roundup/backends/indexer_common.py
 ./roundup/backends/indexer_dbm.py
 ./roundup/backends/indexer_rdbms.py
 ./roundup/backends/locking.py
 ./roundup/backends/portalocker.py
 ./roundup/backends/rdbms_common.py
 ./roundup/backends/indexer_common.py
 ./roundup/backends/indexer_dbm.py
 ./roundup/backends/indexer_rdbms.py
 ./roundup/backends/locking.py
 ./roundup/backends/portalocker.py
 ./roundup/backends/rdbms_common.py
+./roundup/backends/sessions_dbm.py
+./roundup/backends/sessions_rdbms.py
+./roundup/cgi/accept_language.py
+./roundup/cgi/actions.py
+./roundup/cgi/cgitb.py
+
+
+NOTHING DONE
+
+./roundup/__init__.py
+./roundup/actions.py
+./roundup/anypy/__init__.py
+./roundup/anypy/hashlib_.py
+./roundup/anypy/sets_.py
+./roundup/backends/blobfiles.py
+./roundup/backends/indexer_xapian.py
+./roundup/backends/tsearch2_setup.py
+./roundup/cgi/__init__.py
+./roundup/cgi/apache.py
+./roundup/cgi/client.py
diff --git a/roundup/anypy/cookie_.py b/roundup/anypy/cookie_.py
new file mode 100644 (file)
index 0000000..44bf93a
--- /dev/null
@@ -0,0 +1,8 @@
+
+try:
+    from http import cookies as Cookie
+    from http.cookies import CookieError, BaseCookie, SimpleCookie
+    from http.cookies import _getdate as get_cookie_date
+except:
+    from Cookie import CookieError, BaseCookie, SimpleCookie
+    from Cookie import _getdate as get_cookie_date
diff --git a/roundup/anypy/http_.py b/roundup/anypy/http_.py
new file mode 100644 (file)
index 0000000..a7f5238
--- /dev/null
@@ -0,0 +1,5 @@
+try:
+    from http import client
+except:
+    import httplib as client
+
diff --git a/roundup/anypy/io_.py b/roundup/anypy/io_.py
new file mode 100644 (file)
index 0000000..86f8023
--- /dev/null
@@ -0,0 +1,6 @@
+
+try:
+    from io import StringIO
+except:
+    from StringIO import StringIO
+
diff --git a/roundup/anypy/urllib_.py b/roundup/anypy/urllib_.py
new file mode 100644 (file)
index 0000000..d1a8a4b
--- /dev/null
@@ -0,0 +1,6 @@
+
+try:
+    from urllib.parse import quote, urlparse
+except:
+    from urllib import quote
+    from urlparse import urlparse
index 0b8562c6b7353bc8a2bff145cc97aae44d6994f8..11ed64f4efa33c928126f360cdb4acc301cd0d16 100644 (file)
@@ -168,7 +168,7 @@ class Indexer(IndexerBase):
                     hits[k] = self.fileids[k]
             else:
                 # Eliminate hits for every non-match
                     hits[k] = self.fileids[k]
             else:
                 # Eliminate hits for every non-match
-                for fileid in hits:
+                for fileid in list(hits):
                     if fileid not in entry:
                         del hits[fileid]
         if hits is None:
                     if fileid not in entry:
                         del hits[fileid]
         if hits is None:
index 1087967b6096a6d8d0e8e311238c19c378a488e0..27b6c52363fc369b7956ca8b38a5ce5097a9bc24 100644 (file)
@@ -7,9 +7,11 @@ class. It's now also used for One Time Key handling too.
 """
 __docformat__ = 'restructuredtext'
 
 """
 __docformat__ = 'restructuredtext'
 
-import anydbm, whichdb, os, marshal, time
+import os, marshal, time
+
 from roundup import hyperdb
 from roundup.i18n import _
 from roundup import hyperdb
 from roundup.i18n import _
+from roundup.anypy.dbm_ import anydbm, whichdb
 
 class BasicDatabase:
     ''' Provide a nice encapsulation of an anydbm store.
 
 class BasicDatabase:
     ''' Provide a nice encapsulation of an anydbm store.
@@ -26,7 +28,7 @@ class BasicDatabase:
     def exists(self, infoid):
         db = self.opendb('c')
         try:
     def exists(self, infoid):
         db = self.opendb('c')
         try:
-            return db.has_key(infoid)
+            return infoid in db
         finally:
             db.close()
 
         finally:
             db.close()
 
@@ -46,8 +48,8 @@ class BasicDatabase:
         if os.path.exists(path):
             db_type = whichdb.whichdb(path)
             if not db_type:
         if os.path.exists(path):
             db_type = whichdb.whichdb(path)
             if not db_type:
-                raise hyperdb.DatabaseError, \
-                    _("Couldn't identify database type")
+                raise hyperdb.DatabaseError(
+                    _("Couldn't identify database type"))
         elif os.path.exists(path+'.db'):
             # if the path ends in '.db', it's a dbm database, whether
             # anydbm says it's dbhash or not!
         elif os.path.exists(path+'.db'):
             # if the path ends in '.db', it's a dbm database, whether
             # anydbm says it's dbhash or not!
@@ -58,12 +60,12 @@ class BasicDatabase:
     def get(self, infoid, value, default=_marker):
         db = self.opendb('c')
         try:
     def get(self, infoid, value, default=_marker):
         db = self.opendb('c')
         try:
-            if db.has_key(infoid):
+            if infoid in db:
                 values = marshal.loads(db[infoid])
             else:
                 if default != self._marker:
                     return default
                 values = marshal.loads(db[infoid])
             else:
                 if default != self._marker:
                     return default
-                raise KeyError, 'No such %s "%s"'%(self.name, infoid)
+                raise KeyError('No such %s "%s"'%(self.name, infoid))
             return values.get(value, None)
         finally:
             db.close()
             return values.get(value, None)
         finally:
             db.close()
@@ -76,14 +78,14 @@ class BasicDatabase:
                 del d['__timestamp']
                 return d
             except KeyError:
                 del d['__timestamp']
                 return d
             except KeyError:
-                raise KeyError, 'No such %s "%s"'%(self.name, infoid)
+                raise KeyError('No such %s "%s"'%(self.name, infoid))
         finally:
             db.close()
 
     def set(self, infoid, **newvalues):
         db = self.opendb('c')
         try:
         finally:
             db.close()
 
     def set(self, infoid, **newvalues):
         db = self.opendb('c')
         try:
-            if db.has_key(infoid):
+            if infoid in db:
                 values = marshal.loads(db[infoid])
             else:
                 values = {'__timestamp': time.time()}
                 values = marshal.loads(db[infoid])
             else:
                 values = {'__timestamp': time.time()}
@@ -95,14 +97,14 @@ class BasicDatabase:
     def list(self):
         db = self.opendb('r')
         try:
     def list(self):
         db = self.opendb('r')
         try:
-            return db.keys()
+            return list(db)
         finally:
             db.close()
 
     def destroy(self, infoid):
         db = self.opendb('c')
         try:
         finally:
             db.close()
 
     def destroy(self, infoid):
         db = self.opendb('c')
         try:
-            if db.has_key(infoid):
+            if infoid in db:
                 del db[infoid]
         finally:
             db.close()
                 del db[infoid]
         finally:
             db.close()
index 43702522ae4389d2d914357a3cb99fa6c9847a03..c5dc1893624497d199ec2ecaecdee04871c46a5b 100644 (file)
@@ -36,7 +36,7 @@ class BasicDatabase:
         if not res:
             if default != self._marker:
                 return default
         if not res:
             if default != self._marker:
                 return default
-            raise KeyError, 'No such %s "%s"'%(self.name, infoid)
+            raise KeyError('No such %s "%s"'%(self.name, infoid))
         values = eval(res[0])
         return values.get(value, None)
 
         values = eval(res[0])
         return values.get(value, None)
 
@@ -46,7 +46,7 @@ class BasicDatabase:
             n, n, self.db.arg), (infoid,))
         res = self.cursor.fetchone()
         if not res:
             n, n, self.db.arg), (infoid,))
         res = self.cursor.fetchone()
         if not res:
-            raise KeyError, 'No such %s "%s"'%(self.name, infoid)
+            raise KeyError('No such %s "%s"'%(self.name, infoid))
         return eval(res[0])
 
     def set(self, infoid, **newvalues):
         return eval(res[0])
 
     def set(self, infoid, **newvalues):
index d3d73281ec7e9cedf4967788e44cf9aba6d6f57a..09c06cf9ae3024699edc09616944b02a56a8d384 100755 (executable)
@@ -35,7 +35,7 @@ qlre  = "([A-Za-z]+[-[A-Za-z]+]*);q=([\d\.]+)"
 # both
 lre   = re.compile(nqlre + "|" + qlre)
 
 # both
 lre   = re.compile(nqlre + "|" + qlre)
 
-ascii = ''.join([chr(x) for x in xrange(256)])
+ascii = ''.join([chr(x) for x in range(256)])
 whitespace = ' \t\n\r\v\f'
 
 def parse(language_header):
 whitespace = ' \t\n\r\v\f'
 
 def parse(language_header):
index dd86a84da6f56fce0227f9855bc6010912d20675..e3de0dea5c9458e60943845c47c5f2baaad6267a 100755 (executable)
@@ -1,4 +1,4 @@
-import re, cgi, StringIO, urllib, time, random, csv, codecs
+import re, cgi, time, random, csv, codecs
 
 from roundup import hyperdb, token, date, password
 from roundup.actions import Action as BaseAction
 
 from roundup import hyperdb, token, date, password
 from roundup.actions import Action as BaseAction
@@ -6,6 +6,7 @@ from roundup.i18n import _
 import roundup.exceptions
 from roundup.cgi import exceptions, templating
 from roundup.mailgw import uidFromAddress
 import roundup.exceptions
 from roundup.cgi import exceptions, templating
 from roundup.mailgw import uidFromAddress
+from roundup.anypy import io_, urllib_
 
 __all__ = ['Action', 'ShowAction', 'RetireAction', 'SearchAction',
            'EditCSVAction', 'EditItemAction', 'PassResetAction',
 
 __all__ = ['Action', 'ShowAction', 'RetireAction', 'SearchAction',
            'EditCSVAction', 'EditItemAction', 'PassResetAction',
@@ -53,9 +54,9 @@ class Action:
         if (self.permissionType and
                 not self.hasPermission(self.permissionType)):
             info = {'action': self.name, 'classname': self.classname}
         if (self.permissionType and
                 not self.hasPermission(self.permissionType)):
             info = {'action': self.name, 'classname': self.classname}
-            raise exceptions.Unauthorisedself._(
+            raise exceptions.Unauthorised(self._(
                 'You do not have permission to '
                 'You do not have permission to '
-                '%(action)s the %(classname)s class.')%info
+                '%(action)s the %(classname)s class.')%info)
 
     _marker = []
     def hasPermission(self, permission, classname=_marker, itemid=None, property=None):
 
     _marker = []
     def hasPermission(self, permission, classname=_marker, itemid=None, property=None):
@@ -79,23 +80,23 @@ class ShowAction(Action):
     def handle(self):
         """Show a node of a particular class/id."""
         t = n = ''
     def handle(self):
         """Show a node of a particular class/id."""
         t = n = ''
-        for key in self.form.keys():
+        for key in self.form:
             if self.typere.match(key):
                 t = self.form[key].value.strip()
             elif self.numre.match(key):
                 n = self.form[key].value.strip()
         if not t:
             if self.typere.match(key):
                 t = self.form[key].value.strip()
             elif self.numre.match(key):
                 n = self.form[key].value.strip()
         if not t:
-            raise ValueError, self._('No type specified')
+            raise ValueError(self._('No type specified'))
         if not n:
         if not n:
-            raise exceptions.SeriousError, self._('No ID entered')
+            raise exceptions.SeriousError(self._('No ID entered'))
         try:
             int(n)
         except ValueError:
             d = {'input': n, 'classname': t}
         try:
             int(n)
         except ValueError:
             d = {'input': n, 'classname': t}
-            raise exceptions.SeriousErrorself._(
-                '"%(input)s" is not an ID (%(classname)s ID required)')%d
+            raise exceptions.SeriousError(self._(
+                '"%(input)s" is not an ID (%(classname)s ID required)')%d)
         url = '%s%s%s'%(self.base, t, n)
         url = '%s%s%s'%(self.base, t, n)
-        raise exceptions.Redirect, url
+        raise exceptions.Redirect(url)
 
 class RetireAction(Action):
     name = 'retire'
 
 class RetireAction(Action):
     name = 'retire'
@@ -116,15 +117,15 @@ class RetireAction(Action):
         # make sure we don't try to retire admin or anonymous
         if self.classname == 'user' and \
                 self.db.user.get(itemid, 'username') in ('admin', 'anonymous'):
         # make sure we don't try to retire admin or anonymous
         if self.classname == 'user' and \
                 self.db.user.get(itemid, 'username') in ('admin', 'anonymous'):
-            raise ValueErrorself._(
-                'You may not retire the admin or anonymous user')
+            raise ValueError(self._(
+                'You may not retire the admin or anonymous user'))
 
         # check permission
         if not self.hasPermission('Retire', classname=self.classname,
                 itemid=itemid):
 
         # check permission
         if not self.hasPermission('Retire', classname=self.classname,
                 itemid=itemid):
-            raise exceptions.Unauthorisedself._(
+            raise exceptions.Unauthorised(self._(
                 'You do not have permission to retire %(class)s'
                 'You do not have permission to retire %(class)s'
-            ) % {'class': self.classname}
+            ) % {'class': self.classname})
 
         # do the retire
         self.db.getclass(self.classname).retire(itemid)
 
         # do the retire
         self.db.getclass(self.classname).retire(itemid)
@@ -171,14 +172,14 @@ class SearchAction(Action):
                 try:
                     qid = self.db.query.lookup(old_queryname)
                     if not self.hasPermission('Edit', 'query', itemid=qid):
                 try:
                     qid = self.db.query.lookup(old_queryname)
                     if not self.hasPermission('Edit', 'query', itemid=qid):
-                        raise exceptions.Unauthorisedself._(
-                            "You do not have permission to edit queries")
+                        raise exceptions.Unauthorised(self._(
+                            "You do not have permission to edit queries"))
                     self.db.query.set(qid, klass=self.classname, url=url)
                 except KeyError:
                     # create a query
                     if not self.hasPermission('Create', 'query'):
                     self.db.query.set(qid, klass=self.classname, url=url)
                 except KeyError:
                     # create a query
                     if not self.hasPermission('Create', 'query'):
-                        raise exceptions.Unauthorisedself._(
-                            "You do not have permission to store queries")
+                        raise exceptions.Unauthorised(self._(
+                            "You do not have permission to store queries"))
                     qid = self.db.query.create(name=queryname,
                         klass=self.classname, url=url)
             else:
                     qid = self.db.query.create(name=queryname,
                         klass=self.classname, url=url)
             else:
@@ -199,15 +200,15 @@ class SearchAction(Action):
                         if old_queryname != self.db.query.get(qid, 'name'):
                             continue
                         if not self.hasPermission('Edit', 'query', itemid=qid):
                         if old_queryname != self.db.query.get(qid, 'name'):
                             continue
                         if not self.hasPermission('Edit', 'query', itemid=qid):
-                            raise exceptions.Unauthorisedself._(
-                            "You do not have permission to edit queries")
+                            raise exceptions.Unauthorised(self._(
+                            "You do not have permission to edit queries"))
                         self.db.query.set(qid, klass=self.classname,
                             url=url, name=queryname)
                 else:
                     # create a query
                     if not self.hasPermission('Create', 'query'):
                         self.db.query.set(qid, klass=self.classname,
                             url=url, name=queryname)
                 else:
                     # create a query
                     if not self.hasPermission('Create', 'query'):
-                        raise exceptions.Unauthorisedself._(
-                            "You do not have permission to store queries")
+                        raise exceptions.Unauthorised(self._(
+                            "You do not have permission to store queries"))
                     qid = self.db.query.create(name=queryname,
                         klass=self.classname, url=url, private_for=uid)
 
                     qid = self.db.query.create(name=queryname,
                         klass=self.classname, url=url, private_for=uid)
 
@@ -223,7 +224,7 @@ class SearchAction(Action):
     def fakeFilterVars(self):
         """Add a faked :filter form variable for each filtering prop."""
         cls = self.db.classes[self.classname]
     def fakeFilterVars(self):
         """Add a faked :filter form variable for each filtering prop."""
         cls = self.db.classes[self.classname]
-        for key in self.form.keys():
+        for key in self.form:
             prop = cls.get_transitive_prop(key)
             if not prop:
                 continue
             prop = cls.get_transitive_prop(key)
             if not prop:
                 continue
@@ -264,7 +265,7 @@ class SearchAction(Action):
 
     def getFromForm(self, name):
         for key in ('@' + name, ':' + name):
 
     def getFromForm(self, name):
         for key in ('@' + name, ':' + name):
-            if self.form.has_key(key):
+            if key in self.form:
                 return self.form[key].value.strip()
         return ''
 
                 return self.form[key].value.strip()
         return ''
 
@@ -288,7 +289,7 @@ class EditCSVAction(Action):
 
         # figure the properties list for the class
         cl = self.db.classes[self.classname]
 
         # figure the properties list for the class
         cl = self.db.classes[self.classname]
-        props_without_id = cl.getprops(protected=0).keys()
+        props_without_id = list(cl.getprops(protected=0))
 
         # the incoming CSV data will always have the properties in colums
         # sorted and starting with the "id" column
 
         # the incoming CSV data will always have the properties in colums
         # sorted and starting with the "id" column
@@ -296,7 +297,7 @@ class EditCSVAction(Action):
         props = ['id'] + props_without_id
 
         # do the edit
         props = ['id'] + props_without_id
 
         # do the edit
-        rows = StringIO.StringIO(self.form['rows'].value)
+        rows = io_.StringIO(self.form['rows'].value)
         reader = csv.reader(rows)
         found = {}
         line = 0
         reader = csv.reader(rows)
         found = {}
         line = 0
@@ -317,9 +318,9 @@ class EditCSVAction(Action):
 
                 # check permission to create this item
                 if not self.hasPermission('Create', classname=self.classname):
 
                 # check permission to create this item
                 if not self.hasPermission('Create', classname=self.classname):
-                    raise exceptions.Unauthorisedself._(
+                    raise exceptions.Unauthorised(self._(
                         'You do not have permission to create %(class)s'
                         'You do not have permission to create %(class)s'
-                    ) % {'class': self.classname}
+                    ) % {'class': self.classname})
             elif cl.hasnode(itemid) and cl.is_retired(itemid):
                 # If a CSV line just mentions an id and the corresponding
                 # item is retired, then the item is restored.
             elif cl.hasnode(itemid) and cl.is_retired(itemid):
                 # If a CSV line just mentions an id and the corresponding
                 # item is retired, then the item is restored.
@@ -340,9 +341,9 @@ class EditCSVAction(Action):
                 # check permission to edit this property on this item
                 if exists and not self.hasPermission('Edit', itemid=itemid,
                         classname=self.classname, property=name):
                 # check permission to edit this property on this item
                 if exists and not self.hasPermission('Edit', itemid=itemid,
                         classname=self.classname, property=name):
-                    raise exceptions.Unauthorisedself._(
+                    raise exceptions.Unauthorised(self._(
                         'You do not have permission to edit %(class)s'
                         'You do not have permission to edit %(class)s'
-                    ) % {'class': self.classname}
+                    ) % {'class': self.classname})
 
                 prop = cl.properties[name]
                 value = value.strip()
 
                 prop = cl.properties[name]
                 value = value.strip()
@@ -379,13 +380,13 @@ class EditCSVAction(Action):
 
         # retire the removed entries
         for itemid in cl.list():
 
         # retire the removed entries
         for itemid in cl.list():
-            if not found.has_key(itemid):
+            if itemid not in found:
                 # check permission to retire this item
                 if not self.hasPermission('Retire', itemid=itemid,
                         classname=self.classname):
                 # check permission to retire this item
                 if not self.hasPermission('Retire', itemid=itemid,
                         classname=self.classname):
-                    raise exceptions.Unauthorisedself._(
+                    raise exceptions.Unauthorised(self._(
                         'You do not have permission to retire %(class)s'
                         'You do not have permission to retire %(class)s'
-                    ) % {'class': self.classname}
+                    ) % {'class': self.classname})
                 cl.retire(itemid)
 
         # all OK
                 cl.retire(itemid)
 
         # all OK
@@ -405,12 +406,12 @@ class EditCommon(Action):
         links = {}
         for cn, nodeid, propname, vlist in all_links:
             numeric_id = int (nodeid or 0)
         links = {}
         for cn, nodeid, propname, vlist in all_links:
             numeric_id = int (nodeid or 0)
-            if not (numeric_id > 0 or all_props.has_key((cn, nodeid))):
+            if not (numeric_id > 0 or (cn, nodeid) in all_props):
                 # link item to link to doesn't (and won't) exist
                 continue
 
             for value in vlist:
                 # link item to link to doesn't (and won't) exist
                 continue
 
             for value in vlist:
-                if not all_props.has_key(value):
+                if value not in all_props:
                     # link item to link to doesn't (and won't) exist
                     continue
                 deps.setdefault((cn, nodeid), []).append(value)
                     # link item to link to doesn't (and won't) exist
                     continue
                 deps.setdefault((cn, nodeid), []).append(value)
@@ -422,19 +423,19 @@ class EditCommon(Action):
         # loop detection
         change = 0
         while len(all_props) != len(done):
         # loop detection
         change = 0
         while len(all_props) != len(done):
-            for needed in all_props.keys():
-                if done.has_key(needed):
+            for needed in all_props:
+                if needed in done:
                     continue
                 tlist = deps.get(needed, [])
                 for target in tlist:
                     continue
                 tlist = deps.get(needed, [])
                 for target in tlist:
-                    if not done.has_key(target):
+                    if target not in done:
                         break
                 else:
                     done[needed] = 1
                     order.append(needed)
                     change = 1
             if not change:
                         break
                 else:
                     done[needed] = 1
                     order.append(needed)
                     change = 1
             if not change:
-                raise ValueError, 'linking must not loop!'
+                raise ValueError('linking must not loop!')
 
         # now, edit / create
         m = []
 
         # now, edit / create
         m = []
@@ -448,7 +449,7 @@ class EditCommon(Action):
 
                     # and some nice feedback for the user
                     if props:
 
                     # and some nice feedback for the user
                     if props:
-                        info = ', '.join(map(self._, props.keys()))
+                        info = ', '.join(map(self._, props))
                         m.append(
                             self._('%(class)s %(id)s %(properties)s edited ok')
                             % {'class':cn, 'id':nodeid, 'properties':info})
                         m.append(
                             self._('%(class)s %(id)s %(properties)s edited ok')
                             % {'class':cn, 'id':nodeid, 'properties':info})
@@ -469,12 +470,12 @@ class EditCommon(Action):
                         % {'class':cn, 'id':newid})
 
             # fill in new ids in links
                         % {'class':cn, 'id':newid})
 
             # fill in new ids in links
-            if links.has_key(needed):
+            if needed in links:
                 for linkcn, linkid, linkprop in links[needed]:
                     props = all_props[(linkcn, linkid)]
                     cl = self.db.classes[linkcn]
                     propdef = cl.getprops()[linkprop]
                 for linkcn, linkid, linkprop in links[needed]:
                     props = all_props[(linkcn, linkid)]
                     cl = self.db.classes[linkcn]
                     propdef = cl.getprops()[linkprop]
-                    if not props.has_key(linkprop):
+                    if linkprop not in props:
                         if linkid is None or linkid.startswith('-'):
                             # linking to a new item
                             if isinstance(propdef, hyperdb.Multilink):
                         if linkid is None or linkid.startswith('-'):
                             # linking to a new item
                             if isinstance(propdef, hyperdb.Multilink):
@@ -496,9 +497,9 @@ class EditCommon(Action):
         """Change the node based on the contents of the form."""
         # check for permission
         if not self.editItemPermission(props, classname=cn, itemid=nodeid):
         """Change the node based on the contents of the form."""
         # check for permission
         if not self.editItemPermission(props, classname=cn, itemid=nodeid):
-            raise exceptions.Unauthorisedself._(
+            raise exceptions.Unauthorised(self._(
                 'You do not have permission to edit %(class)s'
                 'You do not have permission to edit %(class)s'
-            ) % {'class': cn}
+            ) % {'class': cn})
 
         # make the changes
         cl = self.db.classes[cn]
 
         # make the changes
         cl = self.db.classes[cn]
@@ -508,9 +509,9 @@ class EditCommon(Action):
         """Create a node based on the contents of the form."""
         # check for permission
         if not self.newItemPermission(props, classname=cn):
         """Create a node based on the contents of the form."""
         # check for permission
         if not self.newItemPermission(props, classname=cn):
-            raise exceptions.Unauthorisedself._(
+            raise exceptions.Unauthorised(self._(
                 'You do not have permission to create %(class)s'
                 'You do not have permission to create %(class)s'
-            ) % {'class': cn}
+            ) % {'class': cn})
 
         # create the node and return its id
         cl = self.db.classes[cn]
 
         # create the node and return its id
         cl = self.db.classes[cn]
@@ -561,9 +562,9 @@ class EditCommon(Action):
 
 class EditItemAction(EditCommon):
     def lastUserActivity(self):
 
 class EditItemAction(EditCommon):
     def lastUserActivity(self):
-        if self.form.has_key(':lastactivity'):
+        if ':lastactivity' in self.form:
             d = date.Date(self.form[':lastactivity'].value)
             d = date.Date(self.form[':lastactivity'].value)
-        elif self.form.has_key('@lastactivity'):
+        elif '@lastactivity' in self.form:
             d = date.Date(self.form['@lastactivity'].value)
         else:
             return None
             d = date.Date(self.form['@lastactivity'].value)
         else:
             return None
@@ -583,7 +584,7 @@ class EditItemAction(EditCommon):
             props, links = self.client.parsePropsFromForm()
             key = (self.classname, self.nodeid)
             # we really only collide for direct prop edit conflicts
             props, links = self.client.parsePropsFromForm()
             key = (self.classname, self.nodeid)
             # we really only collide for direct prop edit conflicts
-            return props[key].keys()
+            return list(props[key])
         else:
             return []
 
         else:
             return []
 
@@ -633,12 +634,12 @@ class EditItemAction(EditCommon):
         # we will want to include index-page args in this URL too
         if self.nodeid is not None:
             url += self.nodeid
         # we will want to include index-page args in this URL too
         if self.nodeid is not None:
             url += self.nodeid
-        url += '?@ok_message=%s&@template=%s'%(urllib.quote(message),
-            urllib.quote(self.template))
+        url += '?@ok_message=%s&@template=%s'%(urllib_.quote(message),
+            urllib_.quote(self.template))
         if self.nodeid is None:
             req = templating.HTMLRequest(self.client)
             url += '&' + req.indexargs_url('', {})[1:]
         if self.nodeid is None:
             req = templating.HTMLRequest(self.client)
             url += '&' + req.indexargs_url('', {})[1:]
-        raise exceptions.Redirect, url
+        raise exceptions.Redirect(url)
 
 class NewItemAction(EditCommon):
     def handle(self):
 
 class NewItemAction(EditCommon):
     def handle(self):
@@ -673,9 +674,9 @@ class NewItemAction(EditCommon):
         self.db.commit()
 
         # redirect to the new item's page
         self.db.commit()
 
         # redirect to the new item's page
-        raise exceptions.Redirect'%s%s%s?@ok_message=%s&@template=%s' % (
-            self.base, self.classname, self.nodeid, urllib.quote(messages),
-            urllib.quote(self.template))
+        raise exceptions.Redirect('%s%s%s?@ok_message=%s&@template=%s' % (
+            self.base, self.classname, self.nodeid, urllib_.quote(messages),
+            urllib_.quote(self.template)))
 
 class PassResetAction(Action):
     def handle(self):
 
 class PassResetAction(Action):
     def handle(self):
@@ -686,7 +687,7 @@ class PassResetAction(Action):
 
         """
         otks = self.db.getOTKManager()
 
         """
         otks = self.db.getOTKManager()
-        if self.form.has_key('otk'):
+        if 'otk' in self.form:
             # pull the rego information out of the otk database
             otk = self.form['otk'].value
             uid = otks.get(otk, 'uid', default=None)
             # pull the rego information out of the otk database
             otk = self.form['otk'].value
             uid = otks.get(otk, 'uid', default=None)
@@ -738,7 +739,7 @@ Your password is now: %(password)s
             return
 
         # no OTK, so now figure the user
             return
 
         # no OTK, so now figure the user
-        if self.form.has_key('username'):
+        if 'username' in self.form:
             name = self.form['username'].value
             try:
                 uid = self.db.user.lookup(name)
             name = self.form['username'].value
             try:
                 uid = self.db.user.lookup(name)
@@ -746,7 +747,7 @@ Your password is now: %(password)s
                 self.client.error_message.append(self._('Unknown username'))
                 return
             address = self.db.user.get(uid, 'address')
                 self.client.error_message.append(self._('Unknown username'))
                 return
             address = self.db.user.get(uid, 'address')
-        elif self.form.has_key('address'):
+        elif 'address' in self.form:
             address = self.form['address'].value
             uid = uidFromAddress(self.db, ('', address), create=0)
             if not uid:
             address = self.form['address'].value
             uid = uidFromAddress(self.db, ('', address), create=0)
             if not uid:
@@ -797,7 +798,7 @@ class RegoCommon(Action):
         # nice message
         message = self._('You are now registered, welcome!')
         url = '%suser%s?@ok_message=%s'%(self.base, self.userid,
         # nice message
         message = self._('You are now registered, welcome!')
         url = '%suser%s?@ok_message=%s'%(self.base, self.userid,
-            urllib.quote(message))
+            urllib._quote(message))
 
         # redirect to the user's page (but not 302, as some email clients seem
         # to want to reload the page, or something)
 
         # redirect to the user's page (but not 302, as some email clients seem
         # to want to reload the page, or something)
@@ -865,7 +866,7 @@ class RegisterAction(RegoCommon, EditCommon):
 
         # generate the one-time-key and store the props for later
         user_props = props[('user', None)]
 
         # generate the one-time-key and store the props for later
         user_props = props[('user', None)]
-        for propname, proptype in self.db.user.getprops().items():
+        for propname, proptype in self.db.user.getprops().iteritems():
             value = user_props.get(propname, None)
             if value is None:
                 pass
             value = user_props.get(propname, None)
             if value is None:
                 pass
@@ -916,15 +917,15 @@ reply's additional "Re:" is ok),
         self.db.commit()
 
         # redirect to the "you're almost there" page
         self.db.commit()
 
         # redirect to the "you're almost there" page
-        raise exceptions.Redirect, '%suser?@template=rego_progress'%self.base
+        raise exceptions.Redirect('%suser?@template=rego_progress'%self.base)
 
     def newItemPermission(self, props, classname=None):
         """Just check the "Register" permission.
         """
         # registration isn't allowed to supply roles
 
     def newItemPermission(self, props, classname=None):
         """Just check the "Register" permission.
         """
         # registration isn't allowed to supply roles
-        if props.has_key('roles'):
-            raise exceptions.Unauthorisedself._(
-                "It is not permitted to supply roles at registration.")
+        if 'roles' in props:
+            raise exceptions.Unauthorised(self._(
+                "It is not permitted to supply roles at registration."))
 
         # technically already checked, but here for clarity
         return self.hasPermission('Register', classname=classname)
 
         # technically already checked, but here for clarity
         return self.hasPermission('Register', classname=classname)
@@ -957,13 +958,13 @@ class LoginAction(Action):
             raise roundup.exceptions.Reject(self._('Invalid request'))
 
         # we need the username at a minimum
             raise roundup.exceptions.Reject(self._('Invalid request'))
 
         # we need the username at a minimum
-        if not self.form.has_key('__login_name'):
+        if '__login_name' not in self.form:
             self.client.error_message.append(self._('Username required'))
             return
 
         # get the login info
         self.client.user = self.form['__login_name'].value
             self.client.error_message.append(self._('Username required'))
             return
 
         # get the login info
         self.client.user = self.form['__login_name'].value
-        if self.form.has_key('__login_password'):
+        if '__login_password' in self.form:
             password = self.form['__login_password'].value
         else:
             password = ''
             password = self.form['__login_password'].value
         else:
             password = ''
@@ -980,29 +981,29 @@ class LoginAction(Action):
 
         # save user in session
         self.client.session_api.set(user=self.client.user)
 
         # save user in session
         self.client.session_api.set(user=self.client.user)
-        if self.form.has_key('remember'):
+        if 'remember' in self.form:
             self.client.session_api.update(set_cookie=True, expire=24*3600*365)
 
         # If we came from someplace, go back there
             self.client.session_api.update(set_cookie=True, expire=24*3600*365)
 
         # If we came from someplace, go back there
-        if self.form.has_key('__came_from'):
-            raise exceptions.Redirect, self.form['__came_from'].value
+        if '__came_from' in self.form:
+            raise exceptions.Redirect(self.form['__came_from'].value)
 
     def verifyLogin(self, username, password):
         # make sure the user exists
         try:
             self.client.userid = self.db.user.lookup(username)
         except KeyError:
 
     def verifyLogin(self, username, password):
         # make sure the user exists
         try:
             self.client.userid = self.db.user.lookup(username)
         except KeyError:
-            raise exceptions.LoginError, self._('Invalid login')
+            raise exceptions.LoginError(self._('Invalid login'))
 
         # verify the password
         if not self.verifyPassword(self.client.userid, password):
 
         # verify the password
         if not self.verifyPassword(self.client.userid, password):
-            raise exceptions.LoginError, self._('Invalid login')
+            raise exceptions.LoginError(self._('Invalid login'))
 
         # Determine whether the user has permission to log in.
         # Base behaviour is to check the user has "Web Access".
         if not self.hasPermission("Web Access"):
 
         # Determine whether the user has permission to log in.
         # Base behaviour is to check the user has "Web Access".
         if not self.hasPermission("Web Access"):
-            raise exceptions.LoginErrorself._(
-                "You do not have permission to login")
+            raise exceptions.LoginError(self._(
+                "You do not have permission to login"))
 
     def verifyPassword(self, userid, password):
         '''Verify the password that the user has supplied'''
 
     def verifyPassword(self, userid, password):
         '''Verify the password that the user has supplied'''
@@ -1060,9 +1061,9 @@ class ExportCSVAction(Action):
                 # check permission to view this property on this item
                 if not self.hasPermission('View', itemid=itemid,
                         classname=request.classname, property=name):
                 # check permission to view this property on this item
                 if not self.hasPermission('View', itemid=itemid,
                         classname=request.classname, property=name):
-                    raise exceptions.Unauthorisedself._(
+                    raise exceptions.Unauthorised(self._(
                         'You do not have permission to view %(class)s'
                         'You do not have permission to view %(class)s'
-                    ) % {'class': request.classname}
+                    ) % {'class': request.classname})
                 row.append(str(klass.get(itemid, name)))
             self.client._socket_op(writer.writerow, row)
 
                 row.append(str(klass.get(itemid, name)))
             self.client._socket_op(writer.writerow, row)
 
@@ -1095,7 +1096,7 @@ class Bridge(BaseAction):
 
     def execute_cgi(self):
         args = {}
 
     def execute_cgi(self):
         args = {}
-        for key in self.form.keys():
+        for key in self.form:
             args[key] = self.form.getvalue(key)
         self.permission(args)
         return self.handle(args)
             args[key] = self.form.getvalue(key)
         self.permission(args)
         return self.handle(args)
index b89cb467bde0ba025fcf3c66a1a23053f98a492f..d2b30a1f5e55797032b3c55f387a20a91a184acc 100644 (file)
@@ -37,9 +37,7 @@ def breaker():
 
 def niceDict(indent, dict):
     l = []
 
 def niceDict(indent, dict):
     l = []
-    keys = dict.keys()
-    keys.sort()
-    for k in keys:
+    for k in sorted(dict):
         v = dict[k]
         l.append('<tr><td><strong>%s</strong></td><td>%s</td></tr>'%(k,
             cgi.escape(repr(v))))
         v = dict[k]
         l.append('<tr><td><strong>%s</strong></td><td>%s</td></tr>'%(k,
             cgi.escape(repr(v))))
@@ -59,7 +57,7 @@ def pt_html(context=5, i18n=None):
     t.reverse()
     for frame, file, lnum, func, lines, index in t:
         args, varargs, varkw, locals = inspect.getargvalues(frame)
     t.reverse()
     for frame, file, lnum, func, lines, index in t:
         args, varargs, varkw, locals = inspect.getargvalues(frame)
-        if locals.has_key('__traceback_info__'):
+        if '__traceback_info__' in locals:
             ti = locals['__traceback_info__']
             if isinstance(ti, TraversalError):
                 s = []
             ti = locals['__traceback_info__']
             if isinstance(ti, TraversalError):
                 s = []
@@ -72,7 +70,7 @@ def pt_html(context=5, i18n=None):
                 ) % {'name': ti.name, 'path': s})
             else:
                 l.append(_('<li>In %s</li>') % esc(str(ti)))
                 ) % {'name': ti.name, 'path': s})
             else:
                 l.append(_('<li>In %s</li>') % esc(str(ti)))
-        if locals.has_key('__traceback_supplement__'):
+        if '__traceback_supplement__' in locals:
             ts = locals['__traceback_supplement__']
             if len(ts) == 2:
                 supp, context = ts
             ts = locals['__traceback_supplement__']
             if len(ts) == 2:
                 supp, context = ts
@@ -111,8 +109,8 @@ def pt_html(context=5, i18n=None):
 
 def html(context=5, i18n=None):
     _ = get_translator(i18n)
 
 def html(context=5, i18n=None):
     _ = get_translator(i18n)
-    etype, evalue = sys.exc_type, sys.exc_value
-    if type(etype) is types.ClassType:
+    etype, evalue = sys.exc_info()[0], sys.exc_info()[1]
+    if type(etype) is type:
         etype = etype.__name__
     pyver = 'Python ' + string.split(sys.version)[0] + '<br>' + sys.executable
     head = pydoc.html.heading(
         etype = etype.__name__
     pyver = 'Python ' + string.split(sys.version)[0] + '<br>' + sys.executable
     head = pydoc.html.heading(
@@ -169,13 +167,13 @@ def html(context=5, i18n=None):
         lvals = []
         for name in names:
             if name in frame.f_code.co_varnames:
         lvals = []
         for name in names:
             if name in frame.f_code.co_varnames:
-                if locals.has_key(name):
+                if name in locals:
                     value = pydoc.html.repr(locals[name])
                 else:
                     value = _('<em>undefined</em>')
                 name = '<strong>%s</strong>' % name
             else:
                     value = pydoc.html.repr(locals[name])
                 else:
                     value = _('<em>undefined</em>')
                 name = '<strong>%s</strong>' % name
             else:
-                if frame.f_globals.has_key(name):
+                if name in frame.f_globals:
                     value = pydoc.html.repr(frame.f_globals[name])
                 else:
                     value = _('<em>undefined</em>')
                     value = pydoc.html.repr(frame.f_globals[name])
                 else:
                     value = _('<em>undefined</em>')
index 3b1023806a5bd4b20c7c3040c0cb6bd8378a7406..793a0d8472b32b4f183910948e953e83e2c005a4 100644 (file)
@@ -2,11 +2,9 @@
 """
 __docformat__ = 'restructuredtext'
 
 """
 __docformat__ = 'restructuredtext'
 
-import base64, binascii, cgi, codecs, httplib, mimetypes, os
-import quopri, random, re, rfc822, stat, sys, time, urllib, urlparse
-import Cookie, socket, errno
-from Cookie import CookieError, BaseCookie, SimpleCookie
-from cStringIO import StringIO
+import base64, binascii, cgi, codecs, mimetypes, os
+import quopri, random, re, rfc822, stat, sys, time
+import socket, errno
 
 from roundup import roundupdb, date, hyperdb, password
 from roundup.cgi import templating, cgitb, TranslationService
 
 from roundup import roundupdb, date, hyperdb, password
 from roundup.cgi import templating, cgitb, TranslationService
@@ -18,6 +16,12 @@ from roundup.mailer import Mailer, MessageSendError, encode_quopri
 from roundup.cgi import accept_language
 from roundup import xmlrpc
 
 from roundup.cgi import accept_language
 from roundup import xmlrpc
 
+from roundup.anypy.cookie_ import CookieError, BaseCookie, SimpleCookie, \
+    get_cookie_date
+from roundup.anypy.io_ import StringIO
+from roundup.anypy import http_
+from roundup.anypy import urllib_
+
 def initialiseSecurity(security):
     '''Create some Permissions and Roles on the security object
 
 def initialiseSecurity(security):
     '''Create some Permissions and Roles on the security object
 
@@ -43,7 +47,7 @@ def clean_message(message, mc=re.compile(CLEAN_MESSAGE_RE, re.I)):
 def clean_message_callback(match, ok={'a':1,'i':1,'b':1,'br':1}):
     """ Strip all non <a>,<i>,<b> and <br> tags from a string
     """
 def clean_message_callback(match, ok={'a':1,'i':1,'b':1,'br':1}):
     """ Strip all non <a>,<i>,<b> and <br> tags from a string
     """
-    if ok.has_key(match.group(3).lower()):
+    if match.group(3).lower() in ok:
         return match.group(1)
     return '&lt;%s&gt;'%match.group(2)
 
         return match.group(1)
     return '&lt;%s&gt;'%match.group(2)
 
@@ -293,7 +297,7 @@ class Client:
 
         # this is the "cookie path" for this tracker (ie. the path part of
         # the "base" url)
 
         # this is the "cookie path" for this tracker (ie. the path part of
         # the "base" url)
-        self.cookie_path = urlparse.urlparse(self.base)[2]
+        self.cookie_path = urllib_.urlparse(self.base)[2]
         # cookies to set in http responce
         # {(path, name): (value, expire)}
         self._cookies = {}
         # cookies to set in http responce
         # {(path, name): (value, expire)}
         self._cookies = {}
@@ -501,12 +505,12 @@ class Client:
             # authorization, send back a response that will cause the
             # browser to prompt the user again.
             if self.instance.config.WEB_HTTP_AUTH:
             # authorization, send back a response that will cause the
             # browser to prompt the user again.
             if self.instance.config.WEB_HTTP_AUTH:
-                self.response_code = httplib.UNAUTHORIZED
+                self.response_code = http_.client.UNAUTHORIZED
                 realm = self.instance.config.TRACKER_NAME
                 self.setHeader("WWW-Authenticate",
                                "Basic realm=\"%s\"" % realm)
             else:
                 realm = self.instance.config.TRACKER_NAME
                 self.setHeader("WWW-Authenticate",
                                "Basic realm=\"%s\"" % realm)
             else:
-                self.response_code = httplib.FORBIDDEN
+                self.response_code = http_.client.FORBIDDEN
             self.renderFrontPage(message)
         except Unauthorised, message:
             # users may always see the front page
             self.renderFrontPage(message)
         except Unauthorised, message:
             # users may always see the front page
@@ -526,15 +530,15 @@ class Client:
                 # we can't map the URL to a class we know about
                 # reraise the NotFound and let roundup_server
                 # handle it
                 # we can't map the URL to a class we know about
                 # reraise the NotFound and let roundup_server
                 # handle it
-                raise NotFound, e
+                raise NotFound(e)
         except FormError, e:
             self.error_message.append(self._('Form Error: ') + str(e))
             self.write_html(self.renderContext())
         except:
             # Something has gone badly wrong.  Therefore, we should
             # make sure that the response code indicates failure.
         except FormError, e:
             self.error_message.append(self._('Form Error: ') + str(e))
             self.write_html(self.renderContext())
         except:
             # Something has gone badly wrong.  Therefore, we should
             # make sure that the response code indicates failure.
-            if self.response_code == httplib.OK:
-                self.response_code = httplib.INTERNAL_SERVER_ERROR
+            if self.response_code == http_.client.OK:
+                self.response_code = http_.client.INTERNAL_SERVER_ERROR
             # Help the administrator work out what went wrong.
             html = ("<h1>Traceback</h1>"
                     + cgitb.html(i18n=self.translator)
             # Help the administrator work out what went wrong.
             html = ("<h1>Traceback</h1>"
                     + cgitb.html(i18n=self.translator)
@@ -583,12 +587,12 @@ class Client:
         """
         # look for client charset
         charset_parameter = 0
         """
         # look for client charset
         charset_parameter = 0
-        if self.form.has_key('@charset'):
+        if '@charset' in self.form:
             charset = self.form['@charset'].value
             if charset.lower() == "none":
                 charset = ""
             charset_parameter = 1
             charset = self.form['@charset'].value
             if charset.lower() == "none":
                 charset = ""
             charset_parameter = 1
-        elif self.cookie.has_key('roundup_charset'):
+        elif 'roundup_charset' in self.cookie:
             charset = self.cookie['roundup_charset'].value
         else:
             charset = None
             charset = self.cookie['roundup_charset'].value
         else:
             charset = None
@@ -625,7 +629,7 @@ class Client:
                     uc = int(num)
                 return unichr(uc)
 
                     uc = int(num)
                 return unichr(uc)
 
-            for field_name in self.form.keys():
+            for field_name in self.form:
                 field = self.form[field_name]
                 if (field.type == 'text/plain') and not field.filename:
                     try:
                 field = self.form[field_name]
                 if (field.type == 'text/plain') and not field.filename:
                     try:
@@ -640,12 +644,12 @@ class Client:
         # look for language parameter
         # then for language cookie
         # last for the Accept-Language header
         # look for language parameter
         # then for language cookie
         # last for the Accept-Language header
-        if self.form.has_key("@language"):
+        if "@language" in self.form:
             language = self.form["@language"].value
             if language.lower() == "none":
                 language = ""
             self.add_cookie("roundup_language", language)
             language = self.form["@language"].value
             if language.lower() == "none":
                 language = ""
             self.add_cookie("roundup_language", language)
-        elif self.cookie.has_key("roundup_language"):
+        elif "roundup_language" in self.cookie:
             language = self.cookie["roundup_language"].value
         elif self.instance.config["WEB_USE_BROWSER_LANGUAGE"]:
             hal = self.env.get('HTTP_ACCEPT_LANGUAGE')
             language = self.cookie["roundup_language"].value
         elif self.instance.config["WEB_USE_BROWSER_LANGUAGE"]:
             hal = self.env.get('HTTP_ACCEPT_LANGUAGE')
@@ -673,7 +677,7 @@ class Client:
         user = None
         # first up, try http authorization if enabled
         if self.instance.config['WEB_HTTP_AUTH']:
         user = None
         # first up, try http authorization if enabled
         if self.instance.config['WEB_HTTP_AUTH']:
-            if self.env.has_key('REMOTE_USER'):
+            if 'REMOTE_USER' in self.env:
                 # we have external auth (e.g. by Apache)
                 user = self.env['REMOTE_USER']
             elif self.env.get('HTTP_AUTHORIZATION', ''):
                 # we have external auth (e.g. by Apache)
                 user = self.env['REMOTE_USER']
             elif self.env.get('HTTP_AUTHORIZATION', ''):
@@ -729,9 +733,9 @@ class Client:
         """
         # allow Anonymous to use the "login" and "register" actions (noting
         # that "register" has its own "Register" permission check)
         """
         # allow Anonymous to use the "login" and "register" actions (noting
         # that "register" has its own "Register" permission check)
-        if self.form.has_key(':action'):
+        if ':action' in self.form:
             action = self.form[':action'].value.lower()
             action = self.form[':action'].value.lower()
-        elif self.form.has_key('@action'):
+        elif '@action' in self.form:
             action = self.form['@action'].value.lower()
         else:
             action = None
             action = self.form['@action'].value.lower()
         else:
             action = None
@@ -747,8 +751,8 @@ class Client:
         # otherwise for everything else
         if self.user == 'anonymous':
             if not self.db.security.hasPermission('Web Access', self.userid):
         # otherwise for everything else
         if self.user == 'anonymous':
             if not self.db.security.hasPermission('Web Access', self.userid):
-                raise Unauthorisedself._("Anonymous users are not "
-                    "allowed to use the web interface")
+                raise Unauthorised(self._("Anonymous users are not "
+                    "allowed to use the web interface"))
 
     def opendb(self, username):
         """Open the database and set the current user.
 
     def opendb(self, username):
         """Open the database and set the current user.
@@ -822,7 +826,7 @@ class Client:
 
         # see if a template or messages are specified
         template_override = ok_message = error_message = None
 
         # see if a template or messages are specified
         template_override = ok_message = error_message = None
-        for key in self.form.keys():
+        for key in self.form:
             if self.FV_TEMPLATE.match(key):
                 template_override = self.form[key].value
             elif self.FV_OK_MESSAGE.match(key):
             if self.FV_TEMPLATE.match(key):
                 template_override = self.form[key].value
             elif self.FV_OK_MESSAGE.match(key):
@@ -847,12 +851,12 @@ class Client:
                 self.template = ''
             return
         elif path[0] in ('_file', '@@file'):
                 self.template = ''
             return
         elif path[0] in ('_file', '@@file'):
-            raise SendStaticFile, os.path.join(*path[1:])
+            raise SendStaticFile(os.path.join(*path[1:]))
         else:
             self.classname = path[0]
             if len(path) > 1:
                 # send the file identified by the designator in path[0]
         else:
             self.classname = path[0]
             if len(path) > 1:
                 # send the file identified by the designator in path[0]
-                raise SendFile, path[0]
+                raise SendFile(path[0])
 
         # see if we got a designator
         m = dre.match(self.classname)
 
         # see if we got a designator
         m = dre.match(self.classname)
@@ -862,9 +866,9 @@ class Client:
             try:
                 klass = self.db.getclass(self.classname)
             except KeyError:
             try:
                 klass = self.db.getclass(self.classname)
             except KeyError:
-                raise NotFound, '%s/%s'%(self.classname, self.nodeid)
+                raise NotFound('%s/%s'%(self.classname, self.nodeid))
             if not klass.hasnode(self.nodeid):
             if not klass.hasnode(self.nodeid):
-                raise NotFound, '%s/%s'%(self.classname, self.nodeid)
+                raise NotFound('%s/%s'%(self.classname, self.nodeid))
             # with a designator, we default to item view
             self.template = 'item'
         else:
             # with a designator, we default to item view
             self.template = 'item'
         else:
@@ -875,7 +879,7 @@ class Client:
         try:
             self.db.getclass(self.classname)
         except KeyError:
         try:
             self.db.getclass(self.classname)
         except KeyError:
-            raise NotFound, self.classname
+            raise NotFound(self.classname)
 
         # see if we have a template override
         if template_override is not None:
 
         # see if we have a template override
         if template_override is not None:
@@ -886,30 +890,30 @@ class Client:
         """
         m = dre.match(str(designator))
         if not m:
         """
         m = dre.match(str(designator))
         if not m:
-            raise NotFound, str(designator)
+            raise NotFound(str(designator))
         classname, nodeid = m.group(1), m.group(2)
 
         try:
             klass = self.db.getclass(classname)
         except KeyError:
             # The classname was not valid.
         classname, nodeid = m.group(1), m.group(2)
 
         try:
             klass = self.db.getclass(classname)
         except KeyError:
             # The classname was not valid.
-            raise NotFound, str(designator)
+            raise NotFound(str(designator))
             
         # perform the Anonymous user access check
         self.check_anonymous_access()
 
         # make sure we have the appropriate properties
         props = klass.getprops()
             
         # perform the Anonymous user access check
         self.check_anonymous_access()
 
         # make sure we have the appropriate properties
         props = klass.getprops()
-        if not props.has_key('type'):
-            raise NotFound, designator
-        if not props.has_key('content'):
-            raise NotFound, designator
+        if 'type' not in props:
+            raise NotFound(designator)
+        if 'content' not in props:
+            raise NotFound(designator)
 
         # make sure we have permission
         if not self.db.security.hasPermission('View', self.userid,
                 classname, 'content', nodeid):
 
         # make sure we have permission
         if not self.db.security.hasPermission('View', self.userid,
                 classname, 'content', nodeid):
-            raise Unauthorisedself._("You are not allowed to view "
-                "this file.")
+            raise Unauthorised(self._("You are not allowed to view "
+                "this file."))
 
         mime_type = klass.get(nodeid, 'type')
         # Can happen for msg class:
 
         mime_type = klass.get(nodeid, 'type')
         # Can happen for msg class:
@@ -962,7 +966,7 @@ class Client:
             if os.path.isfile(filename) and filename.startswith(prefix):
                 break
         else:
             if os.path.isfile(filename) and filename.startswith(prefix):
                 break
         else:
-            raise NotFound, file
+            raise NotFound(file)
 
         # last-modified time
         lmt = os.stat(filename)[stat.ST_MTIME]
 
         # last-modified time
         lmt = os.stat(filename)[stat.ST_MTIME]
@@ -991,7 +995,7 @@ class Client:
         # XXX see which interfaces set this
         #if hasattr(self.request, 'headers'):
             #ims = self.request.headers.getheader('if-modified-since')
         # XXX see which interfaces set this
         #if hasattr(self.request, 'headers'):
             #ims = self.request.headers.getheader('if-modified-since')
-        if self.env.has_key('HTTP_IF_MODIFIED_SINCE'):
+        if 'HTTP_IF_MODIFIED_SINCE' in self.env:
             # cgi will put the header in the env var
             ims = self.env['HTTP_IF_MODIFIED_SINCE']
         if ims:
             # cgi will put the header in the env var
             ims = self.env['HTTP_IF_MODIFIED_SINCE']
         if ims:
@@ -1062,7 +1066,7 @@ class Client:
         except templating.NoTemplate, message:
             return '<strong>%s</strong>'%message
         except templating.Unauthorised, message:
         except templating.NoTemplate, message:
             return '<strong>%s</strong>'%message
         except templating.Unauthorised, message:
-            raise Unauthorised, str(message)
+            raise Unauthorised(str(message))
         except:
             # everything else
             if self.instance.config.WEB_DEBUG:
         except:
             # everything else
             if self.instance.config.WEB_DEBUG:
@@ -1080,7 +1084,7 @@ class Client:
                 # receive an error message, and the adminstrator will
                 # receive a traceback, albeit with less information
                 # than the one we tried to generate above.
                 # receive an error message, and the adminstrator will
                 # receive a traceback, albeit with less information
                 # than the one we tried to generate above.
-                raise exc_info[0], exc_info[1], exc_info[2]
+                raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
 
     # these are the actions that are available
     actions = (
 
     # these are the actions that are available
     actions = (
@@ -1110,9 +1114,9 @@ class Client:
             We explicitly catch Reject and ValueError exceptions and
             present their messages to the user.
         """
             We explicitly catch Reject and ValueError exceptions and
             present their messages to the user.
         """
-        if self.form.has_key(':action'):
+        if ':action' in self.form:
             action = self.form[':action'].value.lower()
             action = self.form[':action'].value.lower()
-        elif self.form.has_key('@action'):
+        elif '@action' in self.form:
             action = self.form['@action'].value.lower()
         else:
             return None
             action = self.form['@action'].value.lower()
         else:
             return None
@@ -1132,7 +1136,7 @@ class Client:
 
     def get_action_class(self, action_name):
         if (hasattr(self.instance, 'cgi_actions') and
 
     def get_action_class(self, action_name):
         if (hasattr(self.instance, 'cgi_actions') and
-                self.instance.cgi_actions.has_key(action_name)):
+                action_name in self.instance.cgi_actions):
             # tracker-defined action
             action_klass = self.instance.cgi_actions[action_name]
         else:
             # tracker-defined action
             action_klass = self.instance.cgi_actions[action_name]
         else:
@@ -1141,7 +1145,7 @@ class Client:
                 if name == action_name:
                     break
             else:
                 if name == action_name:
                     break
             else:
-                raise ValueError, 'No such action "%s"'%action_name
+                raise ValueError('No such action "%s"'%action_name)
         return action_klass
 
     def _socket_op(self, call, *args, **kwargs):
         return action_klass
 
     def _socket_op(self, call, *args, **kwargs):
@@ -1181,7 +1185,7 @@ class Client:
     def write_html(self, content):
         if not self.headers_done:
             # at this point, we are sure about Content-Type
     def write_html(self, content):
         if not self.headers_done:
             # at this point, we are sure about Content-Type
-            if not self.additional_headers.has_key('Content-Type'):
+            if 'Content-Type' not in self.additional_headers:
                 self.additional_headers['Content-Type'] = \
                     'text/html; charset=%s' % self.charset
             self.header()
                 self.additional_headers['Content-Type'] = \
                     'text/html; charset=%s' % self.charset
             self.header()
@@ -1343,14 +1347,14 @@ class Client:
                 return None
             # Return code 416 with a Content-Range header giving the
             # allowable range.
                 return None
             # Return code 416 with a Content-Range header giving the
             # allowable range.
-            self.response_code = httplib.REQUESTED_RANGE_NOT_SATISFIABLE
+            self.response_code = http_.client.REQUESTED_RANGE_NOT_SATISFIABLE
             self.setHeader("Content-Range", "bytes */%d" % length)
             return None
         # RFC 2616 10.2.7: 206 Partial Content
         #
         # Tell the client that we are honoring the Range request by
         # indicating that we are providing partial content.
             self.setHeader("Content-Range", "bytes */%d" % length)
             return None
         # RFC 2616 10.2.7: 206 Partial Content
         #
         # Tell the client that we are honoring the Range request by
         # indicating that we are providing partial content.
-        self.response_code = httplib.PARTIAL_CONTENT
+        self.response_code = http_.client.PARTIAL_CONTENT
         # RFC 2616 14.16: Content-Range
         #
         # Tell the client what data we are providing.
         # RFC 2616 14.16: Content-Range
         #
         # Tell the client what data we are providing.
@@ -1404,7 +1408,7 @@ class Client:
         # If the client doesn't actually want the body, or if we are
         # indicating an invalid range.
         if (self.env['REQUEST_METHOD'] == 'HEAD'
         # If the client doesn't actually want the body, or if we are
         # indicating an invalid range.
         if (self.env['REQUEST_METHOD'] == 'HEAD'
-            or self.response_code == httplib.REQUESTED_RANGE_NOT_SATISFIABLE):
+            or self.response_code == http_.client.REQUESTED_RANGE_NOT_SATISFIABLE):
             return
         # Use the optimized "sendfile" operation, if possible.
         if hasattr(self.request, "sendfile"):
             return
         # Use the optimized "sendfile" operation, if possible.
         if hasattr(self.request, "sendfile"):
@@ -1439,12 +1443,12 @@ class Client:
         if headers.get('Content-Type', 'text/html') == 'text/html':
             headers['Content-Type'] = 'text/html; charset=utf-8'
 
         if headers.get('Content-Type', 'text/html') == 'text/html':
             headers['Content-Type'] = 'text/html; charset=utf-8'
 
-        headers = headers.items()
+        headers = list(headers.items())
 
 
-        for ((path, name), (value, expire)) in self._cookies.items():
+        for ((path, name), (value, expire)) in self._cookies.iteritems():
             cookie = "%s=%s; Path=%s;"%(name, value, path)
             if expire is not None:
             cookie = "%s=%s; Path=%s;"%(name, value, path)
             if expire is not None:
-                cookie += " expires=%s;"%Cookie._getdate(expire)
+                cookie += " expires=%s;"%get_cookie_date(expire)
             headers.append(('Set-Cookie', cookie))
 
         self._socket_op(self.request.start_response, headers, response)
             headers.append(('Set-Cookie', cookie))
 
         self._socket_op(self.request.start_response, headers, response)