[Python-modules-commits] r914 - in /packages/clientcookie/branches/upstream/current: ./ ClientCookie.egg-info/ ClientCookie/ ez_setup/ test/

rganesan at users.alioth.debian.org rganesan at users.alioth.debian.org
Mon Jun 19 07:05:12 UTC 2006


Author: rganesan
Date: Mon Jun 19 07:05:08 2006
New Revision: 914

URL: http://svn.debian.org/wsvn/python-modules/?sc=1&rev=914
Log:
Load /tmp/tmp.PfozZ23183/clientcookie-1.3.0 into
packages/clientcookie/branches/upstream/current.

Added:
    packages/clientcookie/branches/upstream/current/README.txt
    packages/clientcookie/branches/upstream/current/cookietest.cgi   (with props)
Modified:
    packages/clientcookie/branches/upstream/current/COPYING.txt
    packages/clientcookie/branches/upstream/current/ChangeLog.txt
    packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/PKG-INFO
    packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/SOURCES.txt
    packages/clientcookie/branches/upstream/current/ClientCookie/_BSDDBCookieJar.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_ClientCookie.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_ConnCache.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_HeadersUtil.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_LWPCookieJar.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_MSIECookieJar.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_MSIEDBCookieJar.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_MozillaCookieJar.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_Opener.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_Request.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_Util.py
    packages/clientcookie/branches/upstream/current/ClientCookie/_urllib2_support.py
    packages/clientcookie/branches/upstream/current/GeneralFAQ.html
    packages/clientcookie/branches/upstream/current/INSTALL.txt
    packages/clientcookie/branches/upstream/current/MANIFEST.in
    packages/clientcookie/branches/upstream/current/PKG-INFO
    packages/clientcookie/branches/upstream/current/README.html
    packages/clientcookie/branches/upstream/current/README.html.in
    packages/clientcookie/branches/upstream/current/doc.html
    packages/clientcookie/branches/upstream/current/doc.html.in
    packages/clientcookie/branches/upstream/current/ez_setup/README.txt   (contents, props changed)
    packages/clientcookie/branches/upstream/current/ez_setup/__init__.py   (contents, props changed)
    packages/clientcookie/branches/upstream/current/functional_tests.py   (contents, props changed)
    packages/clientcookie/branches/upstream/current/setup.py   (contents, props changed)
    packages/clientcookie/branches/upstream/current/test.py   (props changed)
    packages/clientcookie/branches/upstream/current/test/test_headers.py
    packages/clientcookie/branches/upstream/current/test/test_misc.py
    packages/clientcookie/branches/upstream/current/test/test_urllib2.py

Modified: packages/clientcookie/branches/upstream/current/COPYING.txt
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/COPYING.txt?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/COPYING.txt (original)
+++ packages/clientcookie/branches/upstream/current/COPYING.txt Mon Jun 19 07:05:08 2006
@@ -1,6 +1,13 @@
-Copyright (c) 2002-2004 John J. Lee <jjl at pobox.com>
+Copyright (c) 2002-2006 John J. Lee <jjl at pobox.com>
 Copyright (c) 1997-1999 Gisle Aas
 Copyright (c) 1997-1999 Johnny Lee
+
+This software is dual-licensed: you may pick either of the licenses
+below.
+
+
+BSD-style license
+==================
 
 All rights reserved.
 
@@ -30,3 +37,27 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+ZPL 2.1
+==================
+
+Zope Public License (ZPL) Version 2.1
+
+A copyright notice accompanies this license document that identifies the copyright holders.
+
+This license has been certified as open source. It has also been designated as GPL compatible by the Free Software Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the following disclaimer.
+   2. Redistributions in binary form must reproduce the accompanying copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution.
+   3. Names of the copyright holders must not be used to endorse or promote products derived from this software without prior written permission from the copyright holders.
+   4. The right to distribute this software or to use it for any purpose does not give you the right to use Servicemarks (sm) or Trademarks (tm) of the copyright holders. Use of them is covered by separate agreement with the copyright holders.
+   5. If any files are modified, you must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
+
+Disclaimer
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Modified: packages/clientcookie/branches/upstream/current/ChangeLog.txt
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ChangeLog.txt?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ChangeLog.txt (original)
+++ packages/clientcookie/branches/upstream/current/ChangeLog.txt Mon Jun 19 07:05:08 2006
@@ -1,11 +1,41 @@
 This isn't really in proper GNU ChangeLog format, it just happens to
 look that way.
+
+2006-04-08 John J Lee <jjl at pobox.com>
+	* 1.3.0 release:
+	* Fix Refresh in case where the string "url" in the header value
+	  is in upper-case.
+	* Don't do broken XHTML handling by default (need to review code
+	  before switching this back on, e.g. should use a real XML parser
+	  for first-try at parsing).  HTTPEquivProcessor's
+	  i_want_broken_xhtml_support constructor argument gives the old
+	  behaviour.
+
+2006-03-23 John J Lee <jjl at pobox.com>
+	* 1.2.0 release:
+	* Stop trying to record precise dates in changelog, since that's
+	  silly ;-)
+	* ClientCookie is now dual-licensed: you may pick BSD or ZPL 2.1.
+	* ClientCookie.seek_wrapper instances can .copy()able, and the
+	  copies share a single cache (but response_seek_wrapper instances
+	  do not share header state, since the headers are mutable).
+	* Add .set_data() method to response_seek_wrapper.
+	* Support .code and .msg on response_seek_wrapper instances.
+	* Entity fixes (affects HTTP-EQUIV / Refresh handling).
+	* Allow decimal point in HTTP Refresh header pause times (Surachai
+	  Locharoen).
+	* setup.py fixes.
+
+2006-01-03 John J Lee <jjl at pobox.com>
+	* Released 1.1.1
 
 2006-01-02 John J Lee <jjl at pobox.com>
 	* Fix bug triggered by seek()ing past end of internal cache
 	  case in seek_wrapper.
 	* Tighten up seek_wrapper logic.
-	* Released 1.1.1
+	* Fixed HttpRefreshProcessor to handle default-URL case.
+	* Fixed functional tests (somebody's test page I was using went
+	  away, so I made a new test page on wwwsearch.sf.net).
 
 2005-12-03 John J Lee <jjl at pobox.com>
 	* Add setup.cfg for setuptools.

Modified: packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/PKG-INFO
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/PKG-INFO?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/PKG-INFO (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/PKG-INFO Mon Jun 19 07:05:08 2006
@@ -1,38 +1,39 @@
-Metadata-Version: 1.0
-Name: ClientCookie
-Version: 1.1.1
-Summary: Client-side HTTP cookie handling.
-Home-page: http://wwwsearch.sourceforge.net/ClientCookie/
-Author: John J. Lee
-Author-email: jjl at pobox.com
-License: BSD
-Download-URL: http://wwwsearch.sourceforge.net/ClientCookie/src/ClientCookie-1.1.1.tar.gz
-Description: ClientCookie is a Python module for handling HTTP cookies on the
-        client side, useful for accessing web sites that require cookies to be
-        set and then returned later.  It also provides some other (optional)
-        useful stuff: HTTP-EQUIV and Refresh handling, automatic adding of the
-        Referer [sic] header, robots.txt observance and lazily-seek()able
-        responses.  These extras are implemented using an extension that makes
-        it easier to add new functionality to urllib2 (now part of urllib2, as
-        of Python 2.4).  It has developed from a port of Gisle Aas' Perl
-        module HTTP::Cookies, from the libwww-perl library.
-        
-Platform: any
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Natural Language :: English
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Topic :: Internet
-Classifier: Topic :: Internet :: WWW/HTTP
-Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
-Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
-Classifier: Topic :: Internet :: WWW/HTTP :: Site Management :: Link Checking
-Classifier: Topic :: Software Development :: Libraries
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: Software Development :: Testing
-Classifier: Topic :: Software Development :: Testing :: Traffic Generation
-Classifier: Topic :: System :: Networking :: Monitoring
-Classifier: Topic :: System :: Systems Administration
+Metadata-Version: 1.0
+Name: ClientCookie
+Version: 1.3.0
+Summary: Client-side HTTP cookie handling.
+Home-page: http://wwwsearch.sourceforge.net/ClientCookie/
+Author: John J. Lee
+Author-email: jjl at pobox.com
+License: BSD
+Download-URL: http://wwwsearch.sourceforge.net/ClientCookie/src/ClientCookie-1.3.0.tar.gz
+Description: ClientCookie is a Python module for handling HTTP cookies on the
+        client side, useful for accessing web sites that require cookies to be
+        set and then returned later.  It also provides some other (optional)
+        useful stuff: HTTP-EQUIV and Refresh handling, automatic adding of the
+        Referer [sic] header, robots.txt observance and lazily-seek()able
+        responses.  These extras are implemented using an extension that makes
+        it easier to add new functionality to urllib2 (now part of urllib2, as
+        of Python 2.4).  It has developed from a port of Gisle Aas' Perl
+        module HTTP::Cookies, from the libwww-perl library.
+        
+Platform: any
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: System Administrators
+Classifier: License :: OSI Approved :: BSD License
+Classifier: License :: OSI Approved :: Zope Public License
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Internet
+Classifier: Topic :: Internet :: WWW/HTTP
+Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
+Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
+Classifier: Topic :: Internet :: WWW/HTTP :: Site Management :: Link Checking
+Classifier: Topic :: Software Development :: Libraries
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Software Development :: Testing
+Classifier: Topic :: Software Development :: Testing :: Traffic Generation
+Classifier: Topic :: System :: Networking :: Monitoring
+Classifier: Topic :: System :: Systems Administration

Modified: packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/SOURCES.txt
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/SOURCES.txt?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/SOURCES.txt (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie.egg-info/SOURCES.txt Mon Jun 19 07:05:08 2006
@@ -1,37 +1,40 @@
-COPYING
-ChangeLog
-GeneralFAQ.html
-INSTALL
-MANIFEST.in
-README.html
-README.html.in
-doc.html
-doc.html.in
-functional_tests.py
-setup.py
-test.py
-ClientCookie/_BSDDBCookieJar.py
-ClientCookie/_ClientCookie.py
-ClientCookie/_ConnCache.py
-ClientCookie/_Debug.py
-ClientCookie/_HeadersUtil.py
-ClientCookie/_LWPCookieJar.py
-ClientCookie/_MSIECookieJar.py
-ClientCookie/_MSIEDBCookieJar.py
-ClientCookie/_MozillaCookieJar.py
-ClientCookie/_Opener.py
-ClientCookie/_Request.py
-ClientCookie/_Util.py
-ClientCookie/__init__.py
-ClientCookie/_urllib2_support.py
-ClientCookie.egg-info/PKG-INFO
-ClientCookie.egg-info/top_level.txt
-ClientCookie.egg-info/zip-safe
-ez_setup/README.txt
-ez_setup/__init__.py
-test/test_conncache.py
-test/test_cookies.py
-test/test_date.py
-test/test_headers.py
-test/test_misc.py
-test/test_urllib2.py
+COPYING.txt
+ChangeLog.txt
+GeneralFAQ.html
+INSTALL.txt
+MANIFEST.in
+README.html
+README.html.in
+README.txt
+cookietest.cgi
+doc.html
+doc.html.in
+functional_tests.py
+setup.py
+test.py
+ClientCookie/_BSDDBCookieJar.py
+ClientCookie/_ClientCookie.py
+ClientCookie/_ConnCache.py
+ClientCookie/_Debug.py
+ClientCookie/_HeadersUtil.py
+ClientCookie/_LWPCookieJar.py
+ClientCookie/_MSIECookieJar.py
+ClientCookie/_MSIEDBCookieJar.py
+ClientCookie/_MozillaCookieJar.py
+ClientCookie/_Opener.py
+ClientCookie/_Request.py
+ClientCookie/_Util.py
+ClientCookie/__init__.py
+ClientCookie/_urllib2_support.py
+ClientCookie.egg-info/PKG-INFO
+ClientCookie.egg-info/SOURCES.txt
+ClientCookie.egg-info/top_level.txt
+ClientCookie.egg-info/zip-safe
+ez_setup/README.txt
+ez_setup/__init__.py
+test/test_conncache.py
+test/test_cookies.py
+test/test_date.py
+test/test_headers.py
+test/test_misc.py
+test/test_urllib2.py

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_BSDDBCookieJar.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_BSDDBCookieJar.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_BSDDBCookieJar.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_BSDDBCookieJar.py Mon Jun 19 07:05:08 2006
@@ -2,9 +2,9 @@
 
 Copyright 2003-2006 John J Lee <jjl at pobox.com>
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 **********************************************************************
 THIS IS NOT FULLY TESTED!

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_ClientCookie.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_ClientCookie.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_ClientCookie.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_ClientCookie.py Mon Jun 19 07:05:08 2006
@@ -26,13 +26,13 @@
 Copyright 1997-1999 Gisle Aas (original libwww-perl code)
 Copyright 2002-2003 Johnny Lee (original MSIE Perl code)
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 
-VERSION = "1.1.1"
+VERSION = "1.3.0"
 
 
 # Public health warning: anyone who thought 'cookies are simple, aren't they?',

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_ConnCache.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_ConnCache.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_ConnCache.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_ConnCache.py Mon Jun 19 07:05:08 2006
@@ -16,9 +16,9 @@
 Copyright (C) 2004-2006 John J Lee <jjl at pobox.com>.
 Copyright (C) 2001 Gisle Aas.
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_HeadersUtil.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_HeadersUtil.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_HeadersUtil.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_HeadersUtil.py Mon Jun 19 07:05:08 2006
@@ -3,9 +3,9 @@
 Copyright 1997-1998, Gisle Aas
 Copyright 2002-2006, John J. Lee
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 
@@ -24,7 +24,7 @@
     True = 1
     False = 0
 
-def is_html(ct_headers, url):
+def is_html(ct_headers, url, allow_xhtml=False):
     """
     ct_headers: Sequence of Content-Type headers
     url: Response URL
@@ -33,13 +33,19 @@
     if not ct_headers:
         # guess
         ext = os.path.splitext(urlparse.urlparse(url)[2])[1]
-        return ext in ['.htm', '.html', '.xhtml']
+        html_exts = [".htm", ".html"]
+        if allow_xhtml:
+            html_exts += [".xhtml"]
+        return ext in html_exts
     # use first header
     ct = split_header_words(ct_headers)[0][0][0]
-    return ct in [
-        "text/html", "text/xhtml", "text/xml",
-        "application/xml", "application/xhtml+xml",
-        ]
+    html_types = ["text/html"]
+    if allow_xhtml:
+        html_types += [
+            "text/xhtml", "text/xml",
+            "application/xml", "application/xhtml+xml",
+            ]
+    return ct in html_types
 
 def unmatched(match):
     """Return unmatched part of re.Match object."""

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_LWPCookieJar.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_LWPCookieJar.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_LWPCookieJar.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_LWPCookieJar.py Mon Jun 19 07:05:08 2006
@@ -12,9 +12,9 @@
 Copyright 2002-2006 John J Lee <jjl at pobox.com>
 Copyright 1997-1999 Gisle Aas (original libwww-perl code)
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_MSIECookieJar.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_MSIECookieJar.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_MSIECookieJar.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_MSIECookieJar.py Mon Jun 19 07:05:08 2006
@@ -3,9 +3,9 @@
 Copyright 2002-2003 Johnny Lee <typo_pl at hotmail.com> (MSIE Perl code)
 Copyright 2002-2006 John J Lee <jjl at pobox.com> (The Python port)
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_MSIEDBCookieJar.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_MSIEDBCookieJar.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_MSIEDBCookieJar.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_MSIEDBCookieJar.py Mon Jun 19 07:05:08 2006
@@ -2,9 +2,9 @@
 
 Copyright 2003-2006 John J Lee <jjl at pobox.com>
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 **********************************************************************
 THIS DOESN'T WORK!

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_MozillaCookieJar.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_MozillaCookieJar.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_MozillaCookieJar.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_MozillaCookieJar.py Mon Jun 19 07:05:08 2006
@@ -3,9 +3,9 @@
 Copyright 2002-2006 John J Lee <jjl at pobox.com>
 Copyright 1997-1999 Gisle Aas (original libwww-perl code)
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_Opener.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_Opener.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_Opener.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_Opener.py Mon Jun 19 07:05:08 2006
@@ -3,9 +3,9 @@
 
 Copyright 2004-2006 John J Lee <jjl at pobox.com>
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_Request.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_Request.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_Request.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_Request.py Mon Jun 19 07:05:08 2006
@@ -2,9 +2,9 @@
 
 Copyright 2004-2006 John J Lee <jjl at pobox.com>
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_Util.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_Util.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_Util.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_Util.py Mon Jun 19 07:05:08 2006
@@ -2,9 +2,9 @@
 
  Copyright 2002-2006 John J Lee <jjl at pobox.com>
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 
@@ -13,9 +13,9 @@
     True = 1
     False = 0
 
-import re, string, time
+import re, string, time, copy, urllib
 from types import TupleType
-from StringIO import StringIO
+from cStringIO import StringIO
 
 try:
     from exceptions import StopIteration
@@ -399,18 +399,17 @@
     particular file object.
 
     """
-    # General strategy is to check that cache is full enough, then delegate
-    # everything to the cache (self._cache, which is a StringIO.StringIO
-    # instance.  Seems to be some cStringIO.StringIO problem on 1.5.2 -- I
-    # get a StringOobject, with no readlines method.
-
-    # XXX Does this work sensibly in the face of exceptions raised by .read()
-    # / .readline()??
+    # General strategy is to check that cache is full enough, then delegate to
+    # the cache (self.__cache, which is a cStringIO.StringIO instance).  A seek
+    # position (self.__pos) is maintained independently of the cache, in order
+    # that a single cache may be shared between multiple seek_wrapper objects.
+    # Copying using module copy shares the cache in this way.
 
     def __init__(self, wrapped):
         self.wrapped = wrapped
         self.__have_readline = hasattr(self.wrapped, "readline")
         self.__cache = StringIO()
+        self.__pos = 0  # seek position
 
     def invariant(self):
         # The end of the cache is always at the same place as the end of the
@@ -425,59 +424,78 @@
 
     def seek(self, offset, whence=0):
         assert whence in [0,1,2]
-        # make sure we have read all data up to the point we are seeking to
-        pos = self.__cache.tell()
 
         # how much data, if any, do we need to read?
         if whence == 2:  # 2: relative to end of *wrapped* file
+            if offset < 0: raise ValueError("negative seek offset")
             # since we don't know yet where the end of that file is, we must
             # read everything
             to_read = None
         else:
             if whence == 0:  # 0: absolute
-                want = offset - pos
+                if offset < 0: raise ValueError("negative seek offset")
+                dest = offset
             else:  # 1: relative to current position
-                want = offset
+                pos = self.__pos
+                if pos < offset:
+                    raise ValueError("seek to before start of file")
+                dest = pos + offset
             end = len(self.__cache.getvalue())
-            available = end - pos
-            if want <= available:
+            to_read = dest - end
+            if to_read < 0:
                 to_read = 0
-            else:
-                to_read = want - available
 
         if to_read != 0:
             self.__cache.seek(0, 2)
             if to_read is None:
+                assert whence == 2
                 self.__cache.write(self.wrapped.read())
+                self.__pos = self.__cache.tell() - offset
             else:
                 self.__cache.write(self.wrapped.read(to_read))
-            self.__cache.seek(pos)
-
-        return self.__cache.seek(offset, whence)
+                # Don't raise an exception even if we've seek()ed past the end
+                # of .wrapped, since fseek() doesn't complain in that case.
+                # Also like fseek(), pretend we have seek()ed past the end,
+                # i.e. not:
+                #self.__pos = self.__cache.tell()
+                # but rather:
+                self.__pos = dest
+        else:
+            self.__pos = dest
 
     def tell(self):
-        return self.__cache.tell()
+        return self.__pos
+
+    def __copy__(self):
+        cpy = self.__class__(self.wrapped)
+        cpy.__cache = self.__cache
+        return cpy
 
     def read(self, size=-1):
-        pos = self.__cache.tell()
+        pos = self.__pos
         end = len(self.__cache.getvalue())
         available = end - pos
 
         # enough data already cached?
         if size <= available and size != -1:
+            self.__cache.seek(pos)
+            self.__pos = pos+size
             return self.__cache.read(size)
 
         # no, so read sufficient data from wrapped file and cache it
-        to_read = size - available
-        assert to_read > 0 or size == -1
         self.__cache.seek(0, 2)
         if size == -1:
             self.__cache.write(self.wrapped.read())
         else:
+            to_read = size - available
+            assert to_read > 0
             self.__cache.write(self.wrapped.read(to_read))
         self.__cache.seek(pos)
 
-        return self.__cache.read(size)
+        data = self.__cache.read(size)
+        self.__pos = self.__cache.tell()
+        assert self.__pos == pos + len(data)
+        return data
 
     def readline(self, size=-1):
         if not self.__have_readline:
@@ -485,7 +503,7 @@
 
         # line we're about to read might not be complete in the cache, so
         # read another line first
-        pos = self.__cache.tell()
+        pos = self.__pos
         self.__cache.seek(0, 2)
         self.__cache.write(self.wrapped.readline())
         self.__cache.seek(pos)
@@ -493,20 +511,20 @@
         data = self.__cache.readline()
         if size != -1:
             r = data[:size]
-            self.__cache.seek(pos+size)
+            self.__pos = pos+size
         else:
             r = data
+            self.__pos = pos+len(data)
         return r
 
     def readlines(self, sizehint=-1):
-        pos = self.__cache.tell()
+        pos = self.__pos
         self.__cache.seek(0, 2)
         self.__cache.write(self.wrapped.read())
         self.__cache.seek(pos)
-        try:
-            return self.__cache.readlines(sizehint)
-        except TypeError:  # 1.5.2 hack
-            return self.__cache.readlines()
+        data = self.__cache.readlines(sizehint)
+        self.__pos = self.__cache.tell()
+        return data
 
     def __iter__(self): return self
     def next(self):
@@ -517,34 +535,63 @@
     xreadlines = __iter__
 
     def __repr__(self):
-        return ("<%s at %s whose wrapped object = %s>" %
-                (self.__class__.__name__, `id(self)`, `self.wrapped`))
-
-    def close(self):
-        self.__cache = None
-        self.read = None
-        self.readline = None
-        self.readlines = None
-        self.seek = None
-        if self.wrapped: self.wrapped.close()
-        self.wrapped = None
+        return ("<%s at %s whose wrapped object = %r>" %
+                (self.__class__.__name__, hex(id(self)), self.wrapped))
+
+
+class response_seek_wrapper(seek_wrapper):
+
+    """
+    Supports copying response objects and setting response body data.
+
+    """
+
+    def __init__(self, wrapped):
+        seek_wrapper.__init__(self, wrapped)
+        self._headers = self.wrapped.info()
+
+    def __copy__(self):
+        cpy = seek_wrapper.__copy__(self)
+        # copy headers from delegate
+        cpy._headers = copy.copy(self.info())
+        return cpy
+
+    def info(self):
+        return self._headers
+
+    def set_data(self, data):
+        self.seek(0)
+        self.read()
+        self.close()
+        cache = self._seek_wrapper__cache = StringIO()
+        cache.write(data)
+        self.seek(0)
+
 
 class eoffile:
     # file-like object that always claims to be at end-of-file...
     def read(self, size=-1): return ""
     def readline(self, size=-1): return ""
-    # ...and also supports these response methods
-    def info(self):
-        return self.headers
-    def geturl(self):
-        return self.url
-
-
-class response_seek_wrapper(seek_wrapper):
+    def __iter__(self): return self
+    def next(self): return ""
+    def close(self): pass
+
+class eofresponse(eoffile):
+    def __init__(self, url, headers, code, msg):
+        self._url = url
+        self._headers = headers
+        self.code = code
+        self.msg = msg
+    def geturl(self): return self._url
+    def info(self): return self._headers
+
+
+class closeable_response:
     """Avoids unnecessarily clobbering urllib.addinfourl methods on .close().
 
-    After .close():
-    , the following methods are supported:
+    Only supports responses returned by ClientCookie.HTTPHandler.
+
+    After .close(), the following methods are supported:
 
     .read()
     .readline()
@@ -555,16 +602,55 @@
     .geturl()
     .__iter__()
     .next()
-
-    Also supports pickling.
-
-    """
+    .close()
+
+    and the following attributes are supported:
+
+    .code
+    .msg
+
+    Also supports pickling (but the stdlib currently does something to prevent
+    it: http://python.org/sf/1144636).
+
+    """
+
+    def __init__(self, fp, headers, url, code, msg):
+        self._set_fp(fp)
+        self._headers = headers
+        self._url = url
+        self.code = code
+        self.msg = msg
+
+    def _set_fp(self, fp):
+        self.fp = fp
+        self.read = self.fp.read
+        self.readline = self.fp.readline
+        if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines
+        if hasattr(self.fp, "fileno"):
+            self.fileno = self.fp.fileno
+        else:
+            self.fileno = lambda: None
+        if hasattr(self.fp, "__iter__"):
+            self.__iter__ = self.fp.__iter__
+            if hasattr(self.fp, "next"):
+                self.next = self.fp.next
+
+    def __repr__(self):
+        return '<%s at %s whose fp = %r>' % (
+            self.__class__.__name__, hex(id(self)), self.fp)
+
+    def info(self):
+        return self._headers
+
+    def geturl(self):
+        return self._url
 
     def close(self):
-        self.headers = self.wrapped.headers
-        self.url = self.wrapped.url
-        self.wrapped.close()
-        self.wrapped = eoffile()
+        wrapped = self.fp
+        wrapped.close()
+        new_wrapped = eofresponse(
+            self._url, self._headers, self.code, self.msg)
+        self._set_fp(new_wrapped)
 
     def __getstate__(self):
         # There are three obvious options here:
@@ -579,5 +665,7 @@
         # So we do 1.
 
         state = self.__dict__.copy()
-        state["wrapped"] = eoffile()
+        new_wrapped = eofresponse(
+            self._url, self._headers, self.code, self.msg)
+        state["wrapped"] = new_wrapped
         return state

Modified: packages/clientcookie/branches/upstream/current/ClientCookie/_urllib2_support.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ClientCookie/_urllib2_support.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ClientCookie/_urllib2_support.py (original)
+++ packages/clientcookie/branches/upstream/current/ClientCookie/_urllib2_support.py Mon Jun 19 07:05:08 2006
@@ -5,17 +5,17 @@
 
 Copyright 2002-2006 John J Lee <jjl at pobox.com>
 
-This code is free software; you can redistribute it and/or modify it under
-the terms of the BSD License (see the file COPYING included with the
-distribution).
+This code is free software; you can redistribute it and/or modify it
+under the terms of the BSD or ZPL 2.1 licenses (see the file
+COPYING.txt included with the distribution).
 
 """
 
-import copy, time, tempfile
+import copy, time, tempfile, htmlentitydefs, re
 
 import ClientCookie
 from _ClientCookie import CookieJar, request_host
-from _Util import isstringlike, startswith, getheaders
+from _Util import isstringlike, startswith, getheaders, closeable_response
 from _HeadersUtil import is_html
 from _Debug import getLogger
 debug = getLogger("ClientCookie.cookies").debug
@@ -27,6 +27,7 @@
 
 
 CHUNK = 1024  # size of chunks fed to HTML HEAD parser, in bytes
+DEFAULT_ENCODING = 'latin-1'
 
 try:
     from urllib2 import AbstractHTTPHandler
@@ -35,6 +36,8 @@
 else:
     import urlparse, urllib2, urllib, httplib
     import sgmllib
+    # monkeypatch to fix http://www.python.org/sf/803422 :-(
+    sgmllib.charref = re.compile("&#(x?[0-9a-fA-F]+)[^0-9a-fA-F]")
     from urllib2 import URLError, HTTPError
     import types, string, socket
     from cStringIO import StringIO
@@ -177,28 +180,120 @@
         https_request = http_request
 
 
-   # XXX would self.reset() work, instead of raising this exception?
+    # -------------------------------------------------------------------
+    # Beware, the following encoding code is cut-and-pasted between
+    # ClientCookie, ClientForm, mechanize and pullparser, and they differ
+    # subtly :-(((
+    # This particular variant is identical to that in mechanize.
+
+    def unescape(data, entities, encoding):
+        if data is None or "&" not in data:
+            return data
+
+        def replace_entities(match, entities=entities, encoding=encoding):
+            ent = match.group()
+            if ent[1] == "#":
+                return unescape_charref(ent[2:-1], encoding)
+
+            repl = entities.get(ent[1:-1])
+            if repl is not None:
+                repl = unichr(repl)
+                if type(repl) != type(""):
+                    try:
+                        repl = repl.encode(encoding)
+                    except UnicodeError:
+                        repl = ent
+            else:
+                repl = ent
+            return repl
+
+        return re.sub(r"&#?[A-Za-z0-9]+?;", replace_entities, data)
+
+    def unescape_charref(data, encoding):
+        name, base = data, 10
+        if name.startswith("x"):
+            name, base= name[1:], 16
+        uc = unichr(int(name, base))
+        if encoding is None:
+            return uc
+        else:
+            try:
+                repl = uc.encode(encoding)
+            except UnicodeError:
+                repl = "&#%s;" % data
+            return repl
+
+    def get_entitydefs():
+        from codecs import latin_1_decode
+        try:
+            htmlentitydefs.name2codepoint
+        except AttributeError:
+            entitydefs = {}
+            for name, char in htmlentitydefs.entitydefs.items():
+                uc = latin_1_decode(char)[0]
+                if uc.startswith("&#") and uc.endswith(";"):
+                    uc = unescape_charref(uc[2:-1], None)
+                codepoint = ord(uc)
+                entitydefs[name] = codepoint
+        else:
+            entitydefs = htmlentitydefs.name2codepoint
+        return entitydefs
+
+    # -------------------------------------------------------------------
+
+
+    # XXX would self.reset() work, instead of raising this exception?
     class EndOfHeadError(Exception): pass
     class AbstractHeadParser:
         # only these elements are allowed in or before HEAD of document
         head_elems = ("html", "head",
                       "title", "base",
                       "script", "style", "meta", "link", "object")
+        _entitydefs = get_entitydefs()
+        _encoding = DEFAULT_ENCODING
 
         def __init__(self):
             self.http_equiv = []
+
         def start_meta(self, attrs):
             http_equiv = content = None
             for key, value in attrs:
                 if key == "http-equiv":
-                    http_equiv = value
+                    http_equiv = self.unescape_attr_if_required(value)
                 elif key == "content":
-                    content = value
+                    content = self.unescape_attr_if_required(value)
             if http_equiv is not None:
                 self.http_equiv.append((http_equiv, content))
 
         def end_head(self):
             raise EndOfHeadError()
+
+        def handle_entityref(self, name):
+            #debug("%s", name)
+            self.handle_data(unescape(
+                '&%s;' % name, self._entitydefs, self._encoding))
+
+        def handle_charref(self, name):
+            #debug("%s", name)
+            self.handle_data(unescape_charref(name, self._encoding))
+
+        def unescape_attr(self, name):
+            #debug("%s", name)
+            return unescape(name, self._entitydefs, self._encoding)
+
+        def unescape_attrs(self, attrs):
+            #debug("%s", attrs)
+            escaped_attrs = {}
+            for key, val in attrs.items():
+                escaped_attrs[key] = self.unescape_attr(val)
+            return escaped_attrs
+
+        def unknown_entityref(self, ref):
+            self.handle_data("&%s;" % ref)
+
+        def unknown_charref(self, ref):
+            self.handle_data("&#%s;" % ref)
+
 
     try:
         import HTMLParser
@@ -236,36 +331,13 @@
                 else:
                     method()
 
-            # handle_charref, handle_entityref and default entitydefs are taken
-            # from sgmllib
-            def handle_charref(self, name):
-                try:
-                    n = int(name)
-                except ValueError:
-                    self.unknown_charref(name)
-                    return
-                if not 0 <= n <= 255:
-                    self.unknown_charref(name)
-                    return
-                self.handle_data(chr(n))
-
-            # Definition of entities -- derived classes may override
-            entitydefs = \
-                    {'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}
-
-            def handle_entityref(self, name):
-                table = self.entitydefs
-                if name in table:
-                    self.handle_data(table[name])
-                else:
-                    self.unknown_entityref(name)
-                    return
-
-            def unknown_entityref(self, ref):
-                self.handle_data("&%s;" % ref)
-
-            def unknown_charref(self, ref):
-                self.handle_data("&#%s;" % ref)
+            def unescape(self, name):
+                # Use the entitydefs passed into constructor, not
+                # HTMLParser.HTMLParser's entitydefs.
+                return self.unescape_attr(name)
+
+            def unescape_attr_if_required(self, name):
+                return name  # HTMLParser.HTMLParser already did it
 
     class HeadParser(AbstractHeadParser, sgmllib.SGMLParser):
 
@@ -290,6 +362,9 @@
                 method()
             else:
                 raise EndOfHeadError()
+
+        def unescape_attr_if_required(self, name):
+            return self.unescape_attr(name)
 
     def parse_head(fileobj, parser):
         """Return a list of key, value pairs."""
@@ -310,8 +385,11 @@
 
         handler_order = 300  # before handlers that look at HTTP headers
 
-        def __init__(self, head_parser_class=HeadParser):
+        def __init__(self, head_parser_class=HeadParser,
+                     i_want_broken_xhtml_support=False,
+                     ):
             self.head_parser_class = head_parser_class
+            self._allow_xhtml = i_want_broken_xhtml_support
 
         def http_response(self, request, response):
             if not hasattr(response, "seek"):
@@ -319,7 +397,7 @@
             headers = response.info()
             url = response.geturl()
             ct_hdrs = getheaders(response.info(), "content-type")
-            if is_html(ct_hdrs, url):
+            if is_html(ct_hdrs, url, self._allow_xhtml):
                 try:
                     try:
                         html_headers = parse_head(response, self.head_parser_class())
@@ -502,17 +580,17 @@
                 refresh = getheaders(hdrs, "refresh")[0]
                 ii = string.find(refresh, ";")
                 if ii != -1:
-                    pause, newurl_spec = int(refresh[:ii]), refresh[ii+1:]
+                    pause, newurl_spec = float(refresh[:ii]), refresh[ii+1:]
                     jj = string.find(newurl_spec, "=")
                     if jj != -1:
                         key, newurl = newurl_spec[:jj], newurl_spec[jj+1:]
-                    if key.strip() != "url":
+                    if key.strip().lower() != "url":
                         debug("bad Refresh header: %r" % refresh)
                         return response
                 else:
-                    pause, newurl = int(refresh), response.geturl()
+                    pause, newurl = float(refresh), response.geturl()
                 if (self.max_time is None) or (pause <= self.max_time):
-                    if pause != 0 and self.honor_time:
+                    if pause > 1E-3 and self.honor_time:
                         time.sleep(pause)
                     hdrs["location"] = newurl
                     # hardcoded http is NOT a bug
@@ -629,9 +707,8 @@
             r.recv = r.read
             fp = socket._fileobject(r, 'rb', -1)
 
-            resp = urllib.addinfourl(fp, r.msg, req.get_full_url())
-            resp.code = r.status
-            resp.msg = r.reason
+            resp = closeable_response(fp, r.msg, req.get_full_url(),
+                                      r.status, r.reason)
             return resp
 
 

Modified: packages/clientcookie/branches/upstream/current/GeneralFAQ.html
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/GeneralFAQ.html?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/GeneralFAQ.html (original)
+++ packages/clientcookie/branches/upstream/current/GeneralFAQ.html Mon Jun 19 07:05:08 2006
@@ -1,169 +1,169 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
-
-
-
-
-<html>
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-  <meta name="author" content="John J. Lee &lt;jjl at pobox.com&gt;">
-  <meta name="date" content="2006-01-05">
-  <meta name="keywords" content="FAQ,cookie,HTTP,HTML,form,table,Python,web,client,client-side,testing,sniffer,https,script,embedded">
-  <title>Python web-client programming general FAQs</title>
-  <style type="text/css" media="screen">@import "../styles/style.css";</style>
-  <base href="http://wwwsearch.sourceforge.net/bits/clientx.html">
-</head>
-<body>
-
-<div id="sf"><a href="http://sourceforge.net">
-<img src="http://sourceforge.net/sflogo.php?group_id=48205&amp;type=2"
- width="125" height="37" alt="SourceForge.net Logo"></a></div>
-<!--<img src="../images/sflogo.png"-->
-
-<h1>Python web-client programming general FAQs</h1>
-
-<div id="Content">
-<ul>
-  <li>Is there any example code?
-     <p>There's (still!) a bit of a shortage of example code for ClientCookie
-     and ClientForm &amp;co., because the stuff I've written tends to either
-     require access to restricted-access sites, or is proprietary code (and the
-     same goes for other people's code).
-  <li>HTTPS on Windows?
-     <p>Use this <a href="http://pypgsql.sourceforge.net/misc/python22-win32-ssl.zip">
-     _socket.pyd</a>, or use Python 2.3.
-  <li>I want to see what my web browser is doing, but standard network sniffers
-     like <a href="http://www.ethereal.com/">ethereal</a> or netcat (nc) don't
-     work for HTTPS.  How do I sniff HTTPS traffic?
-  <p>Three good options:
-  <ul>
-    <li>Mozilla plugin: <a href="http://livehttpheaders.mozdev.org/">
-     livehttpheaders</a>.
-    <li><a href="http://www.blunck.info/iehttpheaders.html">ieHTTPHeaders</a>
-     does the same for MSIE.
-    <li>Use <a href="http://lynx.browser.org/">lynx</a> <code>-trace</code>,
-     and filter out the junk with a script.
-  </ul>
-  <p>I'm told you can also use a proxy like <a
-  href="http://www.proxomitron.info/">proxomitron</a> (never tried it
-  myself).  There's also a commercial <a href="http://www.simtec.ltd.uk/">MSIE
-  plugin</a>.
-  <li>Embedded script is messing up my web-scraping.  What do I do?
-     <p>It is possible to embed script in HTML pages (sandwiched between
-     <code>&lt;SCRIPT&gt;here&lt;/SCRIPT&gt;</code> tags, and in
-     <code>javascript:</code> URLs) - JavaScript / ECMAScript, VBScript, or
-     even Python.  These scripts can do all sorts of things, including causing
-     cookies to be set in a browser, submitting or filling in parts of forms in
-     response to user actions, changing link colours as the mouse moves over a
-     link, etc.
-
-     <p>If you come across this in a page you want to automate, you
-     have four options.  Here they are, roughly in order of simplicity.
-
-     <ul>
-       <li>Simply figure out what the embedded script is doing and emulate it
-       in your Python code: for example, by manually adding cookies to your
-       <code>CookieJar</code> instance, calling methods on
-       <code>HTMLForm</code>s, calling <code>urlopen</code>, etc.
-
-       <li>Dump ClientCookie and ClientForm and automate a browser instead.
-       For example use MS Internet Explorer via its COM automation interfaces, using
-       the <a href="http://starship.python.net/crew/mhammond/">Python for
-       Windows extensions</a>, aka pywin32, aka win32all (eg.
-       <a href="http://vsbabu.org/mt/archives/2003/06/13/ie_automation.html">simple
-       function</a>, <a href="http://pamie.sourceforge.net/">pamie</a>;
-       <a href="http://www.oreilly.com/catalog/pythonwin32/chapter/ch12.html">
-       pywin32 chapter from the O'Reilly book</a>) or
-       <a href="http://starship.python.net/crew/theller/ctypes/">ctypes</a>
-       (<a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/305273">
-       example</a>: may be out of date, since <code>ctypes</code>' COM support is
-       still evolving).
-       <a href="http://www.brunningonline.net/simon/blog/archives/winGuiAuto.py.html">This</a>
-       kind of thing may also come in useful on Windows for cases where the
-       automation API is lacking.
-       <a href="http://ftp.acc.umu.se/pub/GNOME/sources/pyphany/">pyphany</a>
-       is a binding to the <a href="http://www.gnome.org/projects/epiphany/">
-       epiphany web browser</a>, allowing both plugins and automation code to be
-       written in Python.
-       XXX Mozilla automation &amp; XPCOM / PyXPCOM, Konqueror &amp; DCOP / KParts / PyKDE).
-
-       <li>Use Java's <a href="httpunit.sourceforge.net">httpunit</a> from
-       Jython, since it knows some JavaScript.
-       <li>Get ambitious and automatically delegate the work to an appropriate
-       interpreter (Mozilla's JavaScript interpreter, for instance).  This
-       approach is the one taken by <a href="../DOMForm">DOMForm</a> (the
-       JavaScript support is &quot;very alpha&quot;, though!).
-     </ul>
-  <li>Misc links
-     <ul>
-       <li><a href="http://www.crummy.com/software/BeautifulSoup/">Beautiful
-       Soup</a> is a widely recommended HTML-parsing module.
-       <li><a href="http://linux.duke.edu/projects/urlgrabber/">urlgrabber</a>
-       contains useful stuff like persistent connections, mirroring and
-       throttling, and it looks like most or all of it is well-integrated with
-       <code>urllib2</code> (originally part of the yum package manager, but
-       now becoming a separate project).
-       <li>Another Java thing: <a href="http://maxq.tigris.org/">maxq</a>,
-       which provides a proxy to aid automatic generation of functional tests
-       written in Jython using the standard library unittest module (PyUnit)
-       and the &quot;Jakarta Commons&quot; HttpClient library.
-       <li>A useful set Zope-oriented links on <a
-       href="http://viii.dclxvi.org/bookmarks/tech/zope/test">tools for testing
-       web applications</a>.
-       <li>O'Reilly book: <a href="">Spidering Hacks</a>.  Very Perl-oriented.
-       <li>Useful
-       <a href="http://chrispederick.com/work/webdeveloper/"> Firefox extension
-       </a> which, amongst other things, can display HTML form information and
-       HTML table structure(thanks to Erno Kuusela for this link).
-       <li>
-       <a href="http://www.openqa.org/selenium/">Selenium</a>: In-browser web
-       functional testing.
-       <li><a href="http://www.opensourcetesting.org/functional.php">Open
-       source functional testing tools</a>.  A nice list.
-       <li><a href="http://www.rexx.com/~dkuhlman/quixote_htmlscraping.html">
-       A HOWTO on web scraping</a> from Dave Kuhlman.
-     </ul>
-  <li>Will any of this code make its way into the Python standard library?
-
-  <p>The request / response processing extensions to <code>urllib2</code> from
-     ClientCookie have been merged into <code>urllib2</code> for Python 2.4.
-     The cookie processing has been added, as module <code>cookielib</code>.
-     Eventually, I'll submit patches to get the http-equiv, refresh, and
-     robots.txt code in there too, and maybe <code>mechanize.UserAgent</code>
-     too (but <em>not</em> <code>mechanize.Browser</code>).  The rest, probably
-     not.
-
-</ul>
-
-<p>I prefer questions and comments to be sent to the <a
-href="http://lists.sourceforge.net/lists/listinfo/wwwsearch-general">
-mailing list</a> rather than direct to me.
-
-<p><a href="mailto:jjl at pobox.com">John J. Lee</a>,
-January 2006.
-
-</div> <!--id="Content"-->
-
-<div id="Menu">
-
-<a href="..">Home</a><br>
-<br>
-<span class="thispage">General FAQs</span><br>
-<br>
-<a href="../mechanize/">mechanize</a><br>
-<a href="../pullparser/">pullparser</a><br>
-<a href="../ClientCookie/">ClientCookie</a><br>
-<a href="../ClientCookie/doc.html"><span class="subpage">ClientCookie docs</span></a><br>
-<a href="../ClientForm/">ClientForm</a><br>
-<br>
-<a href="../DOMForm/">DOMForm</a><br>
-<a href="../python-spidermonkey/">python-spidermonkey</a><br>
-<a href="../ClientTable/">ClientTable</a><br>
-<a href="../bits/urllib2_152.py">1.5.2 urllib2.py</a><br>
-<a href="../bits/urllib_152.py">1.5.2 urllib.py</a><br>
-
-<br>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+
+
+
+
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="author" content="John J. Lee &lt;jjl at pobox.com&gt;">
+  <meta name="date" content="2006-01-05">
+  <meta name="keywords" content="FAQ,cookie,HTTP,HTML,form,table,Python,web,client,client-side,testing,sniffer,https,script,embedded">
+  <title>Python web-client programming general FAQs</title>
+  <style type="text/css" media="screen">@import "../styles/style.css";</style>
+  <base href="http://wwwsearch.sourceforge.net/bits/clientx.html">
+</head>
+<body>
+
+<div id="sf"><a href="http://sourceforge.net">
+<img src="http://sourceforge.net/sflogo.php?group_id=48205&amp;type=2"
+ width="125" height="37" alt="SourceForge.net Logo"></a></div>
+<!--<img src="../images/sflogo.png"-->
+
+<h1>Python web-client programming general FAQs</h1>
+
+<div id="Content">
+<ul>
+  <li>Is there any example code?
+     <p>There's (still!) a bit of a shortage of example code for ClientCookie
+     and ClientForm &amp;co., because the stuff I've written tends to either
+     require access to restricted-access sites, or is proprietary code (and the
+     same goes for other people's code).
+  <li>HTTPS on Windows?
+     <p>Use this <a href="http://pypgsql.sourceforge.net/misc/python22-win32-ssl.zip">
+     _socket.pyd</a>, or use Python 2.3.
+  <li>I want to see what my web browser is doing, but standard network sniffers
+     like <a href="http://www.ethereal.com/">ethereal</a> or netcat (nc) don't
+     work for HTTPS.  How do I sniff HTTPS traffic?
+  <p>Three good options:
+  <ul>
+    <li>Mozilla plugin: <a href="http://livehttpheaders.mozdev.org/">
+     livehttpheaders</a>.
+    <li><a href="http://www.blunck.info/iehttpheaders.html">ieHTTPHeaders</a>
+     does the same for MSIE.
+    <li>Use <a href="http://lynx.browser.org/">lynx</a> <code>-trace</code>,
+     and filter out the junk with a script.
+  </ul>
+  <p>I'm told you can also use a proxy like <a
+  href="http://www.proxomitron.info/">proxomitron</a> (never tried it
+  myself).  There's also a commercial <a href="http://www.simtec.ltd.uk/">MSIE
+  plugin</a>.
+  <li>Embedded script is messing up my web-scraping.  What do I do?
+     <p>It is possible to embed script in HTML pages (sandwiched between
+     <code>&lt;SCRIPT&gt;here&lt;/SCRIPT&gt;</code> tags, and in
+     <code>javascript:</code> URLs) - JavaScript / ECMAScript, VBScript, or
+     even Python.  These scripts can do all sorts of things, including causing
+     cookies to be set in a browser, submitting or filling in parts of forms in
+     response to user actions, changing link colours as the mouse moves over a
+     link, etc.
+
+     <p>If you come across this in a page you want to automate, you
+     have four options.  Here they are, roughly in order of simplicity.
+
+     <ul>
+       <li>Simply figure out what the embedded script is doing and emulate it
+       in your Python code: for example, by manually adding cookies to your
+       <code>CookieJar</code> instance, calling methods on
+       <code>HTMLForm</code>s, calling <code>urlopen</code>, etc.
+
+       <li>Dump ClientCookie and ClientForm and automate a browser instead.
+       For example use MS Internet Explorer via its COM automation interfaces, using
+       the <a href="http://starship.python.net/crew/mhammond/">Python for
+       Windows extensions</a>, aka pywin32, aka win32all (eg.
+       <a href="http://vsbabu.org/mt/archives/2003/06/13/ie_automation.html">simple
+       function</a>, <a href="http://pamie.sourceforge.net/">pamie</a>;
+       <a href="http://www.oreilly.com/catalog/pythonwin32/chapter/ch12.html">
+       pywin32 chapter from the O'Reilly book</a>) or
+       <a href="http://starship.python.net/crew/theller/ctypes/">ctypes</a>
+       (<a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/305273">
+       example</a>: may be out of date, since <code>ctypes</code>' COM support is
+       still evolving).
+       <a href="http://www.brunningonline.net/simon/blog/archives/winGuiAuto.py.html">This</a>
+       kind of thing may also come in useful on Windows for cases where the
+       automation API is lacking.
+       <a href="http://ftp.acc.umu.se/pub/GNOME/sources/pyphany/">pyphany</a>
+       is a binding to the <a href="http://www.gnome.org/projects/epiphany/">
+       epiphany web browser</a>, allowing both plugins and automation code to be
+       written in Python.
+       XXX Mozilla automation &amp; XPCOM / PyXPCOM, Konqueror &amp; DCOP / KParts / PyKDE).
+
+       <li>Use Java's <a href="httpunit.sourceforge.net">httpunit</a> from
+       Jython, since it knows some JavaScript.
+       <li>Get ambitious and automatically delegate the work to an appropriate
+       interpreter (Mozilla's JavaScript interpreter, for instance).  This
+       approach is the one taken by <a href="../DOMForm">DOMForm</a> (the
+       JavaScript support is &quot;very alpha&quot;, though!).
+     </ul>
+  <li>Misc links
+     <ul>
+       <li><a href="http://www.crummy.com/software/BeautifulSoup/">Beautiful
+       Soup</a> is a widely recommended HTML-parsing module.
+       <li><a href="http://linux.duke.edu/projects/urlgrabber/">urlgrabber</a>
+       contains useful stuff like persistent connections, mirroring and
+       throttling, and it looks like most or all of it is well-integrated with
+       <code>urllib2</code> (originally part of the yum package manager, but
+       now becoming a separate project).
+       <li>Another Java thing: <a href="http://maxq.tigris.org/">maxq</a>,
+       which provides a proxy to aid automatic generation of functional tests
+       written in Jython using the standard library unittest module (PyUnit)
+       and the &quot;Jakarta Commons&quot; HttpClient library.
+       <li>A useful set Zope-oriented links on <a
+       href="http://viii.dclxvi.org/bookmarks/tech/zope/test">tools for testing
+       web applications</a>.
+       <li>O'Reilly book: <a href="">Spidering Hacks</a>.  Very Perl-oriented.
+       <li>Useful
+       <a href="http://chrispederick.com/work/webdeveloper/"> Firefox extension
+       </a> which, amongst other things, can display HTML form information and
+       HTML table structure(thanks to Erno Kuusela for this link).
+       <li>
+       <a href="http://www.openqa.org/selenium/">Selenium</a>: In-browser web
+       functional testing.
+       <li><a href="http://www.opensourcetesting.org/functional.php">Open
+       source functional testing tools</a>.  A nice list.
+       <li><a href="http://www.rexx.com/~dkuhlman/quixote_htmlscraping.html">
+       A HOWTO on web scraping</a> from Dave Kuhlman.
+     </ul>
+  <li>Will any of this code make its way into the Python standard library?
+
+  <p>The request / response processing extensions to <code>urllib2</code> from
+     ClientCookie have been merged into <code>urllib2</code> for Python 2.4.
+     The cookie processing has been added, as module <code>cookielib</code>.
+     Eventually, I'll submit patches to get the http-equiv, refresh, and
+     robots.txt code in there too, and maybe <code>mechanize.UserAgent</code>
+     too (but <em>not</em> <code>mechanize.Browser</code>).  The rest, probably
+     not.
+
+</ul>
+
+<p>I prefer questions and comments to be sent to the <a
+href="http://lists.sourceforge.net/lists/listinfo/wwwsearch-general">
+mailing list</a> rather than direct to me.
+
+<p><a href="mailto:jjl at pobox.com">John J. Lee</a>,
+January 2006.
+
+</div> <!--id="Content"-->
+
+<div id="Menu">
+
+<a href="..">Home</a><br>
+<br>
+<span class="thispage">General FAQs</span><br>
+<br>
+<a href="../mechanize/">mechanize</a><br>
+<a href="../pullparser/">pullparser</a><br>
+<a href="../ClientCookie/">ClientCookie</a><br>
+<a href="../ClientCookie/doc.html"><span class="subpage">ClientCookie docs</span></a><br>
+<a href="../ClientForm/">ClientForm</a><br>
+<br>
+<a href="../DOMForm/">DOMForm</a><br>
+<a href="../python-spidermonkey/">python-spidermonkey</a><br>
+<a href="../ClientTable/">ClientTable</a><br>
+<a href="../bits/urllib2_152.py">1.5.2 urllib2.py</a><br>
+<a href="../bits/urllib_152.py">1.5.2 urllib.py</a><br>
+
+<br>
+
+</body>
+</html>

Modified: packages/clientcookie/branches/upstream/current/INSTALL.txt
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/INSTALL.txt?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/INSTALL.txt (original)
+++ packages/clientcookie/branches/upstream/current/INSTALL.txt Mon Jun 19 07:05:08 2006
@@ -71,8 +71,8 @@
   (C) 2002-2003 Johhny Lee.  All rights reserved.  (MSIE Perl code)
 
 This code in this package is free software; you can redistribute it
-and/or modify it under the terms of the BSD license (see the file
-COPYING).
+and/or modify it under the terms of the BSD or ZPL licenses (see the
+file COPYING.txt).
 
 John J. Lee <jjl at pobox.com>
-September 2004
+March 2006

Modified: packages/clientcookie/branches/upstream/current/MANIFEST.in
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/MANIFEST.in?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/MANIFEST.in (original)
+++ packages/clientcookie/branches/upstream/current/MANIFEST.in Mon Jun 19 07:05:08 2006
@@ -1,12 +1,11 @@
 include MANIFEST.in
-include COPYING
-include INSTALL
+include COPYING.txt
+include INSTALL.txt
 include GeneralFAQ.html
 include README.html.in
 include README.html
 include README.txt
 include doc.html
 include doc.html.in
-include TODO
-include ChangeLog
+include ChangeLog.txt
 include *.py

Modified: packages/clientcookie/branches/upstream/current/PKG-INFO
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/PKG-INFO?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/PKG-INFO (original)
+++ packages/clientcookie/branches/upstream/current/PKG-INFO Mon Jun 19 07:05:08 2006
@@ -1,38 +1,39 @@
-Metadata-Version: 1.0
-Name: ClientCookie
-Version: 1.1.1
-Summary: Client-side HTTP cookie handling.
-Home-page: http://wwwsearch.sourceforge.net/ClientCookie/
-Author: John J. Lee
-Author-email: jjl at pobox.com
-License: BSD
-Download-URL: http://wwwsearch.sourceforge.net/ClientCookie/src/ClientCookie-1.1.1.tar.gz
-Description: ClientCookie is a Python module for handling HTTP cookies on the
-        client side, useful for accessing web sites that require cookies to be
-        set and then returned later.  It also provides some other (optional)
-        useful stuff: HTTP-EQUIV and Refresh handling, automatic adding of the
-        Referer [sic] header, robots.txt observance and lazily-seek()able
-        responses.  These extras are implemented using an extension that makes
-        it easier to add new functionality to urllib2 (now part of urllib2, as
-        of Python 2.4).  It has developed from a port of Gisle Aas' Perl
-        module HTTP::Cookies, from the libwww-perl library.
-        
-Platform: any
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Natural Language :: English
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Topic :: Internet
-Classifier: Topic :: Internet :: WWW/HTTP
-Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
-Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
-Classifier: Topic :: Internet :: WWW/HTTP :: Site Management :: Link Checking
-Classifier: Topic :: Software Development :: Libraries
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: Software Development :: Testing
-Classifier: Topic :: Software Development :: Testing :: Traffic Generation
-Classifier: Topic :: System :: Networking :: Monitoring
-Classifier: Topic :: System :: Systems Administration
+Metadata-Version: 1.0
+Name: ClientCookie
+Version: 1.3.0
+Summary: Client-side HTTP cookie handling.
+Home-page: http://wwwsearch.sourceforge.net/ClientCookie/
+Author: John J. Lee
+Author-email: jjl at pobox.com
+License: BSD
+Download-URL: http://wwwsearch.sourceforge.net/ClientCookie/src/ClientCookie-1.3.0.tar.gz
+Description: ClientCookie is a Python module for handling HTTP cookies on the
+        client side, useful for accessing web sites that require cookies to be
+        set and then returned later.  It also provides some other (optional)
+        useful stuff: HTTP-EQUIV and Refresh handling, automatic adding of the
+        Referer [sic] header, robots.txt observance and lazily-seek()able
+        responses.  These extras are implemented using an extension that makes
+        it easier to add new functionality to urllib2 (now part of urllib2, as
+        of Python 2.4).  It has developed from a port of Gisle Aas' Perl
+        module HTTP::Cookies, from the libwww-perl library.
+        
+Platform: any
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: System Administrators
+Classifier: License :: OSI Approved :: BSD License
+Classifier: License :: OSI Approved :: Zope Public License
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Internet
+Classifier: Topic :: Internet :: WWW/HTTP
+Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
+Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
+Classifier: Topic :: Internet :: WWW/HTTP :: Site Management :: Link Checking
+Classifier: Topic :: Software Development :: Libraries
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Software Development :: Testing
+Classifier: Topic :: Software Development :: Testing :: Traffic Generation
+Classifier: Topic :: System :: Networking :: Monitoring
+Classifier: Topic :: System :: Systems Administration

Modified: packages/clientcookie/branches/upstream/current/README.html
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/README.html?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/README.html (original)
+++ packages/clientcookie/branches/upstream/current/README.html Mon Jun 19 07:05:08 2006
@@ -1,246 +1,248 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
-
-
-
-
-<html>
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-  <meta name="author" content="John J. Lee &lt;jjl at pobox.com&gt;">
-  <meta name="date" content="2006-01-10">
-  <meta name="keywords" content="cookie,HTTP,Python,web,client,client-side,HTML,META,HTTP-EQUIV,Refresh">
-  <title>ClientCookie</title>
-  <style type="text/css" media="screen">@import "../styles/style.css";</style>
-  <style type="text/css" media="screen">@import "../styles/cookie_style.css";</style>
-  <base href="http://wwwsearch.sourceforge.net/ClientCookie/">
-</head>
-<body>
-
-<div id="sf"><a href="http://sourceforge.net">
-<img src="http://sourceforge.net/sflogo.php?group_id=48205&amp;type=2"
- width="125" height="37" alt="SourceForge.net Logo"></a></div>
-<!--<img src="../images/sflogo.png"-->
-
-<h1>ClientCookie</h1>
-
-<div id="Content">
-
-<p>Please read <a href="./#compatnotes">this note</a> explaining the
-relationship between ClientCookie, <code>cookielib</code> and
-<code>urllib2</code>, and which to use when.
-
-<p>ClientCookie is a <a href="http://www.python.org/">Python</a> module for
-handling HTTP cookies on the client side, useful for accessing web sites that
-require cookies to be set and then returned later.  It also provides some other
-(optional) useful stuff: <code>HTTP-EQUIV</code> and <code>Refresh</code>
-handling, automatic adding of the <code>Referer</code> [<em><a
-href="http://www.ietf.org/rfc/rfc2616.txt">sic</a></em>] header, automatic
-observance of <code>robots.txt</code> and lazily-<code>seek()</code>able
-responses.  These extras are implemented using an extension that makes it
-easier to add new functionality to <code>urllib2</code>.  It has developed from
-a port of Gisle Aas' Perl module <code>HTTP::Cookies</code>, from the <a
-href="http://www.linpro.no/lwp/">libwww-perl</a> library.
-
-<pre>
- <span class="pykw">import</span> ClientCookie
- response = ClientCookie.urlopen(<span class="pystr">"http://foo.bar.com/"</span>)</pre>
-
-
-<p>This function behaves identically to <code>urllib2.urlopen</code>, except
-that it deals with cookies automatically.  That's probably all you need to
-know.
-
-<p>Python 2.0 or above is required, and <code>urllib2</code> is recommended.
-If you have 2.1 or above, you've already got a recent enough version of
-<code>urllib2</code>.  For Python 2.0, you need the newer versions from Python
-2.1 (available from the source distribution or Python CVS: <a
-href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/python/python/dist/src/Lib/urllib2.py?rev=1.13.2.2">urllib2.py</a>).
-Note that you don't need to replace the original <code>urllib2</code> /
-<code>urllib</code> - you can just make sure they're in <code>sys.path</code>
-ahead of the copies from 2.0's standard library.
-
-<p>For full documentation, see <a href="./doc.html">here</a> and the docstrings
-in the module source code.
-
-<p>Other than Gisle, particular thanks to Johnny Lee (MSIE Perl code) and
-Ronald Tschalar (advice on Netscape cookies).
-
-
-<a name="compatnotes"></a>
-<h2>Notes about ClientCookie, <code>urllib2</code> and <code>cookielib</code></h2>
-
-<p>Even if you're not using Python 2.4, please note the last of these points.
-
-<ol>
-
-  <li>The cookie handling parts of ClientCookie are in Python 2.4 standard
-      library as module <code>cookielib</code> and extensions to module
-      <code>urllib2</code>.
-
-  <li>ClientCookie works with Python 2.4.
-
-  <li>For new code to run on Python 2.4, I recommend use of standard
-      library modules <code>urllib2</code> and <code>cookielib</code>
-      instead of ClientCookie.  I recommend
-      <a href="http://docs.python.org/lib/cookielib-examples.html">turning on
-      RFC 2965 support</a> to work around a bug in <code>cookielib</code> in
-      Python 2.4.0.
-
-  <li>Handler classes thst are missing from 2.4's <code>urllib2</code>
-      (eg. <code>HTTPRefreshProcessor</code>) may be used with 2.4's
-      <code>urllib2</code> (however, note the paragraph below).  With any
-      version of Python, parts of <code>urllib2</code> that are missing from
-      ClientCookie (eg. <code>ProxyHandler</code>) may be used with
-      ClientCookie, and <code>urllib2.Request</code> objects may be used with
-      ClientCookie.  <strong>IMPORTANT:</strong> For all other code, use
-      ClientCookie <em><strong>exclusively</strong></em>: do NOT mix use of
-      ClientCookie and <code>urllib2</code>!
-
-</ol>
-
-<p><strong>Finally, note</strong> that, if you want to use
-<code>ClientCookie.RefreshProcessor</code> with Python 2.4's
-<code>urllib2</code>, you must also use
-<code>ClientCookie.HTTPRedirectHandler</code>.
-
-<a name="download"></a>
-<h2>Download</h2>
-
-<p>All documentation (including these web pages) is included in the
-distribution.
-
-<p>To port your code from 0.4.x to 1.0.x, see <a
-href="./porting-0.4-1.0.txt">here</a>.
-
-<p><em>Stable release.</em>
-
-<ul>
-
-
-<li><a href="./src/ClientCookie-1.1.1.tar.gz">ClientCookie-1.1.1.tar.gz</a>
-<li><a href="./src/ClientCookie-1_1_1.zip">ClientCookie-1_1_1.zip</a>
-<li><a href="./src/ChangeLog.txt">Change Log</a> (included in distribution)
-<li><a href="./src/">Older versions.</a>
-</ul>
-
-<br>
-
-<p><em>Old release.</em>
-
-<ul>
-
-
-<li><a href="./src/ClientCookie-0.4.19.tar.gz">ClientCookie-0.4.19.tar.gz</a>
-<li><a href="./src/ClientCookie-0_4_19.zip">ClientCookie-0_4_19.zip</a>
-<li><a href="./src/ChangeLog.txt">Change Log</a> (included in distribution)
-<li><a href="./src/">Older versions.</a>
-</ul>
-
-<p>For installation instructions, see the INSTALL file included in the
-distribution.
-
-
-<h2>Subversion</h2>
-
-<p>The <a href="http://subversion.tigris.org/">Subversion (SVN)</a> trunk is <a href="http://codespeak.net/svn/wwwsearch/ClientCookie/trunk#egg=ClientCookie-dev">http://codespeak.net/svn/wwwsearch/ClientCookie/trunk</a>, so to check out the source:
-
-<pre>
-svn co http://codespeak.net/svn/wwwsearch/ClientCookie/trunk ClientCookie
-</pre>
-
-
-<a name="faq_pre"></a>
-<h2>FAQs - pre-install</h2>
-<ul>
-  <li>Doesn't the standard Python library module, <code>Cookie</code>, do
-     this?
-  <p>No: Cookie.py does the server end of the job.  It doesn't know when to
-     accept cookies from a server or when to pass them back.
-  <li>Which version of Python do I need?
-  <p>2.0 or above.
-  <li>Is urllib2.py required?
-  <p>No.  You probably want it, though.
-  <li>Which urllib2.py do I need?
-  <p>You don't, but if you want to use the extended <code>urllib2</code>
-     callables from ClientCookie, and you have Python 2.0, you need to
-     upgrade to the version from Python 2.1.  Otherwise, you're OK.
-  <li>Which license?
-     <p>The <a href="http://www.opensource.org/licenses/bsd-license.php">
-     BSD license</a> (included in distribution).
-  <li>Where can I find out more about the HTTP cookie protocol?
-  <p>There is more than one protocol, in fact (see the <a href="./doc.html">docs</a>
-     for a brief explanation of the history):
-  <ul>
-    <li>The original <a href="http://www.netscape.com/newsref/std/cookie_spec.html">
-        Netscape cookie protocol</a> - the standard still in use today, in
-        theory (in reality, the protocol implemented by all the major browsers
-        only bears a passing resemblance to the protocol sketched out in this
-        document).
-    <li><a href="http://www.ietf.org/rfcs/rfc2109.txt">RFC 2109</a> - obsoleted
-        by RFC 2965.
-     <li><a href="http://www.ietf.org/rfcs/rfc2965.txt">RFC 2965</a> - the
-        Netscape protocol with the bugs fixed (not widely used - the Netscape
-        protocol still dominates, and seems likely to remain dominant
-        indefinitely, at least on the Internet).
-        <a href="http://www.ietf.org/rfcs/rfc2964.txt">RFC 2964</a> discusses use
-        of the protocol.
-        <a href="http://kristol.org/cookie/errata.html">Errata</a> to RFC 2965
-        are currently being discussed on the
-        <a href="http://lists.bell-labs.com/mailman/listinfo/http-state">
-        http-state mailing list</a> (update: list traffic died months ago and
-        hasn't revived).
-    <li>A <a href="http://doi.acm.org/10.1145/502152.502153">paper</a> by David
-        Kristol setting out the history of the cookie standards in exhausting
-        detail.
-    <li>HTTP cookies <a href="http://www.cookiecentral.com/">FAQ</a>.
-  </ul>
-  <li>Which protocols does ClientCookie support?
-     <p>Netscape and RFC 2965.  RFC 2965 handling is switched off by default.
-  <li>What about RFC 2109?
-     <p>RFC 2109 cookies are currently parsed as Netscape cookies, and treated
-     by default as RFC 2965 cookies thereafter if RFC 2965 handling is enabled,
-     or as Netscape cookies otherwise.  RFC 2109 is officially obsoleted by RFC
-     2965.  Browsers do use a few RFC 2109 features in their Netscape cookie
-     implementations (<code>port</code> and <code>max-age</code>), and
-     ClientCookie knows about that, too.
-</ul>
-
-<p>I prefer questions and comments to be sent to the <a
-href="http://lists.sourceforge.net/lists/listinfo/wwwsearch-general">
-mailing list</a> rather than direct to me.
-
-<p><a href="mailto:jjl at pobox.com">John J. Lee</a>,
-January 2006.
-
-<hr>
-
-</div>
-
-<div id="Menu">
-
-<a href="..">Home</a><br>
-<br>
-<a href="../bits/GeneralFAQ.html">General FAQs</a><br>
-<br>
-<a href="../mechanize/">mechanize</a><br>
-<a href="../pullparser/">pullparser</a><br>
-<span class="thispage">ClientCookie</span><br>
-<a href="../ClientCookie/doc.html"><span class="subpage">ClientCookie docs</span></a><br>
-<a href="../ClientForm/">ClientForm</a><br>
-<br>
-<a href="../DOMForm/">DOMForm</a><br>
-<a href="../python-spidermonkey/">python-spidermonkey</a><br>
-<a href="../ClientTable/">ClientTable</a><br>
-<a href="../bits/urllib2_152.py">1.5.2 urllib2.py</a><br>
-<a href="../bits/urllib_152.py">1.5.2 urllib.py</a><br>
-
-<br>
-
-<a href="./#download">Download</a><br>
-<a href="./#faq_pre">FAQs - pre-install</a><br>
-
-</div>
-
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+
+
+
+
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="author" content="John J. Lee &lt;jjl at pobox.com&gt;">
+  <meta name="date" content="2006-04-08">
+  <meta name="keywords" content="cookie,HTTP,Python,web,client,client-side,HTML,META,HTTP-EQUIV,Refresh">
+  <title>ClientCookie</title>
+  <style type="text/css" media="screen">@import "../styles/style.css";</style>
+  <style type="text/css" media="screen">@import "../styles/cookie_style.css";</style>
+  <base href="http://wwwsearch.sourceforge.net/ClientCookie/">
+</head>
+<body>
+
+<div id="sf"><a href="http://sourceforge.net">
+<img src="http://sourceforge.net/sflogo.php?group_id=48205&amp;type=2"
+ width="125" height="37" alt="SourceForge.net Logo"></a></div>
+<!--<img src="../images/sflogo.png"-->
+
+<h1>ClientCookie</h1>
+
+<div id="Content">
+
+<p>Please read <a href="./#compatnotes">this note</a> explaining the
+relationship between ClientCookie, <code>cookielib</code> and
+<code>urllib2</code>, and which to use when.
+
+<p>ClientCookie is a <a href="http://www.python.org/">Python</a> module for
+handling HTTP cookies on the client side, useful for accessing web sites that
+require cookies to be set and then returned later.  It also provides some other
+(optional) useful stuff: <code>HTTP-EQUIV</code> and <code>Refresh</code>
+handling, automatic adding of the <code>Referer</code> [<em><a
+href="http://www.ietf.org/rfc/rfc2616.txt">sic</a></em>] header, automatic
+observance of <code>robots.txt</code> and lazily-<code>seek()</code>able
+responses.  These extras are implemented using an extension that makes it
+easier to add new functionality to <code>urllib2</code>.  It has developed from
+a port of Gisle Aas' Perl module <code>HTTP::Cookies</code>, from the <a
+href="http://www.linpro.no/lwp/">libwww-perl</a> library.
+
+<pre>
+ <span class="pykw">import</span> ClientCookie
+ response = ClientCookie.urlopen(<span class="pystr">"http://foo.bar.com/"</span>)</pre>
+
+
+<p>This function behaves identically to <code>urllib2.urlopen</code>, except
+that it deals with cookies automatically.  That's probably all you need to
+know.
+
+<p>Python 2.0 or above is required, and <code>urllib2</code> is recommended.
+If you have 2.1 or above, you've already got a recent enough version of
+<code>urllib2</code>.  For Python 2.0, you need the newer versions from Python
+2.1 (available from the source distribution or Python CVS: <a
+href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/python/python/dist/src/Lib/urllib2.py?rev=1.13.2.2">urllib2.py</a>).
+Note that you don't need to replace the original <code>urllib2</code> /
+<code>urllib</code> - you can just make sure they're in <code>sys.path</code>
+ahead of the copies from 2.0's standard library.
+
+<p>For full documentation, see <a href="./doc.html">here</a> and the docstrings
+in the module source code.
+
+<p>Other than Gisle, particular thanks to Johnny Lee (MSIE Perl code) and
+Ronald Tschalar (advice on Netscape cookies).
+
+
+<a name="compatnotes"></a>
+<h2>Notes about ClientCookie, <code>urllib2</code> and <code>cookielib</code></h2>
+
+<p>Even if you're not using Python 2.4, please note the last of these points.
+
+<ol>
+
+  <li>The cookie handling parts of ClientCookie are in Python 2.4 standard
+      library as module <code>cookielib</code> and extensions to module
+      <code>urllib2</code>.
+
+  <li>ClientCookie works with Python 2.4.
+
+  <li>For new code to run on Python 2.4, I recommend use of standard
+      library modules <code>urllib2</code> and <code>cookielib</code>
+      instead of ClientCookie.  I recommend
+      <a href="http://docs.python.org/lib/cookielib-examples.html">turning on
+      RFC 2965 support</a> to work around a bug in <code>cookielib</code> in
+      Python 2.4.0.
+
+  <li>Handler classes thst are missing from 2.4's <code>urllib2</code>
+      (eg. <code>HTTPRefreshProcessor</code>) may be used with 2.4's
+      <code>urllib2</code> (however, note the paragraph below).  With any
+      version of Python, parts of <code>urllib2</code> that are missing from
+      ClientCookie (eg. <code>ProxyHandler</code>) may be used with
+      ClientCookie, and <code>urllib2.Request</code> objects may be used with
+      ClientCookie.  <strong>IMPORTANT:</strong> For all other code, use
+      ClientCookie <em><strong>exclusively</strong></em>: do NOT mix use of
+      ClientCookie and <code>urllib2</code>!
+
+</ol>
+
+<p><strong>Finally, note</strong> that, if you want to use
+<code>ClientCookie.RefreshProcessor</code> with Python 2.4's
+<code>urllib2</code>, you must also use
+<code>ClientCookie.HTTPRedirectHandler</code>.
+
+<a name="download"></a>
+<h2>Download</h2>
+
+<p>All documentation (including these web pages) is included in the
+distribution.
+
+<p>To port your code from 0.4.x to 1.0.x, see <a
+href="./porting-0.4-1.0.txt">here</a>.
+
+<p><em>Stable release.</em>
+
+<ul>
+
+<li><a href="./src/ClientCookie-1.3.0.tar.gz">ClientCookie-1.3.0.tar.gz</a>
+<li><a href="./src/ClientCookie-1.3.0.zip">ClientCookie-1.3.0.zip</a>
+<li><a href="./src/ChangeLog.txt">Change Log</a> (included in distribution)
+<li><a href="./src/">Older versions.</a>
+</ul>
+
+<br>
+
+<p><em>Old release.</em>
+
+<ul>
+
+
+<li><a href="./src/ClientCookie-0.4.19.tar.gz">ClientCookie-0.4.19.tar.gz</a>
+<li><a href="./src/ClientCookie-0_4_19.zip">ClientCookie-0_4_19.zip</a>
+<li><a href="./src/ChangeLog.txt">Change Log</a> (included in distribution)
+<li><a href="./src/">Older versions.</a>
+</ul>
+
+<p>For installation instructions, see the INSTALL file included in the
+distribution.
+
+
+<h2>Subversion</h2>
+
+<p>The <a href="http://subversion.tigris.org/">Subversion (SVN)</a> trunk is <a href="http://codespeak.net/svn/wwwsearch/ClientCookie/trunk#egg=ClientCookie-dev">http://codespeak.net/svn/wwwsearch/ClientCookie/trunk</a>, so to check out the source:
+
+<pre>
+svn co http://codespeak.net/svn/wwwsearch/ClientCookie/trunk ClientCookie
+</pre>
+
+
+<a name="faq_pre"></a>
+<h2>FAQs - pre-install</h2>
+<ul>
+  <li>Doesn't the standard Python library module, <code>Cookie</code>, do
+     this?
+  <p>No: Cookie.py does the server end of the job.  It doesn't know when to
+     accept cookies from a server or when to pass them back.
+  <li>Which version of Python do I need?
+  <p>2.0 or above.
+  <li>Is urllib2.py required?
+  <p>No.  You probably want it, though.
+  <li>Which urllib2.py do I need?
+  <p>You don't, but if you want to use the extended <code>urllib2</code>
+     callables from ClientCookie, and you have Python 2.0, you need to
+     upgrade to the version from Python 2.1.  Otherwise, you're OK.
+  <li>Which license?
+  <p>ClientCookie is dual-licensed: you may pick either the
+     <a href="http://www.opensource.org/licenses/bsd-license.php">BSD license</a>,
+     or the <a href="http://www.zope.org/Resources/ZPL">ZPL 2.1</a> (both are
+     included in the distribution).
+  <li>Where can I find out more about the HTTP cookie protocol?
+  <p>There is more than one protocol, in fact (see the <a href="./doc.html">docs</a>
+     for a brief explanation of the history):
+  <ul>
+    <li>The original <a href="http://www.netscape.com/newsref/std/cookie_spec.html">
+        Netscape cookie protocol</a> - the standard still in use today, in
+        theory (in reality, the protocol implemented by all the major browsers
+        only bears a passing resemblance to the protocol sketched out in this
+        document).
+    <li><a href="http://www.ietf.org/rfcs/rfc2109.txt">RFC 2109</a> - obsoleted
+        by RFC 2965.
+     <li><a href="http://www.ietf.org/rfcs/rfc2965.txt">RFC 2965</a> - the
+        Netscape protocol with the bugs fixed (not widely used - the Netscape
+        protocol still dominates, and seems likely to remain dominant
+        indefinitely, at least on the Internet).
+        <a href="http://www.ietf.org/rfcs/rfc2964.txt">RFC 2964</a> discusses use
+        of the protocol.
+        <a href="http://kristol.org/cookie/errata.html">Errata</a> to RFC 2965
+        are currently being discussed on the
+        <a href="http://lists.bell-labs.com/mailman/listinfo/http-state">
+        http-state mailing list</a> (update: list traffic died months ago and
+        hasn't revived).
+    <li>A <a href="http://doi.acm.org/10.1145/502152.502153">paper</a> by David
+        Kristol setting out the history of the cookie standards in exhausting
+        detail.
+    <li>HTTP cookies <a href="http://www.cookiecentral.com/">FAQ</a>.
+  </ul>
+  <li>Which protocols does ClientCookie support?
+     <p>Netscape and RFC 2965.  RFC 2965 handling is switched off by default.
+  <li>What about RFC 2109?
+     <p>RFC 2109 cookies are currently parsed as Netscape cookies, and treated
+     by default as RFC 2965 cookies thereafter if RFC 2965 handling is enabled,
+     or as Netscape cookies otherwise.  RFC 2109 is officially obsoleted by RFC
+     2965.  Browsers do use a few RFC 2109 features in their Netscape cookie
+     implementations (<code>port</code> and <code>max-age</code>), and
+     ClientCookie knows about that, too.
+</ul>
+
+<p>I prefer questions and comments to be sent to the <a
+href="http://lists.sourceforge.net/lists/listinfo/wwwsearch-general">
+mailing list</a> rather than direct to me.
+
+<p><a href="mailto:jjl at pobox.com">John J. Lee</a>,
+April 2006.
+
+<hr>
+
+</div>
+
+<div id="Menu">
+
+<a href="..">Home</a><br>
+<br>
+<a href="../bits/GeneralFAQ.html">General FAQs</a><br>
+<br>
+<a href="../mechanize/">mechanize</a><br>
+<a href="../pullparser/">pullparser</a><br>
+<span class="thispage">ClientCookie</span><br>
+<a href="../ClientCookie/doc.html"><span class="subpage">ClientCookie docs</span></a><br>
+<a href="../ClientForm/">ClientForm</a><br>
+<br>
+<a href="../DOMForm/">DOMForm</a><br>
+<a href="../python-spidermonkey/">python-spidermonkey</a><br>
+<a href="../ClientTable/">ClientTable</a><br>
+<a href="../bits/urllib2_152.py">1.5.2 urllib2.py</a><br>
+<a href="../bits/urllib_152.py">1.5.2 urllib.py</a><br>
+
+<br>
+
+<a href="./#download">Download</a><br>
+<a href="./#faq_pre">FAQs - pre-install</a><br>
+
+</div>
+
+
+</body>
+</html>

Modified: packages/clientcookie/branches/upstream/current/README.html.in
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/README.html.in?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/README.html.in (original)
+++ packages/clientcookie/branches/upstream/current/README.html.in Mon Jun 19 07:05:08 2006
@@ -5,7 +5,7 @@
 @{from colorize import colorize}
 @{import time}
 @{import release}
-@{last_modified = release.svn_id_to_time("$Id: README.html.in 21909 2006-01-10 22:42:33Z jjlee $")}
+@{last_modified = release.svn_id_to_time("$Id: README.html.in 25588 2006-04-08 19:26:54Z jjlee $")}
 <html>
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -118,10 +118,9 @@
 <p><em>Stable release.</em>
 
 <ul>
-@{version = "1.1.1"}
-@{win_version = release.win_version(version)}
+@{version = "1.3.0"}
 <li><a href="./src/ClientCookie-@(version).tar.gz">ClientCookie-@(version).tar.gz</a>
-<li><a href="./src/ClientCookie-@(win_version).zip">ClientCookie-@(win_version).zip</a>
+<li><a href="./src/ClientCookie-@(version).zip">ClientCookie-@(version).zip</a>
 <li><a href="./src/ChangeLog.txt">Change Log</a> (included in distribution)
 <li><a href="./src/">Older versions.</a>
 </ul>
@@ -168,8 +167,10 @@
      callables from ClientCookie, and you have Python 2.0, you need to
      upgrade to the version from Python 2.1.  Otherwise, you're OK.
   <li>Which license?
-     <p>The <a href="http://www.opensource.org/licenses/bsd-license.php">
-     BSD license</a> (included in distribution).
+  <p>ClientCookie is dual-licensed: you may pick either the
+     <a href="http://www.opensource.org/licenses/bsd-license.php">BSD license</a>,
+     or the <a href="http://www.zope.org/Resources/ZPL">ZPL 2.1</a> (both are
+     included in the distribution).
   <li>Where can I find out more about the HTTP cookie protocol?
   <p>There is more than one protocol, in fact (see the <a href="./doc.html">docs</a>
      for a brief explanation of the history):
@@ -230,5 +231,6 @@
 
 </div>
 
+
 </body>
 </html>

Added: packages/clientcookie/branches/upstream/current/README.txt
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/README.txt?rev=914&op=file
==============================================================================
--- packages/clientcookie/branches/upstream/current/README.txt (added)
+++ packages/clientcookie/branches/upstream/current/README.txt Mon Jun 19 07:05:08 2006
@@ -1,0 +1,204 @@
+   [1]SourceForge.net Logo
+
+                                 ClientCookie
+
+   Please read [2]this note explaining the relationship between
+   ClientCookie, cookielib and urllib2, and which to use when.
+
+   ClientCookie is a [3]Python module for handling HTTP cookies on the
+   client side, useful for accessing web sites that require cookies to be
+   set and then returned later. It also provides some other (optional)
+   useful stuff: HTTP-EQUIV and Refresh handling, automatic adding of the
+   Referer [[4]sic] header, automatic observance of robots.txt and
+   lazily-seek()able responses. These extras are implemented using an
+   extension that makes it easier to add new functionality to urllib2. It
+   has developed from a port of Gisle Aas' Perl module HTTP::Cookies,
+   from the [5]libwww-perl library.
+ import ClientCookie
+ response = ClientCookie.urlopen("http://foo.bar.com/")
+
+   This function behaves identically to urllib2.urlopen, except that it
+   deals with cookies automatically. That's probably all you need to
+   know.
+
+   Python 2.0 or above is required, and urllib2 is recommended. If you
+   have 2.1 or above, you've already got a recent enough version of
+   urllib2. For Python 2.0, you need the newer versions from Python 2.1
+   (available from the source distribution or Python CVS: [6]urllib2.py).
+   Note that you don't need to replace the original urllib2 / urllib -
+   you can just make sure they're in sys.path ahead of the copies from
+   2.0's standard library.
+
+   For full documentation, see [7]here and the docstrings in the module
+   source code.
+
+   Other than Gisle, particular thanks to Johnny Lee (MSIE Perl code) and
+   Ronald Tschalar (advice on Netscape cookies).
+
+Notes about ClientCookie, urllib2 and cookielib
+
+   Even if you're not using Python 2.4, please note the last of these
+   points.
+    1. The cookie handling parts of ClientCookie are in Python 2.4
+       standard library as module cookielib and extensions to module
+       urllib2.
+    2. ClientCookie works with Python 2.4.
+    3. For new code to run on Python 2.4, I recommend use of standard
+       library modules urllib2 and cookielib instead of ClientCookie. I
+       recommend [8]turning on RFC 2965 support to work around a bug in
+       cookielib in Python 2.4.0.
+    4. Handler classes thst are missing from 2.4's urllib2 (eg.
+       HTTPRefreshProcessor) may be used with 2.4's urllib2 (however,
+       note the paragraph below). With any version of Python, parts of
+       urllib2 that are missing from ClientCookie (eg. ProxyHandler) may
+       be used with ClientCookie, and urllib2.Request objects may be used
+       with ClientCookie. IMPORTANT: For all other code, use ClientCookie
+       exclusively: do NOT mix use of ClientCookie and urllib2!
+
+   Finally, note that, if you want to use ClientCookie.RefreshProcessor
+   with Python 2.4's urllib2, you must also use
+   ClientCookie.HTTPRedirectHandler.
+
+Download
+
+   All documentation (including these web pages) is included in the
+   distribution.
+
+   To port your code from 0.4.x to 1.0.x, see [9]here.
+
+   Stable release.
+     * [10]ClientCookie-1.3.0.tar.gz
+     * [11]ClientCookie-1.3.0.zip
+     * [12]Change Log (included in distribution)
+     * [13]Older versions.
+
+   Old release.
+     * [14]ClientCookie-0.4.19.tar.gz
+     * [15]ClientCookie-0_4_19.zip
+     * [16]Change Log (included in distribution)
+     * [17]Older versions.
+
+   For installation instructions, see the INSTALL file included in the
+   distribution.
+
+Subversion
+
+   The [18]Subversion (SVN) trunk is
+   [19]http://codespeak.net/svn/wwwsearch/ClientCookie/trunk, so to check
+   out the source:
+svn co http://codespeak.net/svn/wwwsearch/ClientCookie/trunk ClientCookie
+
+FAQs - pre-install
+
+     * Doesn't the standard Python library module, Cookie, do this?
+       No: Cookie.py does the server end of the job. It doesn't know when
+       to accept cookies from a server or when to pass them back.
+     * Which version of Python do I need?
+       2.0 or above.
+     * Is urllib2.py required?
+       No. You probably want it, though.
+     * Which urllib2.py do I need?
+       You don't, but if you want to use the extended urllib2 callables
+       from ClientCookie, and you have Python 2.0, you need to upgrade to
+       the version from Python 2.1. Otherwise, you're OK.
+     * Which license?
+       ClientCookie is dual-licensed: you may pick either the [20]BSD
+       license, or the [21]ZPL 2.1 (both are included in the
+       distribution).
+     * Where can I find out more about the HTTP cookie protocol?
+       There is more than one protocol, in fact (see the [22]docs for a
+       brief explanation of the history):
+          + The original [23]Netscape cookie protocol - the standard
+            still in use today, in theory (in reality, the protocol
+            implemented by all the major browsers only bears a passing
+            resemblance to the protocol sketched out in this document).
+          + [24]RFC 2109 - obsoleted by RFC 2965.
+          + [25]RFC 2965 - the Netscape protocol with the bugs fixed (not
+            widely used - the Netscape protocol still dominates, and
+            seems likely to remain dominant indefinitely, at least on the
+            Internet). [26]RFC 2964 discusses use of the protocol.
+            [27]Errata to RFC 2965 are currently being discussed on the
+            [28]http-state mailing list (update: list traffic died months
+            ago and hasn't revived).
+          + A [29]paper by David Kristol setting out the history of the
+            cookie standards in exhausting detail.
+          + HTTP cookies [30]FAQ.
+     * Which protocols does ClientCookie support?
+       Netscape and RFC 2965. RFC 2965 handling is switched off by
+       default.
+     * What about RFC 2109?
+       RFC 2109 cookies are currently parsed as Netscape cookies, and
+       treated by default as RFC 2965 cookies thereafter if RFC 2965
+       handling is enabled, or as Netscape cookies otherwise. RFC 2109 is
+       officially obsoleted by RFC 2965. Browsers do use a few RFC 2109
+       features in their Netscape cookie implementations (port and
+       max-age), and ClientCookie knows about that, too.
+
+   I prefer questions and comments to be sent to the [31]mailing list
+   rather than direct to me.
+
+   [32]John J. Lee, April 2006.
+     _________________________________________________________________
+
+   [33]Home
+   [34]General FAQs
+   [35]mechanize
+   [36]pullparser
+   ClientCookie
+   [37]ClientCookie docs
+   [38]ClientForm
+   [39]DOMForm
+   [40]python-spidermonkey
+   [41]ClientTable
+   [42]1.5.2 urllib2.py
+   [43]1.5.2 urllib.py
+   [44]Download
+   [45]FAQs - pre-install
+
+References
+
+   1. http://sourceforge.net/
+   2. http://wwwsearch.sourceforge.net/ClientCookie/#compatnotes
+   3. http://www.python.org/
+   4. http://www.ietf.org/rfc/rfc2616.txt
+   5. http://www.linpro.no/lwp/
+   6. http://cvs.sourceforge.net/viewcvs.py/*checkout*/python/python/dist/src/Lib/urllib2.py?rev=1.13.2.2
+   7. http://wwwsearch.sourceforge.net/ClientCookie/doc.html
+   8. http://docs.python.org/lib/cookielib-examples.html
+   9. http://wwwsearch.sourceforge.net/ClientCookie/porting-0.4-1.0.txt
+  10. http://wwwsearch.sourceforge.net/ClientCookie/src/ClientCookie-1.3.0.tar.gz
+  11. http://wwwsearch.sourceforge.net/ClientCookie/src/ClientCookie-1.3.0.zip
+  12. http://wwwsearch.sourceforge.net/ClientCookie/src/ChangeLog.txt
+  13. http://wwwsearch.sourceforge.net/ClientCookie/src/
+  14. http://wwwsearch.sourceforge.net/ClientCookie/src/ClientCookie-0.4.19.tar.gz
+  15. http://wwwsearch.sourceforge.net/ClientCookie/src/ClientCookie-0_4_19.zip
+  16. http://wwwsearch.sourceforge.net/ClientCookie/src/ChangeLog.txt
+  17. http://wwwsearch.sourceforge.net/ClientCookie/src/
+  18. http://subversion.tigris.org/
+  19. http://codespeak.net/svn/wwwsearch/ClientCookie/trunk#egg=ClientCookie-dev
+  20. http://www.opensource.org/licenses/bsd-license.php
+  21. http://www.zope.org/Resources/ZPL
+  22. http://wwwsearch.sourceforge.net/ClientCookie/doc.html
+  23. http://www.netscape.com/newsref/std/cookie_spec.html
+  24. http://www.ietf.org/rfcs/rfc2109.txt
+  25. http://www.ietf.org/rfcs/rfc2965.txt
+  26. http://www.ietf.org/rfcs/rfc2964.txt
+  27. http://kristol.org/cookie/errata.html
+  28. http://lists.bell-labs.com/mailman/listinfo/http-state
+  29. http://doi.acm.org/10.1145/502152.502153
+  30. http://www.cookiecentral.com/
+  31. http://lists.sourceforge.net/lists/listinfo/wwwsearch-general
+  32. mailto:jjl at pobox.com
+  33. http://wwwsearch.sourceforge.net/
+  34. http://wwwsearch.sourceforge.net/bits/GeneralFAQ.html
+  35. http://wwwsearch.sourceforge.net/mechanize/
+  36. http://wwwsearch.sourceforge.net/pullparser/
+  37. http://wwwsearch.sourceforge.net/ClientCookie/doc.html
+  38. http://wwwsearch.sourceforge.net/ClientForm/
+  39. http://wwwsearch.sourceforge.net/DOMForm/
+  40. http://wwwsearch.sourceforge.net/python-spidermonkey/
+  41. http://wwwsearch.sourceforge.net/ClientTable/
+  42. http://wwwsearch.sourceforge.net/bits/urllib2_152.py
+  43. http://wwwsearch.sourceforge.net/bits/urllib_152.py
+  44. http://wwwsearch.sourceforge.net/ClientCookie/#download
+  45. http://wwwsearch.sourceforge.net/ClientCookie/#faq_pre

Added: packages/clientcookie/branches/upstream/current/cookietest.cgi
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/cookietest.cgi?rev=914&op=file
==============================================================================
--- packages/clientcookie/branches/upstream/current/cookietest.cgi (added)
+++ packages/clientcookie/branches/upstream/current/cookietest.cgi Mon Jun 19 07:05:08 2006
@@ -1,0 +1,39 @@
+#!/usr/bin/python
+# -*-python-*-
+
+# The copy of this script that lives at wwwsearch.sf.net is used by the
+# ClientCookie functional tests.
+
+print "Content-Type: text/html"
+print "Set-Cookie: foo=bar\n"
+import sys, os, string, cgi, Cookie
+
+from types import ListType
+
+print "<html><head><title>Cookies and form submission parameters</title>"
+cookie = Cookie.SimpleCookie()
+cookieHdr = os.environ.get("HTTP_COOKIE", "")
+cookie.load(cookieHdr)
+if not cookie.has_key("foo"):
+    print '<meta http-equiv="refresh" content="5">'
+print "</head>"
+print "<p>Received cookies:</p>"
+print "<pre>"
+print cgi.escape(os.environ.get("HTTP_COOKIE", ""))
+print "</pre>"
+if cookie.has_key("foo"):
+    print "Your browser supports cookies!"
+form = cgi.FieldStorage()
+print "<p>Received parameters:</p>"
+print "<pre>"
+for k in form.keys():
+    v = form[k]
+    if isinstance(v, ListType):
+        vs = []
+        for item in v:
+            vs.append(item.value)
+        text = string.join(vs, ", ")
+    else:
+        text = v.value
+    print "%s: %s" % (cgi.escape(k), cgi.escape(text))
+print "</pre></html>"

Propchange: packages/clientcookie/branches/upstream/current/cookietest.cgi
------------------------------------------------------------------------------
    svn:executable = *

Modified: packages/clientcookie/branches/upstream/current/doc.html
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/doc.html?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/doc.html (original)
+++ packages/clientcookie/branches/upstream/current/doc.html Mon Jun 19 07:05:08 2006
@@ -1,832 +1,857 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
-
-
-
-
-<html>
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-  <meta name="author" content="John J. Lee &lt;jjl at pobox.com&gt;">
-  <meta name="date" content="2005-12-04">
-  <meta name="keywords" content="cookie,HTTP,Python,web,client,client-side,HTML,META,HTTP-EQUIV,Refresh">
-  <title>ClientCookie documentation</title>
-  <style type="text/css" media="screen">@import "../styles/style.css";</style>
-  <style type="text/css" media="screen">@import "../styles/cookie_style.css";</style>
-  <base href="http://wwwsearch.sourceforge.net/ClientCookie/">
-</head>
-<body>
-
-<div id="sf"><a href="http://sourceforge.net">
-<img src="http://sourceforge.net/sflogo.php?group_id=48205&amp;type=2"
- width="125" height="37" alt="SourceForge.net Logo"></a></div>
-
-<h1>ClientCookie</h1>
-
-<div id="Content">
-
-<a name="examples"></a>
-<h2>Examples</h2>
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-response = ClientCookie.urlopen(<span class="pystr">"http://foo.bar.com/"</span>)</pre>
-
-
-<p>This function behaves identically to <code>urllib2.urlopen()</code>, except
-that it deals with cookies automatically.  That's probably all you need to know
-(except that ClientCookie provides <a href="./doc.html#extras">features other
-than cookie handling</a> that you can turn on).
-
-<p>Here is a more complicated example, involving <code>Request</code> objects
-(useful if you want to pass <code>Request</code>s around, add headers to them,
-etc.):
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-request = ClientCookie.Request(<span class="pystr">"http://www.acme.com/"</span>)
-<span class="pycmt"># note we're using the urlopen from ClientCookie, not urllib2
-</span>response = ClientCookie.urlopen(request)
-<span class="pycmt"># let's say this next request requires a cookie that was set in response
-</span>request2 = ClientCookie.Request(<span class="pystr">"http://www.acme.com/flying_machines.html"</span>)
-response2 = ClientCookie.urlopen(request2)
-
-<span class="pykw">print</span> response2.geturl()
-<span class="pykw">print</span> response2.info()  <span class="pycmt"># headers</span>
-<span class="pykw">print</span> response2.read()  <span class="pycmt"># body (readline and readlines work too)</span></pre>
-
-
-<p>(The above example would also work with <code>urllib2.Request</code> objects
-too, since <code>ClientCookie.HTTPRequestUpgradeProcessor</code> knows about
-that class, but don't if you can avoid it, because this is an obscure hack for
-compatibility purposes only).
-
-<p>In these examples, the workings are hidden inside the
-<code>ClientCookie.urlopen()</code> function, which is an extension of
-<code>urllib2.urlopen()</code>.  Redirects, proxies and cookies are handled
-automatically by this function (note that you may need a bit of configuration
-to get your proxies correctly set up: see <code>urllib2</code> documentation).
-
-<p>Cookie processing (etc.) is handled by processor objects, which are an
-extension of <code>urllib2</code>'s handlers: <code>HTTPCookieProcessor</code>,
-<code>HTTPRefererProcessor</code>, <code>SeekableProcessor</code> etc.  They
-are used like any other handler.  There is quite a bit of other
-<code>urllib2</code>-workalike code, too.  Note: This duplication has gone away
-in Python 2.4, since 2.4's <code>urllib2</code> contains the processor
-extensions from ClientCookie, so you can simply use ClientCookie's processor
-classes direct with 2.4's <code>urllib2</code>; also, ClientCookie's cookie
-functionality is included in Python 2.4 as module <code>cookielib</code> and
-<code>urllib2.HTTPCookieProcessor</code>.
-
-<p>There is also a <code>urlretrieve()</code> function, which works like
-<code>urllib.urlretrieve()</code>.
-
-<p>An example at a slightly lower level shows how the module processes
-cookies more clearly:
-
-<pre>
-<span class="pycmt"># Don't copy this blindly!  You probably want to follow the examples
-</span><span class="pycmt"># above, not this one.
-</span><span class="pykw">import</span> ClientCookie
-
-<span class="pycmt"># Build an opener that *doesn't* automatically call .add_cookie_header()
-</span><span class="pycmt"># and .extract_cookies(), so we can do it manually without interference.
-</span><span class="pykw">class</span> NullCookieProcessor(ClientCookie.HTTPCookieProcessor):
-    <span class="pykw">def</span> http_request(self, request): <span class="pykw">return</span> request
-    <span class="pykw">def</span> http_response(self, request, response): <span class="pykw">return</span> response
-opener = ClientCookie.build_opener(NullCookieProcessor)
-
-request = ClientCookie.Request(<span class="pystr">"http://www.acme.com/"</span>)
-response = ClientCookie.urlopen(request)
-cj = ClientCookie.CookieJar()
-cj.extract_cookies(response, request)
-<span class="pycmt"># let's say this next request requires a cookie that was set in response
-</span>request2 = ClientCookie.Request(<span class="pystr">"http://www.acme.com/flying_machines.html"</span>)
-cj.add_cookie_header(request2)
-response2 = ClientCookie.urlopen(request2)</pre>
-
-
-<p>The <code>CookieJar</code> class does all the work.  There are essentially
-two operations: <code>.extract_cookies()</code> extracts HTTP cookies from
-<code>Set-Cookie</code> (the original <a
-href="http://www.netscape.com/newsref/std/cookie_spec.html">Netscape cookie
-standard</a>) and <code>Set-Cookie2</code> (<a
-href="http://www.ietf.org/rfc/rfc2965.txt">RFC 2965</a>) headers from a
-response if and only if they should be set given the request, and
-<code>.add_cookie_header()</code> adds <code>Cookie</code> headers if and only
-if they are appropriate for a particular HTTP request.  Incoming cookies are
-checked for acceptability based on the host name, etc.  Cookies are only set on
-outgoing requests if they match the request's host name, path, etc.
-
-<p><strong>Note that if you're using <code>ClientCookie.urlopen()</code> (or if
-you're using <code>ClientCookie.HTTPCookieProcessor</code> by some other
-means), you don't need to call <code>.extract_cookies()</code> or
-<code>.add_cookie_header()</code> yourself</strong>.  If, on the other hand,
-you don't want to use <code>urllib2</code>, you will need to use this pair of
-methods.  You can make your own <code>request</code> and <code>response</code>
-objects, which must support the interfaces described in the docstrings of
-<code>.extract_cookies()</code> and <code>.add_cookie_header()</code>.
-
-<p>There are also some <code>CookieJar</code> subclasses which can store
-cookies in files and databases.  <code>FileCookieJar</code> is the abstract
-class for <code>CookieJar</code>s that can store cookies in disk files.
-<code>LWPCookieJar</code> saves cookies in a format compatible with the
-libwww-perl library.  This class is convenient if you want to store cookies in
-a human-readable file:
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-cj = ClientCookie.LWPCookieJar()
-cj.revert(<span class="pystr">"cookie3.txt"</span>)
-opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
-r = opener.open(<span class="pystr">"http://foobar.com/"</span>)
-cj.save(<span class="pystr">"cookie3.txt"</span>)</pre>
-
-
-<p>The <code>.revert()</code> method discards all existing cookies held by the
-<code>CookieJar</code> (it won't lose any existing cookies if the load fails).
-The <code>.load()</code> method, on the other hand, adds the loaded cookies to
-existing cookies held in the <code>CookieJar</code> (old cookies are kept
-unless overwritten by newly loaded ones).
-
-<p><code>MozillaCookieJar</code> can load and save to the
-Mozilla/Netscape/lynx-compatible <code>'cookies.txt'</code> format.  This
-format loses some information (unusual and nonstandard cookie attributes such
-as comment, and also information specific to RFC 2965 cookies).  The subclass
-<code>MSIECookieJar</code> can load (but not save, yet) from Microsoft Internet
-Explorer's cookie files (on Windows).  <code>BSDDBCookieJar</code> (NOT FULLY
-TESTED!) saves to a BSDDB database using the standard library's
-<code>bsddb</code> module.  There's an unfinished <code>MSIEDBCookieJar</code>,
-which uses (reads and writes) the Windows MSIE cookie database directly, rather
-than storing copies of cookies as <code>MSIECookieJar</code> does.
-
-<h2>Important note</h2>
-
-<p>Only use names you can import directly from the <code>ClientCookie</code>
-package, and that don't start with a single underscore.  Everything else is
-subject to change or disappearance without notice.
-
-<a name="browsers"></a>
-<h2>Cooperating with Mozilla/Netscape, lynx and Internet Explorer</h2>
-
-<p>The subclass <code>MozillaCookieJar</code> differs from
-<code>CookieJar</code> only in storing cookies using a different,
-Mozilla/Netscape-compatible, file format.  The lynx browser also uses this
-format.  This file format can't store RFC 2965 cookies, so they are downgraded
-to Netscape cookies on saving.  <code>LWPCookieJar</code> itself uses a
-libwww-perl specific format (`Set-Cookie3') - see the example above.  Python
-and your browser should be able to share a cookies file (note that the file
-location here will differ on non-unix OSes):
-
-<p><strong>WARNING:</strong> you may want to backup your browser's cookies file
-if you use <code>MozillaCookieJar</code> to save cookies.  I <em>think</em> it
-works, but there have been bugs in the past!
-
-<pre>
-<span class="pykw">import</span> os, ClientCookie
-cookies = ClientCookie.MozillaCookieJar()
-cookies.load(os.path.join(os.environ[<span class="pystr">"HOME"</span>], <span class="pystr">"/.netscape/cookies.txt"</span>))
-<span class="pycmt"># see also the save and revert methods</span></pre>
-
-
-<p>Note that cookies saved while Mozilla is running will get clobbered by
-Mozilla - see <code>MozillaCookieJar.__doc__</code>.
-
-<p><code>MSIECookieJar</code> does the same for Microsoft Internet Explorer
-(MSIE) 5.x and 6.x on Windows, but does not allow saving cookies in this
-format.  In future, the Windows API calls might be used to load and save
-(though the index has to be read directly, since there is no API for that,
-AFAIK; there's also an unfinished <code>MSIEDBCookieJar</code>, which uses
-(reads and writes) the Windows MSIE cookie database directly, rather than
-storing copies of cookies as <code>MSIECookieJar</code> does).
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-cj = ClientCookie.MSIECookieJar(delayload=True)
-cj.load_from_registry()  <span class="pycmt"># finds cookie index file from registry</span></pre>
-
-
-<p>A true <code>delayload</code> argument speeds things up.
-
-<p>On Windows 9x (win 95, win 98, win ME), you need to supply a username to the
-<code>.load_from_registry()</code> method:
-
-<pre>
-cj.load_from_registry(username=<span class="pystr">"jbloggs"</span>)</pre>
-
-
-<p>Konqueror/Safari and Opera use different file formats, which aren't yet
-supported.
-
-<a name="file"></a>
-<h2>Saving cookies in a file</h2>
-
-<p>If you have no need to co-operate with a browser, the most convenient way to
-save cookies on disk between sessions in human-readable form is to use
-<code>LWPCookieJar</code>.  This class uses a libwww-perl specific format
-(`Set-Cookie3').  Unlike <code>MozilliaCookieJar</code>, this file format
-doesn't lose information.
-
-<a name="database"></a>
-<h2>Saving cookies in a database</h2>
-
-<p><code>BSDDBCookieJar</code> (NOT FULLY TESTED!) saves to a BSDDB database
-using the standard library's <code>bsddb</code> module.  Rather than using the
-constructor directly, you probably want to use
-<code>CreateBSDDBCookieJar<code>, which will create the named database file if
-it doesn't exist; otherwise, it will be opened.
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-cj = ClientCookie.CreateBSDDBCookieJar(<span class="pystr">"cookies.db"</span>)</pre>
-
-
-<p>See also <code>MSIEDBCookieJar</code> <a href="browsers">above</a>.
-
-<a name="cookiejar"></a>
-<h2>Using your own CookieJar instance</h2>
-
-<p>You might want to do this to <a href="./doc.html#browsers">use your
-browser's cookies</a>, to customize <code>CookieJar</code>'s behaviour by
-passing constructor arguments, or to be able to get at the cookies it will hold
-(for example, for saving cookies between sessions and for debugging).
-
-<p>If you're using the higher-level <code>urllib2</code>-like interface
-(<code>urlopen()</code>, etc), you'll have to let it know what
-<code>CookieJar</code> it should use:
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-cookies = ClientCookie.CookieJar()
-<span class="pycmt"># build_opener() adds standard handlers (such as HTTPHandler and
-</span><span class="pycmt"># HTTPCookieProcessor) by default.  The cookie processor we supply
-</span><span class="pycmt"># will replace the default one.
-</span>opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cookies))
-
-r = opener.open(<span class="pystr">"http://acme.com/"</span>)  <span class="pycmt"># GET</span>
-r = opener.open(<span class="pystr">"http://acme.com/"</span>, data)  <span class="pycmt"># POST</span></pre>
-
-
-<p>The <code>urlopen()</code> function uses a global
-<code>OpenerDirector</code> instance to do its work, so if you want to use
-<code>urlopen()</code> with your own <code>CookieJar</code>, install the
-<code>OpenerDirector</code> you built with <code>build_opener()</code> using
-the <code>ClientCookie.install_opener()</code> function, then proceed as usual:
-
-<pre>
-ClientCookie.install_opener(opener)
-r = ClientCookie.urlopen(<span class="pystr">"http://www.acme.com/"</span>)</pre>
-
-
-<p>Of course, everyone using <code>urlopen</code> is using the same global
-<code>CookieJar</code> instance!
-
-<a name="policy"></a>
-
-<p>You can set a policy object (must satisfy the interface defined by
-<code>ClientCookie.CookiePolicy</code>), which determines which cookies are
-allowed to be set and returned.  Use the policy argument to the
-<code>CookieJar</code> constructor, or use the .set_policy() method.  The
-default implementation has some useful switches:
-
-<pre>
-<span class="pykw">from</span> ClientCookie <span class="pykw">import</span> CookieJar, DefaultCookiePolicy as Policy
-cookies = CookieJar()
-<span class="pycmt"># turn on RFC 2965 cookies, be more strict about domains when setting and
-</span><span class="pycmt"># returning Netscape cookies, and block some domains from setting cookies
-</span><span class="pycmt"># or having them returned (read the DefaultCookiePolicy docstring for the
-</span><span class="pycmt"># domain matching rules here)
-</span>policy = Policy(rfc2965=True, strict_ns_domain=Policy.DomainStrict,
-                blocked_domains=[<span class="pystr">"ads.net"</span>, <span class="pystr">".ads.net"</span>])
-cookies.set_policy(policy)</pre>
-
-
-
-<a name="extras"></a>
-<h2>Optional extras: robots.txt, HTTP-EQUIV, Refresh, Referer and seekable responses</h2>
-
-<p>These are implemented as processor classes.  Processors are an extension of
-<code>urllib2</code>'s handlers (now a standard part of urllib2 in Python 2.4):
-you just pass them to <code>build_opener()</code> (example code below).
-
-<dl>
-
-<dt><code>HTTPRobotRulesProcessor</code>
-
-<dd><p>WWW Robots (also called wanderers or spiders) are programs that traverse
-many pages in the World Wide Web by recursively retrieving linked pages.  This
-kind of program can place significant loads on web servers, so there is a <a
-href="http://www.robotstxt.org/wc/norobots.html">standard</a> for a <code>
-robots.txt</code> file by which web site operators can request robots to keep
-out of their site, or out of particular areas of it.  This processor uses the
-standard Python library's <code>robotparser</code> module.  It raises
-<code>ClientCookie.RobotExclusionError</code> (subclass of
-<code>urllib2.HTTPError</code>) if an attempt is made to open a URL prohibited
-by <code>robots.txt</code>.  XXX ATM, this makes use of code in the
-<code>robotparser</code> module that uses <code>urllib</code> - this will
-likely change in future to use <code>urllib2</code>.
-
-<dt><code>HTTPEquivProcessor</code>
-
-<dd><p>The <code>&lt;META HTTP-EQUIV&gt;</code> tag is a way of including data
-in HTML to be treated as if it were part of the HTTP headers.  ClientCookie can
-automatically read these tags and add the <code>HTTP-EQUIV</code> headers to
-the response object's real HTTP headers.  The HTML is left unchanged.
-
-<dt><code>HTTPRefreshProcessor</code>
-
-<dd><p>The <code>Refresh</code> HTTP header is a non-standard header which is
-widely used.  It requests that the user-agent follow a URL after a specified
-time delay.  ClientCookie can treat these headers (which may have been set in
-<code>&lt;META HTTP-EQUIV&gt;</code> tags) as if they were 302 redirections.
-Exactly when and how <code>Refresh</code> headers are handled is configurable
-using the constructor arguments.
-
-<dt><code>SeekableProcessor</code>
-
-<dd><p>This makes ClientCookie's response objects <code>seek()</code>able.
-Seeking is done lazily (ie. the response object only reads from the socket as
-necessary, rather than slurping in all the data before the response is returned
-to you).  XXX only works for HTTP ATM, I think
-
-<dt><code>HTTPRefererProcessor</code>
-
-<dd><p>The <code>Referer</code> HTTP header lets the server know which URL
-you've just visited.  Some servers use this header as state information, and
-don't like it if this is not present.  It's a chore to add this header by hand
-every time you make a request.  This adds it automatically.
-<strong>NOTE</strong>: this only makes sense if you use each processor for a
-single chain of HTTP requests (so, for example, if you use a single
-HTTPRefererProcessor to fetch a series of URLs extracted from a single page,
-<strong>this will break</strong>).  The <a href="../mechanize/">mechanize</a>
-package does this properly.</p></dd>
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-cookies = ClientCookie.CookieJar()
-
-opener = ClientCookie.build_opener(ClientCookie.HTTPRefererProcessor,
-                                   ClientCookie.HTTPEquivProcessor,
-                                   ClientCookie.HTTPRefreshProcessor,
-                                   ClientCookie.SeekableProcessor)
-opener.open(<span class="pystr">"http://www.rhubarb.com/"</span>)</pre>
-
-
-</dl>
-
-
-<a name="requests"></a>
-<h2>Confusing fact about headers and Requests</h2>
-
-<p>ClientCookie automatically upgrades <code>urllib2.Request</code> objects to
-<code>ClientCookie.Request</code>, as a backwards-compatibility hack.  This
-means that you won't see any headers that are added to Request objects by
-handlers unless you use <code>ClientCookie.Request</code> in the first place.
-Sorry about that.
-
-
-<a name="headers"></a>
-<h2>Adding headers</h2>
-
-<p>Adding headers is done like so:
-
-<pre>
-<span class="pykw">import</span> ClientCookie, urllib2
-req = urllib2.Request(<span class="pystr">"http://foobar.com/"</span>)
-req.add_header(<span class="pystr">"Referer"</span>, <span class="pystr">"http://wwwsearch.sourceforge.net/ClientCookie/"</span>)
-r = ClientCookie.urlopen(req)</pre>
-
-
-<p>You can also use the headers argument to the <code>urllib2.Request</code>
-constructor.
-
-<p><code>urllib2</code> (in fact, ClientCookie takes over this task from
-<code>urllib2</code>) adds some headers to <code>Request</code> objects
-automatically - see the next section for details.
-
-
-<h2>Changing the automatically-added headers (User-Agent)</h2>
-
-<p><code>OpenerDirector</code> automatically adds a <code>User-Agent</code>
-header to every <code>Request</code>.
-
-<p>To change this and/or add similar headers, use your own
-<code>OpenerDirector</code>:
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-cookies = ClientCookie.CookieJar()
-opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cookies))
-opener.addheaders = [(<span class="pystr">"User-agent"</span>, <span class="pystr">"Mozilla/5.0 (compatible; MyProgram/0.1)"</span>),
-                     (<span class="pystr">"From"</span>, <span class="pystr">"responsible.person at example.com"</span>)]</pre>
-
-
-<p>Again, to use <code>urlopen()</code>, install your
-<code>OpenerDirector</code> globally:
-
-<pre>
-ClientCookie.install_opener(opener)
-r = ClientCookie.urlopen(<span class="pystr">"http://acme.com/"</span>)</pre>
-
-
-<p>Also, a few standard headers (<code>Content-Length</code>,
-<code>Content-Type</code> and <code>Host</code>) are added when the
-<code>Request</code> is passed to <code>urlopen()</code> (or
-<code>OpenerDirector.open()</code>).  ClientCookie explictly adds these (and
-<code>User-Agent</code>) to the <code>Request</code> object, unlike versions of
-<code>urllib2</code> before Python 2.4 (but <strong>note</strong> that
-Content-Length is an exception to this rule: it is sent, but not explicitly
-added to the <code>Request</code>'s headers; this is due to a bug in
-<code>httplib</code> in Python 2.3 and earlier).  You shouldn't need to change
-these headers, but since this is done by <code>AbstractHTTPHandler</code>, you
-can change the way it works by passing a subclass of that handler to
-<code>build_opener()</code> (or, as always, by constructing an opener yourself
-and calling .add_handler()).
-
-
-<a name="unverifiable"></a>
-<h2>Initiating unverifiable transactions</h2>
-
-<p>This section is only of interest for correct handling of third-party HTTP
-cookies.  See <a href="./doc.html#standards">below</a> for an explanation of
-'third-party'.
-
-<p>First, some terminology.
-
-<p>An <em>unverifiable request</em> (defined fully by RFC 2965) is one whose
-URL the user did not have the option to approve.  For example, a transaction is
-unverifiable if the request is for an image in an HTML document, and the user
-had no option to approve the fetching of the image from a particular URL.
-
-<p>The <em>request-host of the origin transaction</em> (defined fully by RFC
-2965) is the host name or IP address of the original request that was initiated
-by the user.  For example, if the request is for an image in an HTML document,
-this is the request-host of the request for the page containing the image.
-
-<p><strong>ClientCookie knows that redirected transactions are unverifiable,
-and will handle that on its own (ie. you don't need to think about the origin
-request-host or verifiability yourself).</strong>
-
-<p>If you want to initiate an unverifiable transaction yourself (which you
-should if, for example, you're downloading the images from a page, and 'the
-user' hasn't explicitly OKed those URLs):
-
-<ol>
-
-  <li>If you're using a <code>urllib2.Request</code> from Python 2.3 or
-  earlier, set the <code>unverifiable</code> and <code>origin_req_host</code>
-  attributes on your <code>Request</code> instance:
-
-<pre>
-request.unverifiable = True
-request.origin_req_host = <span class="pystr">"www.example.com"</span></pre>
-
-
-  <li>If you're using a <code>urllib2.Request</code> from Python 2.4 or later,
-  or you're using a <code>ClientCookie.Request<code>, use the
-  <code>unverifiable</code> and <code>origin_req_host</code> arguments to the
-  constructor:
-
-<pre>
-request = Request(origin_req_host=<span class="pystr">"www.example.com"</span>, unverifiable=True)</pre>
-
-
-</ol>
-
-
-<a name="rfc2965"></a>
-<h2>RFC 2965 handling</h2>
-
-<p>RFC 2965 handling is switched off by default, because few browsers implement
-it, so the RFC 2965 protocol is essentially never seen on the internet.  To
-switch it on, see <a href="./doc.html#policy">here</a>.
-
-
-<a name="debugging"></a>
-<h2>Debugging</h2>
-
-<!--XXX move as much as poss. to General page-->
-
-<p>First, a few common problems.  The most frequent mistake people seem to make
-is to use <code>ClientCookie.urlopen()</code>, <em>and</em> the
-<code>.extract_cookies()</code> and <code>.add_cookie_header()</code> methods
-on a cookie object themselves.  If you use <code>ClientCookie.urlopen()</code>
-(or <code>OpenerDirector.open()</code>), the module handles extraction and
-adding of cookies by itself, so you should not call
-<code>.extract_cookies()</code> or <code>.add_cookie_header()</code>.
-
-<p>Are you sure the server is sending you any cookies in the first place?
-Maybe the server is keeping track of state in some other way
-(<code>HIDDEN</code> HTML form entries (possibly in a separate page referenced
-by a frame), URL-encoded session keys, IP address, HTTP <code>Referer</code>
-headers)?  Perhaps some embedded script in the HTML is setting cookies (see
-below)?  Maybe you messed up your request, and the server is sending you some
-standard failure page (even if the page doesn't appear to indicate any
-failure).  Sometimes, a server wants particular headers set to the values it
-expects, or it won't play nicely.  The most frequent offenders here are the
-<code>Referer</code> [<em>sic</em>] and / or <code>User-Agent</code> HTTP
-headers (<a href="./doc.html#headers">see above</a> for how to set these).  The
-<code>User-Agent</code> header may need to be set to a value like that of a
-popular browser.  The <code>Referer</code> header may need to be set to the URL
-that the server expects you to have followed a link from.  Occasionally, it may
-even be that operators deliberately configure a server to insist on precisely
-the headers that the popular browsers (MS Internet Explorer, Mozilla/Netscape,
-Opera, Konqueror/Safari) generate, but remember that incompetence (possibly on
-your part) is more probable than deliberate sabotage (and if a site owner is
-that keen to stop robots, you probably shouldn't be scraping it anyway).
-
-<p>When you <code>.save()</code> to or
-<code>.load()</code>/<code>.revert()</code> from a file, single-session cookies
-will expire unless you explicitly request otherwise with the
-<code>ignore_discard</code> argument.  This may be your problem if you find
-cookies are going away after saving and loading.
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-cj = ClientCookie.LWPCookieJar()
-opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
-ClientCookie.install_opener(opener)
-r = ClientCookie.urlopen(<span class="pystr">"http://foobar.com/"</span>)
-cj.save(<span class="pystr">"/some/file"</span>, ignore_discard=True, ignore_expires=True)</pre>
-
-
-<p>If none of the advice above solves your problem quickly, try comparing the
-headers and data that you are sending out with those that a browser emits.
-Often this will give you the clue you need.  Of course, you'll want to check
-that the browser is able to do manually what you're trying to achieve
-programatically before minutely examining the headers.  Make sure that what you
-do manually is <em>exactly</em> the same as what you're trying to do from
-Python - you may simply be hitting a server bug that only gets revealed if you
-view pages in a particular order, for example.  In order to see what your
-browser is sending to the server (even if HTTPS is in use), see <a
-href="../clientx.html">the General FAQ page</a>.  If nothing is obviously wrong
-with the requests your program is sending and you're out of ideas, you can try
-the last resort of good old brute force binary-search debugging.  Temporarily
-switch to sending HTTP headers (with <code>httplib</code>).  Start by copying
-Netscape/Mozilla or IE slavishly (apart from session IDs, etc., of course),
-then begin the tedious process of mutating your headers and data until they
-match what your higher-level code was sending.  This will at least reliably
-find your problem.
-
-<p>You can turn on display of HTTP headers:
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-hh = ClientCookie.HTTPHandler()  <span class="pycmt"># you might want HTTPSHandler, too</span>
-hh.set_http_debuglevel(1)
-opener = ClientCookie.build_opener(hh)
-response = opener.open(url)</pre>
-
-
-<p>Alternatively, you can examine your individual request and response objects
-to see what's going on.  Note, though, that ClientCookie upgrades
-urllib2.Request objects to ClientCookie.Request, so you won't see any headers
-that are added to requests by handlers unless you use ClientCookie.Request in
-the first place.  ClientCookie's responses can be made <code>.seek()</code>able
-using <code>SeekableProcessor</code>.  It's often useful to use the
-<code>.seek()</code> method like this during debugging:
-
-<pre>
-...
-response = ClientCookie.urlopen(<span class="pystr">"http://spam.eggs.org/"</span>)
-<span class="pykw">print</span> response.read()
-response.seek(0)
-<span class="pycmt"># rest of code continues as if you'd never .read() the response
-</span>...</pre>
-
-
-<p>Also, note <code>HTTPRedirectDebugProcessor</code> (which prints information
-about redirections) and <code>HTTPResponseDebugProcessor</code> (which prints
-out all response bodies, including those that are read during redirections).
-<strong>NOTE</strong>: as well as having these processors in your
-<code>OpenerDirector</code> (for example, by passing them to
-<code>build_opener()</code>) you have to turn on logging at the
-<code>INFO</code> level or lower in order to see any output.
-
-<p>If you would like to see what is going on in ClientCookie's tiny mind, do
-this:
-
-<pre>
-<span class="pykw">import</span> ClientCookie
-<span class="pycmt"># ClientCookie.DEBUG covers masses of debugging information,
-</span><span class="pycmt"># ClientCookie.INFO just shows the output from HTTPRedirectDebugProcessor,
-</span>logger = ClientCookie.getLogger(<span class="pystr">"ClientCookie"</span>)
-logger.addHandler(ClientCookie.StreamHandler())
-logger.setLevel(ClientCookie.DEBUG)</pre>
-
-
-<p>(In Python 2.3 or newer, <code>logging.getLogger</code>,
-<code>logging.DEBUG</code>, <code>logging.INFO</code> etc. work just as well.)
-
-<p>The <code>DEBUG</code> level (as opposed to the <code>INFO</code> level) can
-actually be quite useful, as it explains why particular cookies are accepted or
-rejected and why they are or are not returned.
-
-<p>One final thing to note is that there are some catch-all bare
-<code>except:</code> statements in the module, which are there to handle
-unexpected bad input without crashing your program.  If this happens, it's a
-bug in ClientCookie, so please mail me the warning text.
-
-
-<a name="script"></a>
-<h2>Embedded script that sets cookies</h2>
-
-<p>It is possible to embed script in HTML pages (sandwiched between
-<code>&lt;SCRIPT&gt;here&lt;/SCRIPT&gt;</code> tags, and in
-<code>javascript:</code> URLs) - JavaScript / ECMAScript, VBScript, or even
-Python - that causes cookies to be set in a browser.  See the <a
-href="../bits/clientx.html">General FAQs</a> page for what to do about this.
-
-
-<a name="dates"></a>
-<h2>Parsing HTTP date strings</h2>
-
-<p>A function named <code>str2time</code> is provided by the package,
-which may be useful for parsing dates in HTTP headers.
-<code>str2time</code> is intended to be liberal, since HTTP date/time
-formats are poorly standardised in practice.  There is no need to use this
-function in normal operations: <code>CookieJar</code> instances keep track
-of cookie lifetimes automatically.  This function will stay around in some
-form, though the supported date/time formats may change.
-
-
-<a name="standards"></a>
-<h2>Note about cookie standards</h2>
-
-<p>The various cookie standards and their history form a case study of the
-terrible things that can happen to a protocol.  The long-suffering David
-Kristol has written a <a
-href="http://arxiv.org/abs/cs.SE/0105018">paper</a> about it, if you
-want to know the gory details.
-
-<p>Here is a summary.
-
-<p>The <a href="http://www.netscape.com/newsref/std/cookie_spec.html">Netscape
-protocol</a> (cookie_spec.html) is still the only standard supported by most
-browsers (including Internet Explorer and Netscape).  Be aware that
-cookie_spec.html is not, and never was, actually followed to the letter (or
-anything close) by anyone (including Netscape, IE and ClientCookie): the
-Netscape protocol standard is really defined by the behaviour of Netscape (and
-now IE).  Netscape cookies are also known as V0 cookies, to distinguish them
-from RFC 2109 or RFC 2965 cookies, which have a version cookie-attribute with a
-value of 1.
-
-<p><a href="http://www.ietf.org/rfcs/rfc2109.txt">RFC 2109</a> was introduced
-to fix some problems identified with the Netscape protocol, while still keeping
-the same HTTP headers (<code>Cookie</code> and <code>Set-Cookie</code>).  The
-most prominent of these problems is the 'third-party' cookie issue, which was
-an accidental feature of the Netscape protocol.  When one visits www.bland.org,
-one doesn't expect to get a cookie from www.lurid.com, a site one has never
-visited.  Depending on browser configuration, this can still happen, because
-the unreconstructed Netscape protocol is happy to accept cookies from, say, an
-image in a webpage (www.bland.org) that's included by linking to an
-advertiser's server (www.lurid.com).  This kind of event, where your browser
-talks to a server that you haven't explicitly okayed by some means, is what the
-RFCs call an 'unverifiable transaction'.  In addition to the potential for
-embarrassment caused by the presence of lurid.com's cookies on one's machine,
-this may also be used to track your movements on the web, because advertising
-agencies like doubleclick.net place ads on many sites.  RFC 2109 tried to
-change this by requiring cookies to be turned off during unverifiable
-transactions with third-party servers - unless the user explicitly asks them to
-be turned on.  This clashed with the business model of advertisers like
-doubleclick.net, who had started to take advantage of the third-party cookies
-'bug'.  Since the browser vendors were more interested in the advertisers'
-concerns than those of the browser users, this arguably doomed both RFC 2109
-and its successor, RFC 2965, from the start.  Other problems than the
-third-party cookie issue were also fixed by 2109.  However, even ignoring the
-advertising issue, 2109 was stillborn, because Internet Explorer and Netscape
-behaved differently in response to its extended <code>Set-Cookie</code>
-headers.  This was not really RFC 2109's fault: it worked the way it did to
-keep compatibility with the Netscape protocol as implemented by Netscape.
-Microsoft Internet Explorer (MSIE) was very new when the standard was designed,
-but was starting to be very popular when the standard was finalised.  XXX P3P,
-and MSIE & Mozilla options
-
-<p>XXX Apparently MSIE implements bits of RFC 2109 - but not very compliant
-(surprise).  Presumably other browsers do too, as a result.  ClientCookie
-already does allow Netscape cookies to have <code>max-age</code> and
-<code>port</code> cookie-attributes, and as far as I know that's the extent of
-the support present in MSIE.  I haven't tested, though!
-
-<p><a href="http://www.ietf.org/rfcs/rfc2965.txt">RFC 2965</a> attempted to fix
-the compatibility problem by introducing two new headers,
-<code>Set-Cookie2</code> and <code>Cookie2</code>.  Unlike the
-<code>Cookie</code> header, <code>Cookie2</code> does <em>not</em> carry
-cookies to the server - rather, it simply advertises to the server that RFC
-2965 is understood.  <code>Set-Cookie2</code> <em>does</em> carry cookies, from
-server to client: the new header means that both IE and Netscape completely
-ignore these cookies.  This prevents breakage, but introduces a chicken-egg
-problem that means 2965 may never be widely adopted, especially since Microsoft
-shows no interest in it.  XXX Rumour has it that the European Union is unhappy
-with P3P, and might introduce legislation that requires something better,
-forming a gap that RFC 2965 might fill - any truth in this?  Opera is the only
-browser I know of that supports the standard.  On the server side, Apache's
-<code>mod_usertrack</code> supports it.  One confusing point to note about RFC
-2965 is that it uses the same value (1) of the Version attribute in HTTP
-headers as does RFC 2109.
-
-<p>Most recently, it was discovered that RFC 2965 does not fully take account
-of issues arising when 2965 and Netscape cookies coexist, and errata were
-discussed on the W3C http-state mailing list, but the list traffic died and it
-seems RFC 2965 is dead as an internet protocol (but still a useful basis for
-implementing the de-facto standards, and perhaps as an intranet protocol).
-
-<p>Because Netscape cookies are so poorly specified, the general philosophy
-of the module's Netscape cookie implementation is to start with RFC 2965
-and open holes where required for Netscape protocol-compatibility.  RFC
-2965 cookies are <em>always</em> treated as RFC 2965 requires, of course!
-
-<a name="faq_use"></a>
-<h2>FAQs - usage</h2>
-<ul>
-  <li>Why don't I have any cookies?
-  <p>Read the <a href="./doc.html#debugging">debugging section</a> of this page.
-  <li>My response claims to be empty, but I know it's not!
-  <p>Did you call <code>response.read()</code> (eg., in a debug statement),
-     then forget that all the data has already been read?  In that case, you
-     may want to use <code>SeekableProcessor</code>.
-  <li>How do I download only part of a response body?
-  <p>Just call <code>.read()</code> or <code>.readline()</code> methods on your
-     response object as many times as you need.  The <code>.seek()</code> method
-     (which will only be there if you're using <code>SeekableProcessor</code>)
-     still works, because <code>SeekableProcessor</code>'s response objects
-     cache read data.
-  <li>What's the difference between the <code>.load()</code> and
-      <code>.revert()</code> methods of <code>CookieJar</code>?
-  <p><code>.load()</code> <emph>appends</emph> cookies from a file.
-     <code>.revert()</code> discards all existing cookies held by the
-     <code>CookieJar</code> first (but it won't lose any existing cookies if
-     the loading fails).
-  <li>Is it threadsafe?
-  <p>No.  <em>Tested</em> patches welcome.  Clarification: As far as I know,
-     it's perfectly possible to use ClientCookie in threaded code, but it
-     provides no synchronisation: you have to provide that yourself.
-  <li>How do I do &lt;X&gt;
-  <p>The module docstrings are worth reading if you want to do something
-     unusual.
-  <li>What's this &quot;processor&quot; business about?  I knew
-      <code>urllib2</code> used &quot;handlers&quot;, but not these
-      &quot;processors&quot;.
-  <p>This Python library <a href="http://www.python.org/sf/852995">patch</a>
-     contains an explanation.  Processors are now a standard part of urllib2
-     in Python 2.4.
-  <li>How do I use it without urllib2.py?
-  <p><pre>
-<span class="pykw">from</span> ClientCookie <span class="pykw">import</span> CookieJar
-<span class="pykw">print</span> CookieJar.extract_cookies.__doc__
-<span class="pykw">print</span> CookieJar.add_cookie_header.__doc__</pre>
-
-</ul>
-
-<p>I prefer questions and comments to be sent to the <a
-href="http://lists.sourceforge.net/lists/listinfo/wwwsearch-general">
-mailing list</a> rather than direct to me.
-
-<p><a href="mailto:jjl at pobox.com">John J. Lee</a>,
-December 2005.
-
-<hr>
-
-</div>
-
-<div id="Menu">
-
-<a href="..">Home</a><br>
-<br>
-<a href="../bits/GeneralFAQ.html">General FAQs</a><br>
-<br>
-<a href="../mechanize/">mechanize</a><br>
-<a href="../pullparser/">pullparser</a><br>
-<a href="../ClientCookie/">ClientCookie</a><br>
-<span class="thispage"><span class="subpage">ClientCookie docs</span></span><br>
-<a href="../ClientForm/">ClientForm</a><br>
-<br>
-<a href="../DOMForm/">DOMForm</a><br>
-<a href="../python-spidermonkey/">python-spidermonkey</a><br>
-<a href="../ClientTable/">ClientTable</a><br>
-<a href="../bits/urllib2_152.py">1.5.2 urllib2.py</a><br>
-<a href="../bits/urllib_152.py">1.5.2 urllib.py</a><br>
-
-<br>
-
-<a href="./doc.html#examples">Examples</a><br>
-<a href="./doc.html#browsers">Mozilla & MSIE</a><br>
-<a href="./doc.html#file">Cookies in a file</a><br>
-<a href="./doc.html#database">Cookies in a database</a><br>
-<a href="./doc.html#cookiejar">Using a <code>CookieJar</code></a><br>
-<a href="./doc.html#extras">Processors</a><br>
-<a href="./doc.html#requests">Request confusion</a><br>
-<a href="./doc.html#headers">Adding headers</a><br>
-<a href="./doc.html#unverifiable">Verifiability</a><br>
-<a href="./doc.html#rfc2965">RFC 2965</a><br>
-<a href="./doc.html#debugging">Debugging</a><br>
-<a href="./doc.html#script">Embedded scripts</a><br>
-<a href="./doc.html#dates">HTTP date parsing</a><br>
-<a href="./doc.html#standards">Standards</a><br>
-<a href="./doc.html#faq_use">FAQs - usage</a><br>
-
-</div>
-
-</body>
-
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+
+
+
+
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="author" content="John J. Lee &lt;jjl at pobox.com&gt;">
+  <meta name="date" content="2006-01-05">
+  <meta name="keywords" content="cookie,HTTP,Python,web,client,client-side,HTML,META,HTTP-EQUIV,Refresh">
+  <title>ClientCookie documentation</title>
+  <style type="text/css" media="screen">@import "../styles/style.css";</style>
+  <style type="text/css" media="screen">@import "../styles/cookie_style.css";</style>
+  <base href="http://wwwsearch.sourceforge.net/ClientCookie/">
+</head>
+<body>
+
+<div id="sf"><a href="http://sourceforge.net">
+<img src="http://sourceforge.net/sflogo.php?group_id=48205&amp;type=2"
+ width="125" height="37" alt="SourceForge.net Logo"></a></div>
+
+<h1>ClientCookie</h1>
+
+<div id="Content">
+
+<a name="examples"></a>
+<h2>Examples</h2>
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+response = ClientCookie.urlopen(<span class="pystr">"http://foo.bar.com/"</span>)</pre>
+
+
+<p>This function behaves identically to <code>urllib2.urlopen()</code>, except
+that it deals with cookies automatically.  That's probably all you need to know
+(except that ClientCookie provides <a href="./doc.html#extras">features other
+than cookie handling</a> that you can turn on).
+
+<p>Here is a more complicated example, involving <code>Request</code> objects
+(useful if you want to pass <code>Request</code>s around, add headers to them,
+etc.):
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+request = ClientCookie.Request(<span class="pystr">"http://www.acme.com/"</span>)
+<span class="pycmt"># note we're using the urlopen from ClientCookie, not urllib2
+</span>response = ClientCookie.urlopen(request)
+<span class="pycmt"># let's say this next request requires a cookie that was set in response
+</span>request2 = ClientCookie.Request(<span class="pystr">"http://www.acme.com/flying_machines.html"</span>)
+response2 = ClientCookie.urlopen(request2)
+
+<span class="pykw">print</span> response2.geturl()
+<span class="pykw">print</span> response2.info()  <span class="pycmt"># headers</span>
+<span class="pykw">print</span> response2.read()  <span class="pycmt"># body (readline and readlines work too)</span></pre>
+
+
+<p>(The above example would also work with <code>urllib2.Request</code> objects
+too, since <code>ClientCookie.HTTPRequestUpgradeProcessor</code> knows about
+that class, but don't if you can avoid it, because this is an obscure hack for
+compatibility purposes only).
+
+<p>In these examples, the workings are hidden inside the
+<code>ClientCookie.urlopen()</code> function, which is an extension of
+<code>urllib2.urlopen()</code>.  Redirects, proxies and cookies are handled
+automatically by this function (note that you may need a bit of configuration
+to get your proxies correctly set up: see <code>urllib2</code> documentation).
+
+<p>Cookie processing (etc.) is handled by processor objects, which are an
+extension of <code>urllib2</code>'s handlers: <code>HTTPCookieProcessor</code>,
+<code>HTTPRefererProcessor</code>, <code>SeekableProcessor</code> etc.  They
+are used like any other handler.  There is quite a bit of other
+<code>urllib2</code>-workalike code, too.  Note: This duplication has gone away
+in Python 2.4, since 2.4's <code>urllib2</code> contains the processor
+extensions from ClientCookie, so you can simply use ClientCookie's processor
+classes direct with 2.4's <code>urllib2</code>; also, ClientCookie's cookie
+functionality is included in Python 2.4 as module <code>cookielib</code> and
+<code>urllib2.HTTPCookieProcessor</code>.
+
+<p>There is also a <code>urlretrieve()</code> function, which works like
+<code>urllib.urlretrieve()</code>.
+
+<p>An example at a slightly lower level shows how the module processes
+cookies more clearly:
+
+<pre>
+<span class="pycmt"># Don't copy this blindly!  You probably want to follow the examples
+</span><span class="pycmt"># above, not this one.
+</span><span class="pykw">import</span> ClientCookie
+
+<span class="pycmt"># Build an opener that *doesn't* automatically call .add_cookie_header()
+</span><span class="pycmt"># and .extract_cookies(), so we can do it manually without interference.
+</span><span class="pykw">class</span> NullCookieProcessor(ClientCookie.HTTPCookieProcessor):
+    <span class="pykw">def</span> http_request(self, request): <span class="pykw">return</span> request
+    <span class="pykw">def</span> http_response(self, request, response): <span class="pykw">return</span> response
+opener = ClientCookie.build_opener(NullCookieProcessor)
+
+request = ClientCookie.Request(<span class="pystr">"http://www.acme.com/"</span>)
+response = ClientCookie.urlopen(request)
+cj = ClientCookie.CookieJar()
+cj.extract_cookies(response, request)
+<span class="pycmt"># let's say this next request requires a cookie that was set in response
+</span>request2 = ClientCookie.Request(<span class="pystr">"http://www.acme.com/flying_machines.html"</span>)
+cj.add_cookie_header(request2)
+response2 = ClientCookie.urlopen(request2)</pre>
+
+
+<p>The <code>CookieJar</code> class does all the work.  There are essentially
+two operations: <code>.extract_cookies()</code> extracts HTTP cookies from
+<code>Set-Cookie</code> (the original <a
+href="http://www.netscape.com/newsref/std/cookie_spec.html">Netscape cookie
+standard</a>) and <code>Set-Cookie2</code> (<a
+href="http://www.ietf.org/rfc/rfc2965.txt">RFC 2965</a>) headers from a
+response if and only if they should be set given the request, and
+<code>.add_cookie_header()</code> adds <code>Cookie</code> headers if and only
+if they are appropriate for a particular HTTP request.  Incoming cookies are
+checked for acceptability based on the host name, etc.  Cookies are only set on
+outgoing requests if they match the request's host name, path, etc.
+
+<p><strong>Note that if you're using <code>ClientCookie.urlopen()</code> (or if
+you're using <code>ClientCookie.HTTPCookieProcessor</code> by some other
+means), you don't need to call <code>.extract_cookies()</code> or
+<code>.add_cookie_header()</code> yourself</strong>.  If, on the other hand,
+you don't want to use <code>urllib2</code>, you will need to use this pair of
+methods.  You can make your own <code>request</code> and <code>response</code>
+objects, which must support the interfaces described in the docstrings of
+<code>.extract_cookies()</code> and <code>.add_cookie_header()</code>.
+
+<p>There are also some <code>CookieJar</code> subclasses which can store
+cookies in files and databases.  <code>FileCookieJar</code> is the abstract
+class for <code>CookieJar</code>s that can store cookies in disk files.
+<code>LWPCookieJar</code> saves cookies in a format compatible with the
+libwww-perl library.  This class is convenient if you want to store cookies in
+a human-readable file:
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+cj = ClientCookie.LWPCookieJar()
+cj.revert(<span class="pystr">"cookie3.txt"</span>)
+opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
+r = opener.open(<span class="pystr">"http://foobar.com/"</span>)
+cj.save(<span class="pystr">"cookie3.txt"</span>)</pre>
+
+
+<p>The <code>.revert()</code> method discards all existing cookies held by the
+<code>CookieJar</code> (it won't lose any existing cookies if the load fails).
+The <code>.load()</code> method, on the other hand, adds the loaded cookies to
+existing cookies held in the <code>CookieJar</code> (old cookies are kept
+unless overwritten by newly loaded ones).
+
+<p><code>MozillaCookieJar</code> can load and save to the
+Mozilla/Netscape/lynx-compatible <code>'cookies.txt'</code> format.  This
+format loses some information (unusual and nonstandard cookie attributes such
+as comment, and also information specific to RFC 2965 cookies).  The subclass
+<code>MSIECookieJar</code> can load (but not save, yet) from Microsoft Internet
+Explorer's cookie files (on Windows).  <code>BSDDBCookieJar</code> (NOT FULLY
+TESTED!) saves to a BSDDB database using the standard library's
+<code>bsddb</code> module.  There's an unfinished <code>MSIEDBCookieJar</code>,
+which uses (reads and writes) the Windows MSIE cookie database directly, rather
+than storing copies of cookies as <code>MSIECookieJar</code> does.
+
+<h2>Important note</h2>
+
+<p>Only use names you can import directly from the <code>ClientCookie</code>
+package, and that don't start with a single underscore.  Everything else is
+subject to change or disappearance without notice.
+
+<a name="browsers"></a>
+<h2>Cooperating with Mozilla/Netscape, lynx and Internet Explorer</h2>
+
+<p>The subclass <code>MozillaCookieJar</code> differs from
+<code>CookieJar</code> only in storing cookies using a different,
+Mozilla/Netscape-compatible, file format.  The lynx browser also uses this
+format.  This file format can't store RFC 2965 cookies, so they are downgraded
+to Netscape cookies on saving.  <code>LWPCookieJar</code> itself uses a
+libwww-perl specific format (`Set-Cookie3') - see the example above.  Python
+and your browser should be able to share a cookies file (note that the file
+location here will differ on non-unix OSes):
+
+<p><strong>WARNING:</strong> you may want to backup your browser's cookies file
+if you use <code>MozillaCookieJar</code> to save cookies.  I <em>think</em> it
+works, but there have been bugs in the past!
+
+<pre>
+<span class="pykw">import</span> os, ClientCookie
+cookies = ClientCookie.MozillaCookieJar()
+cookies.load(os.path.join(os.environ[<span class="pystr">"HOME"</span>], <span class="pystr">"/.netscape/cookies.txt"</span>))
+<span class="pycmt"># see also the save and revert methods</span></pre>
+
+
+<p>Note that cookies saved while Mozilla is running will get clobbered by
+Mozilla - see <code>MozillaCookieJar.__doc__</code>.
+
+<p><code>MSIECookieJar</code> does the same for Microsoft Internet Explorer
+(MSIE) 5.x and 6.x on Windows, but does not allow saving cookies in this
+format.  In future, the Windows API calls might be used to load and save
+(though the index has to be read directly, since there is no API for that,
+AFAIK; there's also an unfinished <code>MSIEDBCookieJar</code>, which uses
+(reads and writes) the Windows MSIE cookie database directly, rather than
+storing copies of cookies as <code>MSIECookieJar</code> does).
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+cj = ClientCookie.MSIECookieJar(delayload=True)
+cj.load_from_registry()  <span class="pycmt"># finds cookie index file from registry</span></pre>
+
+
+<p>A true <code>delayload</code> argument speeds things up.
+
+<p>On Windows 9x (win 95, win 98, win ME), you need to supply a username to the
+<code>.load_from_registry()</code> method:
+
+<pre>
+cj.load_from_registry(username=<span class="pystr">"jbloggs"</span>)</pre>
+
+
+<p>Konqueror/Safari and Opera use different file formats, which aren't yet
+supported.
+
+<a name="file"></a>
+<h2>Saving cookies in a file</h2>
+
+<p>If you have no need to co-operate with a browser, the most convenient way to
+save cookies on disk between sessions in human-readable form is to use
+<code>LWPCookieJar</code>.  This class uses a libwww-perl specific format
+(`Set-Cookie3').  Unlike <code>MozilliaCookieJar</code>, this file format
+doesn't lose information.
+
+<a name="database"></a>
+<h2>Saving cookies in a database</h2>
+
+<p><code>BSDDBCookieJar</code> (NOT FULLY TESTED!) saves to a BSDDB database
+using the standard library's <code>bsddb</code> module.  Rather than using the
+constructor directly, you probably want to use
+<code>CreateBSDDBCookieJar<code>, which will create the named database file if
+it doesn't exist; otherwise, it will be opened.
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+cj = ClientCookie.CreateBSDDBCookieJar(<span class="pystr">"cookies.db"</span>)</pre>
+
+
+<p>See also <code>MSIEDBCookieJar</code> <a href="browsers">above</a>.
+
+<a name="cookiejar"></a>
+<h2>Using your own CookieJar instance</h2>
+
+<p>You might want to do this to <a href="./doc.html#browsers">use your
+browser's cookies</a>, to customize <code>CookieJar</code>'s behaviour by
+passing constructor arguments, or to be able to get at the cookies it will hold
+(for example, for saving cookies between sessions and for debugging).
+
+<p>If you're using the higher-level <code>urllib2</code>-like interface
+(<code>urlopen()</code>, etc), you'll have to let it know what
+<code>CookieJar</code> it should use:
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+cookies = ClientCookie.CookieJar()
+<span class="pycmt"># build_opener() adds standard handlers (such as HTTPHandler and
+</span><span class="pycmt"># HTTPCookieProcessor) by default.  The cookie processor we supply
+</span><span class="pycmt"># will replace the default one.
+</span>opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cookies))
+
+r = opener.open(<span class="pystr">"http://acme.com/"</span>)  <span class="pycmt"># GET</span>
+r = opener.open(<span class="pystr">"http://acme.com/"</span>, data)  <span class="pycmt"># POST</span></pre>
+
+
+<p>The <code>urlopen()</code> function uses a global
+<code>OpenerDirector</code> instance to do its work, so if you want to use
+<code>urlopen()</code> with your own <code>CookieJar</code>, install the
+<code>OpenerDirector</code> you built with <code>build_opener()</code> using
+the <code>ClientCookie.install_opener()</code> function, then proceed as usual:
+
+<pre>
+ClientCookie.install_opener(opener)
+r = ClientCookie.urlopen(<span class="pystr">"http://www.acme.com/"</span>)</pre>
+
+
+<p>Of course, everyone using <code>urlopen</code> is using the same global
+<code>CookieJar</code> instance!
+
+<a name="policy"></a>
+
+<p>You can set a policy object (must satisfy the interface defined by
+<code>ClientCookie.CookiePolicy</code>), which determines which cookies are
+allowed to be set and returned.  Use the policy argument to the
+<code>CookieJar</code> constructor, or use the .set_policy() method.  The
+default implementation has some useful switches:
+
+<pre>
+<span class="pykw">from</span> ClientCookie <span class="pykw">import</span> CookieJar, DefaultCookiePolicy as Policy
+cookies = CookieJar()
+<span class="pycmt"># turn on RFC 2965 cookies, be more strict about domains when setting and
+</span><span class="pycmt"># returning Netscape cookies, and block some domains from setting cookies
+</span><span class="pycmt"># or having them returned (read the DefaultCookiePolicy docstring for the
+</span><span class="pycmt"># domain matching rules here)
+</span>policy = Policy(rfc2965=True, strict_ns_domain=Policy.DomainStrict,
+                blocked_domains=[<span class="pystr">"ads.net"</span>, <span class="pystr">".ads.net"</span>])
+cookies.set_policy(policy)</pre>
+
+
+
+<a name="extras"></a>
+<h2>Optional extras: robots.txt, HTTP-EQUIV, Refresh, Referer and seekable responses</h2>
+
+<p>These are implemented as processor classes.  Processors are an extension of
+<code>urllib2</code>'s handlers (now a standard part of urllib2 in Python 2.4):
+you just pass them to <code>build_opener()</code> (example code below).
+
+<dl>
+
+<dt><code>HTTPRobotRulesProcessor</code>
+
+<dd><p>WWW Robots (also called wanderers or spiders) are programs that traverse
+many pages in the World Wide Web by recursively retrieving linked pages.  This
+kind of program can place significant loads on web servers, so there is a <a
+href="http://www.robotstxt.org/wc/norobots.html">standard</a> for a <code>
+robots.txt</code> file by which web site operators can request robots to keep
+out of their site, or out of particular areas of it.  This processor uses the
+standard Python library's <code>robotparser</code> module.  It raises
+<code>ClientCookie.RobotExclusionError</code> (subclass of
+<code>urllib2.HTTPError</code>) if an attempt is made to open a URL prohibited
+by <code>robots.txt</code>.  XXX ATM, this makes use of code in the
+<code>robotparser</code> module that uses <code>urllib</code> - this will
+likely change in future to use <code>urllib2</code>.
+
+<dt><code>HTTPEquivProcessor</code>
+
+<dd><p>The <code>&lt;META HTTP-EQUIV&gt;</code> tag is a way of including data
+in HTML to be treated as if it were part of the HTTP headers.  ClientCookie can
+automatically read these tags and add the <code>HTTP-EQUIV</code> headers to
+the response object's real HTTP headers.  The HTML is left unchanged.
+
+<dt><code>HTTPRefreshProcessor</code>
+
+<dd><p>The <code>Refresh</code> HTTP header is a non-standard header which is
+widely used.  It requests that the user-agent follow a URL after a specified
+time delay.  ClientCookie can treat these headers (which may have been set in
+<code>&lt;META HTTP-EQUIV&gt;</code> tags) as if they were 302 redirections.
+Exactly when and how <code>Refresh</code> headers are handled is configurable
+using the constructor arguments.
+
+<dt><code>SeekableProcessor</code>
+
+<dd><p>This makes ClientCookie's response objects <code>seek()</code>able.
+Seeking is done lazily (ie. the response object only reads from the socket as
+necessary, rather than slurping in all the data before the response is returned
+to you).  XXX only works for HTTP ATM, I think, and also doesn't work for
+HTTPError exceptions...
+
+<dt><code>HTTPRefererProcessor</code>
+
+<dd><p>The <code>Referer</code> HTTP header lets the server know which URL
+you've just visited.  Some servers use this header as state information, and
+don't like it if this is not present.  It's a chore to add this header by hand
+every time you make a request.  This adds it automatically.
+<strong>NOTE</strong>: this only makes sense if you use each processor for a
+single chain of HTTP requests (so, for example, if you use a single
+HTTPRefererProcessor to fetch a series of URLs extracted from a single page,
+<strong>this will break</strong>).  The <a href="../mechanize/">mechanize</a>
+package does this properly.</p></dd>
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+cookies = ClientCookie.CookieJar()
+
+opener = ClientCookie.build_opener(ClientCookie.HTTPRefererProcessor,
+                                   ClientCookie.HTTPEquivProcessor,
+                                   ClientCookie.HTTPRefreshProcessor,
+                                   ClientCookie.SeekableProcessor)
+opener.open(<span class="pystr">"http://www.rhubarb.com/"</span>)</pre>
+
+
+</dl>
+
+
+<a name="requests"></a>
+<h2>Confusing fact about headers and Requests</h2>
+
+<p>ClientCookie automatically upgrades <code>urllib2.Request</code> objects to
+<code>ClientCookie.Request</code>, as a backwards-compatibility hack.  This
+means that you won't see any headers that are added to Request objects by
+handlers unless you use <code>ClientCookie.Request</code> in the first place.
+Sorry about that.
+
+
+<a name="headers"></a>
+<h2>Adding headers</h2>
+
+<p>Adding headers is done like so:
+
+<pre>
+<span class="pykw">import</span> ClientCookie, urllib2
+req = urllib2.Request(<span class="pystr">"http://foobar.com/"</span>)
+req.add_header(<span class="pystr">"Referer"</span>, <span class="pystr">"http://wwwsearch.sourceforge.net/ClientCookie/"</span>)
+r = ClientCookie.urlopen(req)</pre>
+
+
+<p>You can also use the headers argument to the <code>urllib2.Request</code>
+constructor.
+
+<p><code>urllib2</code> (in fact, ClientCookie takes over this task from
+<code>urllib2</code>) adds some headers to <code>Request</code> objects
+automatically - see the next section for details.
+
+
+<h2>Changing the automatically-added headers (User-Agent)</h2>
+
+<p><code>OpenerDirector</code> automatically adds a <code>User-Agent</code>
+header to every <code>Request</code>.
+
+<p>To change this and/or add similar headers, use your own
+<code>OpenerDirector</code>:
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+cookies = ClientCookie.CookieJar()
+opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cookies))
+opener.addheaders = [(<span class="pystr">"User-agent"</span>, <span class="pystr">"Mozilla/5.0 (compatible; MyProgram/0.1)"</span>),
+                     (<span class="pystr">"From"</span>, <span class="pystr">"responsible.person at example.com"</span>)]</pre>
+
+
+<p>Again, to use <code>urlopen()</code>, install your
+<code>OpenerDirector</code> globally:
+
+<pre>
+ClientCookie.install_opener(opener)
+r = ClientCookie.urlopen(<span class="pystr">"http://acme.com/"</span>)</pre>
+
+
+<p>Also, a few standard headers (<code>Content-Length</code>,
+<code>Content-Type</code> and <code>Host</code>) are added when the
+<code>Request</code> is passed to <code>urlopen()</code> (or
+<code>OpenerDirector.open()</code>).  ClientCookie explictly adds these (and
+<code>User-Agent</code>) to the <code>Request</code> object, unlike versions of
+<code>urllib2</code> before Python 2.4 (but <strong>note</strong> that
+Content-Length is an exception to this rule: it is sent, but not explicitly
+added to the <code>Request</code>'s headers; this is due to a bug in
+<code>httplib</code> in Python 2.3 and earlier).  You shouldn't need to change
+these headers, but since this is done by <code>AbstractHTTPHandler</code>, you
+can change the way it works by passing a subclass of that handler to
+<code>build_opener()</code> (or, as always, by constructing an opener yourself
+and calling .add_handler()).
+
+
+<a name="unverifiable"></a>
+<h2>Initiating unverifiable transactions</h2>
+
+<p>This section is only of interest for correct handling of third-party HTTP
+cookies.  See <a href="./doc.html#standards">below</a> for an explanation of
+'third-party'.
+
+<p>First, some terminology.
+
+<p>An <em>unverifiable request</em> (defined fully by RFC 2965) is one whose
+URL the user did not have the option to approve.  For example, a transaction is
+unverifiable if the request is for an image in an HTML document, and the user
+had no option to approve the fetching of the image from a particular URL.
+
+<p>The <em>request-host of the origin transaction</em> (defined fully by RFC
+2965) is the host name or IP address of the original request that was initiated
+by the user.  For example, if the request is for an image in an HTML document,
+this is the request-host of the request for the page containing the image.
+
+<p><strong>ClientCookie knows that redirected transactions are unverifiable,
+and will handle that on its own (ie. you don't need to think about the origin
+request-host or verifiability yourself).</strong>
+
+<p>If you want to initiate an unverifiable transaction yourself (which you
+should if, for example, you're downloading the images from a page, and 'the
+user' hasn't explicitly OKed those URLs):
+
+<ol>
+
+  <li>If you're using a <code>urllib2.Request</code> from Python 2.3 or
+  earlier, set the <code>unverifiable</code> and <code>origin_req_host</code>
+  attributes on your <code>Request</code> instance:
+
+<pre>
+request.unverifiable = True
+request.origin_req_host = <span class="pystr">"www.example.com"</span></pre>
+
+
+  <li>If you're using a <code>urllib2.Request</code> from Python 2.4 or later,
+  or you're using a <code>ClientCookie.Request<code>, use the
+  <code>unverifiable</code> and <code>origin_req_host</code> arguments to the
+  constructor:
+
+<pre>
+request = Request(origin_req_host=<span class="pystr">"www.example.com"</span>, unverifiable=True)</pre>
+
+
+</ol>
+
+
+<a name="rfc2965"></a>
+<h2>RFC 2965 handling</h2>
+
+<p>RFC 2965 handling is switched off by default, because few browsers implement
+it, so the RFC 2965 protocol is essentially never seen on the internet.  To
+switch it on, see <a href="./doc.html#policy">here</a>.
+
+
+<a name="debugging"></a>
+<h2>Debugging</h2>
+
+<!--XXX move as much as poss. to General page-->
+
+<p>First, a few common problems.  The most frequent mistake people seem to make
+is to use <code>ClientCookie.urlopen()</code>, <em>and</em> the
+<code>.extract_cookies()</code> and <code>.add_cookie_header()</code> methods
+on a cookie object themselves.  If you use <code>ClientCookie.urlopen()</code>
+(or <code>OpenerDirector.open()</code>), the module handles extraction and
+adding of cookies by itself, so you should not call
+<code>.extract_cookies()</code> or <code>.add_cookie_header()</code>.
+
+<p>Are you sure the server is sending you any cookies in the first place?
+Maybe the server is keeping track of state in some other way
+(<code>HIDDEN</code> HTML form entries (possibly in a separate page referenced
+by a frame), URL-encoded session keys, IP address, HTTP <code>Referer</code>
+headers)?  Perhaps some embedded script in the HTML is setting cookies (see
+below)?  Maybe you messed up your request, and the server is sending you some
+standard failure page (even if the page doesn't appear to indicate any
+failure).  Sometimes, a server wants particular headers set to the values it
+expects, or it won't play nicely.  The most frequent offenders here are the
+<code>Referer</code> [<em>sic</em>] and / or <code>User-Agent</code> HTTP
+headers (<a href="./doc.html#headers">see above</a> for how to set these).  The
+<code>User-Agent</code> header may need to be set to a value like that of a
+popular browser.  The <code>Referer</code> header may need to be set to the URL
+that the server expects you to have followed a link from.  Occasionally, it may
+even be that operators deliberately configure a server to insist on precisely
+the headers that the popular browsers (MS Internet Explorer, Mozilla/Netscape,
+Opera, Konqueror/Safari) generate, but remember that incompetence (possibly on
+your part) is more probable than deliberate sabotage (and if a site owner is
+that keen to stop robots, you probably shouldn't be scraping it anyway).
+
+<p>When you <code>.save()</code> to or
+<code>.load()</code>/<code>.revert()</code> from a file, single-session cookies
+will expire unless you explicitly request otherwise with the
+<code>ignore_discard</code> argument.  This may be your problem if you find
+cookies are going away after saving and loading.
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+cj = ClientCookie.LWPCookieJar()
+opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
+ClientCookie.install_opener(opener)
+r = ClientCookie.urlopen(<span class="pystr">"http://foobar.com/"</span>)
+cj.save(<span class="pystr">"/some/file"</span>, ignore_discard=True, ignore_expires=True)</pre>
+
+
+<p>If none of the advice above solves your problem quickly, try comparing the
+headers and data that you are sending out with those that a browser emits.
+Often this will give you the clue you need.  Of course, you'll want to check
+that the browser is able to do manually what you're trying to achieve
+programatically before minutely examining the headers.  Make sure that what you
+do manually is <em>exactly</em> the same as what you're trying to do from
+Python - you may simply be hitting a server bug that only gets revealed if you
+view pages in a particular order, for example.  In order to see what your
+browser is sending to the server (even if HTTPS is in use), see <a
+href="../clientx.html">the General FAQ page</a>.  If nothing is obviously wrong
+with the requests your program is sending and you're out of ideas, you can try
+the last resort of good old brute force binary-search debugging.  Temporarily
+switch to sending HTTP headers (with <code>httplib</code>).  Start by copying
+Netscape/Mozilla or IE slavishly (apart from session IDs, etc., of course),
+then begin the tedious process of mutating your headers and data until they
+match what your higher-level code was sending.  This will at least reliably
+find your problem.
+
+<p>You can turn on display of HTTP headers:
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+hh = ClientCookie.HTTPHandler()  <span class="pycmt"># you might want HTTPSHandler, too</span>
+hh.set_http_debuglevel(1)
+opener = ClientCookie.build_opener(hh)
+response = opener.open(url)</pre>
+
+
+<p>Alternatively, you can examine your individual request and response objects
+to see what's going on.  Note, though, that ClientCookie upgrades
+urllib2.Request objects to ClientCookie.Request, so you won't see any headers
+that are added to requests by handlers unless you use ClientCookie.Request in
+the first place.  ClientCookie's responses can be made <code>.seek()</code>able
+using <code>SeekableProcessor</code>.  It's often useful to use the
+<code>.seek()</code> method like this during debugging:
+
+<pre>
+...
+response = ClientCookie.urlopen(<span class="pystr">"http://spam.eggs.org/"</span>)
+<span class="pykw">print</span> response.read()
+response.seek(0)
+<span class="pycmt"># rest of code continues as if you'd never .read() the response
+</span>...</pre>
+
+
+<p>Also, note <code>HTTPRedirectDebugProcessor</code> (which prints information
+about redirections) and <code>HTTPResponseDebugProcessor</code> (which prints
+out all response bodies, including those that are read during redirections).
+<strong>NOTE</strong>: as well as having these processors in your
+<code>OpenerDirector</code> (for example, by passing them to
+<code>build_opener()</code>) you have to turn on logging at the
+<code>INFO</code> level or lower in order to see any output.
+
+<p>If you would like to see what is going on in ClientCookie's tiny mind, do
+this:
+
+<pre>
+<span class="pykw">import</span> ClientCookie
+<span class="pycmt"># ClientCookie.DEBUG covers masses of debugging information,
+</span><span class="pycmt"># ClientCookie.INFO just shows the output from HTTPRedirectDebugProcessor,
+</span>logger = ClientCookie.getLogger(<span class="pystr">"ClientCookie"</span>)
+logger.addHandler(ClientCookie.StreamHandler())
+logger.setLevel(ClientCookie.DEBUG)</pre>
+
+
+<p>(In Python 2.3 or newer, <code>logging.getLogger</code>,
+<code>logging.DEBUG</code>, <code>logging.INFO</code> etc. work just as well.)
+
+<p>The <code>DEBUG</code> level (as opposed to the <code>INFO</code> level) can
+actually be quite useful, as it explains why particular cookies are accepted or
+rejected and why they are or are not returned.
+
+<p>One final thing to note is that there are some catch-all bare
+<code>except:</code> statements in the module, which are there to handle
+unexpected bad input without crashing your program.  If this happens, it's a
+bug in ClientCookie, so please mail me the warning text.
+
+
+<a name="script"></a>
+<h2>Embedded script that sets cookies</h2>
+
+<p>It is possible to embed script in HTML pages (sandwiched between
+<code>&lt;SCRIPT&gt;here&lt;/SCRIPT&gt;</code> tags, and in
+<code>javascript:</code> URLs) - JavaScript / ECMAScript, VBScript, or even
+Python - that causes cookies to be set in a browser.  See the <a
+href="../bits/clientx.html">General FAQs</a> page for what to do about this.
+
+
+<a name="dates"></a>
+<h2>Parsing HTTP date strings</h2>
+
+<p>A function named <code>str2time</code> is provided by the package,
+which may be useful for parsing dates in HTTP headers.
+<code>str2time</code> is intended to be liberal, since HTTP date/time
+formats are poorly standardised in practice.  There is no need to use this
+function in normal operations: <code>CookieJar</code> instances keep track
+of cookie lifetimes automatically.  This function will stay around in some
+form, though the supported date/time formats may change.
+
+
+<a name="badhtml"></a>
+<h2>Dealing with bad HTML</h2>
+
+<p>XXX Intro
+
+<p>XXX Test me
+
+<pre><span class="pykw">import</span> copy
+<span class="pykw">import</span> ClientCookie
+<span class="pykw">class</span> CommentCleanProcessor(ClientCookie.BaseProcessor):
+      <span class="pykw">def</span> http_response(self, request, response):
+          <span class="pykw">if</span> <span class="pykw">not</span> hasattr(response, <span class="pystr">"seek"</span>):
+              response = ClientCookie.response_seek_wrapper(response)
+          response.seek(0)
+          new_response = copy.copy(response)
+          new_response.set_data(
+              re.sub(<span class="pystr">"&lt;!-([^-]*)-&gt;"</span>, <span class="pystr">"&lt;!--\1--&gt;"</span>, response.read()))
+          <span class="pykw">return</span> new_response
+      https_response = http_response</pre>
+
+
+<p>XXX TidyProcessor: mxTidy?  tidylib?  tidy?
+
+
+<a name="standards"></a>
+<h2>Note about cookie standards</h2>
+
+<p>The various cookie standards and their history form a case study of the
+terrible things that can happen to a protocol.  The long-suffering David
+Kristol has written a <a
+href="http://arxiv.org/abs/cs.SE/0105018">paper</a> about it, if you
+want to know the gory details.
+
+<p>Here is a summary.
+
+<p>The <a href="http://www.netscape.com/newsref/std/cookie_spec.html">Netscape
+protocol</a> (cookie_spec.html) is still the only standard supported by most
+browsers (including Internet Explorer and Netscape).  Be aware that
+cookie_spec.html is not, and never was, actually followed to the letter (or
+anything close) by anyone (including Netscape, IE and ClientCookie): the
+Netscape protocol standard is really defined by the behaviour of Netscape (and
+now IE).  Netscape cookies are also known as V0 cookies, to distinguish them
+from RFC 2109 or RFC 2965 cookies, which have a version cookie-attribute with a
+value of 1.
+
+<p><a href="http://www.ietf.org/rfcs/rfc2109.txt">RFC 2109</a> was introduced
+to fix some problems identified with the Netscape protocol, while still keeping
+the same HTTP headers (<code>Cookie</code> and <code>Set-Cookie</code>).  The
+most prominent of these problems is the 'third-party' cookie issue, which was
+an accidental feature of the Netscape protocol.  When one visits www.bland.org,
+one doesn't expect to get a cookie from www.lurid.com, a site one has never
+visited.  Depending on browser configuration, this can still happen, because
+the unreconstructed Netscape protocol is happy to accept cookies from, say, an
+image in a webpage (www.bland.org) that's included by linking to an
+advertiser's server (www.lurid.com).  This kind of event, where your browser
+talks to a server that you haven't explicitly okayed by some means, is what the
+RFCs call an 'unverifiable transaction'.  In addition to the potential for
+embarrassment caused by the presence of lurid.com's cookies on one's machine,
+this may also be used to track your movements on the web, because advertising
+agencies like doubleclick.net place ads on many sites.  RFC 2109 tried to
+change this by requiring cookies to be turned off during unverifiable
+transactions with third-party servers - unless the user explicitly asks them to
+be turned on.  This clashed with the business model of advertisers like
+doubleclick.net, who had started to take advantage of the third-party cookies
+'bug'.  Since the browser vendors were more interested in the advertisers'
+concerns than those of the browser users, this arguably doomed both RFC 2109
+and its successor, RFC 2965, from the start.  Other problems than the
+third-party cookie issue were also fixed by 2109.  However, even ignoring the
+advertising issue, 2109 was stillborn, because Internet Explorer and Netscape
+behaved differently in response to its extended <code>Set-Cookie</code>
+headers.  This was not really RFC 2109's fault: it worked the way it did to
+keep compatibility with the Netscape protocol as implemented by Netscape.
+Microsoft Internet Explorer (MSIE) was very new when the standard was designed,
+but was starting to be very popular when the standard was finalised.  XXX P3P,
+and MSIE & Mozilla options
+
+<p>XXX Apparently MSIE implements bits of RFC 2109 - but not very compliant
+(surprise).  Presumably other browsers do too, as a result.  ClientCookie
+already does allow Netscape cookies to have <code>max-age</code> and
+<code>port</code> cookie-attributes, and as far as I know that's the extent of
+the support present in MSIE.  I haven't tested, though!
+
+<p><a href="http://www.ietf.org/rfcs/rfc2965.txt">RFC 2965</a> attempted to fix
+the compatibility problem by introducing two new headers,
+<code>Set-Cookie2</code> and <code>Cookie2</code>.  Unlike the
+<code>Cookie</code> header, <code>Cookie2</code> does <em>not</em> carry
+cookies to the server - rather, it simply advertises to the server that RFC
+2965 is understood.  <code>Set-Cookie2</code> <em>does</em> carry cookies, from
+server to client: the new header means that both IE and Netscape completely
+ignore these cookies.  This prevents breakage, but introduces a chicken-egg
+problem that means 2965 may never be widely adopted, especially since Microsoft
+shows no interest in it.  XXX Rumour has it that the European Union is unhappy
+with P3P, and might introduce legislation that requires something better,
+forming a gap that RFC 2965 might fill - any truth in this?  Opera is the only
+browser I know of that supports the standard.  On the server side, Apache's
+<code>mod_usertrack</code> supports it.  One confusing point to note about RFC
+2965 is that it uses the same value (1) of the Version attribute in HTTP
+headers as does RFC 2109.
+
+<p>Most recently, it was discovered that RFC 2965 does not fully take account
+of issues arising when 2965 and Netscape cookies coexist, and errata were
+discussed on the W3C http-state mailing list, but the list traffic died and it
+seems RFC 2965 is dead as an internet protocol (but still a useful basis for
+implementing the de-facto standards, and perhaps as an intranet protocol).
+
+<p>Because Netscape cookies are so poorly specified, the general philosophy
+of the module's Netscape cookie implementation is to start with RFC 2965
+and open holes where required for Netscape protocol-compatibility.  RFC
+2965 cookies are <em>always</em> treated as RFC 2965 requires, of course!
+
+<a name="faq_use"></a>
+<h2>FAQs - usage</h2>
+<ul>
+  <li>Why don't I have any cookies?
+  <p>Read the <a href="./doc.html#debugging">debugging section</a> of this page.
+  <li>My response claims to be empty, but I know it's not!
+  <p>Did you call <code>response.read()</code> (eg., in a debug statement),
+     then forget that all the data has already been read?  In that case, you
+     may want to use <code>SeekableProcessor</code>.
+  <li>How do I download only part of a response body?
+  <p>Just call <code>.read()</code> or <code>.readline()</code> methods on your
+     response object as many times as you need.  The <code>.seek()</code> method
+     (which will only be there if you're using <code>SeekableProcessor</code>)
+     still works, because <code>SeekableProcessor</code>'s response objects
+     cache read data.
+  <li>What's the difference between the <code>.load()</code> and
+      <code>.revert()</code> methods of <code>CookieJar</code>?
+  <p><code>.load()</code> <emph>appends</emph> cookies from a file.
+     <code>.revert()</code> discards all existing cookies held by the
+     <code>CookieJar</code> first (but it won't lose any existing cookies if
+     the loading fails).
+  <li>Is it threadsafe?
+  <p>No.  <em>Tested</em> patches welcome.  Clarification: As far as I know,
+     it's perfectly possible to use ClientCookie in threaded code, but it
+     provides no synchronisation: you have to provide that yourself.
+  <li>How do I do &lt;X&gt;
+  <p>The module docstrings are worth reading if you want to do something
+     unusual.
+  <li>What's this &quot;processor&quot; business about?  I knew
+      <code>urllib2</code> used &quot;handlers&quot;, but not these
+      &quot;processors&quot;.
+  <p>This Python library <a href="http://www.python.org/sf/852995">patch</a>
+     contains an explanation.  Processors are now a standard part of urllib2
+     in Python 2.4.
+  <li>How do I use it without urllib2.py?
+  <p><pre>
+<span class="pykw">from</span> ClientCookie <span class="pykw">import</span> CookieJar
+<span class="pykw">print</span> CookieJar.extract_cookies.__doc__
+<span class="pykw">print</span> CookieJar.add_cookie_header.__doc__</pre>
+
+</ul>
+
+<p>I prefer questions and comments to be sent to the <a
+href="http://lists.sourceforge.net/lists/listinfo/wwwsearch-general">
+mailing list</a> rather than direct to me.
+
+<p><a href="mailto:jjl at pobox.com">John J. Lee</a>,
+January 2006.
+
+<hr>
+
+</div>
+
+<div id="Menu">
+
+<a href="..">Home</a><br>
+<br>
+<a href="../bits/GeneralFAQ.html">General FAQs</a><br>
+<br>
+<a href="../mechanize/">mechanize</a><br>
+<a href="../pullparser/">pullparser</a><br>
+<a href="../ClientCookie/">ClientCookie</a><br>
+<span class="thispage"><span class="subpage">ClientCookie docs</span></span><br>
+<a href="../ClientForm/">ClientForm</a><br>
+<br>
+<a href="../DOMForm/">DOMForm</a><br>
+<a href="../python-spidermonkey/">python-spidermonkey</a><br>
+<a href="../ClientTable/">ClientTable</a><br>
+<a href="../bits/urllib2_152.py">1.5.2 urllib2.py</a><br>
+<a href="../bits/urllib_152.py">1.5.2 urllib.py</a><br>
+
+<br>
+
+<a href="./doc.html#examples">Examples</a><br>
+<a href="./doc.html#browsers">Mozilla & MSIE</a><br>
+<a href="./doc.html#file">Cookies in a file</a><br>
+<a href="./doc.html#database">Cookies in a database</a><br>
+<a href="./doc.html#cookiejar">Using a <code>CookieJar</code></a><br>
+<a href="./doc.html#extras">Processors</a><br>
+<a href="./doc.html#requests">Request confusion</a><br>
+<a href="./doc.html#headers">Adding headers</a><br>
+<a href="./doc.html#unverifiable">Verifiability</a><br>
+<a href="./doc.html#rfc2965">RFC 2965</a><br>
+<a href="./doc.html#debugging">Debugging</a><br>
+<a href="./doc.html#script">Embedded scripts</a><br>
+<a href="./doc.html#dates">HTTP date parsing</a><br>
+<a href="./doc.html#standards">Standards</a><br>
+<a href="./doc.html#faq_use">FAQs - usage</a><br>
+
+</div>
+
+</body>
+
+</html>

Modified: packages/clientcookie/branches/upstream/current/doc.html.in
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/doc.html.in?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/doc.html.in (original)
+++ packages/clientcookie/branches/upstream/current/doc.html.in Mon Jun 19 07:05:08 2006
@@ -5,7 +5,7 @@
 @{from colorize import colorize}
 @{import time}
 @{import release}
-@{last_modified = release.svn_id_to_time("$Id: doc.html.in 20644 2005-12-04 15:53:53Z jjlee $")}
+@{last_modified = release.svn_id_to_time("$Id: doc.html.in 21729 2006-01-05 22:46:16Z jjlee $")}
 <html>
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -349,7 +349,8 @@
 <dd><p>This makes ClientCookie's response objects <code>seek()</code>able.
 Seeking is done lazily (ie. the response object only reads from the socket as
 necessary, rather than slurping in all the data before the response is returned
-to you).  XXX only works for HTTP ATM, I think
+to you).  XXX only works for HTTP ATM, I think, and also doesn't work for
+HTTPError exceptions...
 
 <dt><code>HTTPRefererProcessor</code>
 
@@ -650,6 +651,31 @@
 function in normal operations: <code>CookieJar</code> instances keep track
 of cookie lifetimes automatically.  This function will stay around in some
 form, though the supported date/time formats may change.
+
+
+<a name="badhtml"></a>
+<h2>Dealing with bad HTML</h2>
+
+<p>XXX Intro
+
+<p>XXX Test me
+
+@{colorize("""\
+import copy
+import ClientCookie
+class CommentCleanProcessor(ClientCookie.BaseProcessor):
+      def http_response(self, request, response):
+          if not hasattr(response, "seek"):
+              response = ClientCookie.response_seek_wrapper(response)
+          response.seek(0)
+          new_response = copy.copy(response)
+          new_response.set_data(
+              re.sub("<!-([^-]*)->", "<!--\\1-->", response.read()))
+          return new_response
+      https_response = http_response
+""")}
+
+<p>XXX TidyProcessor: mxTidy?  tidylib?  tidy?
 
 
 <a name="standards"></a>

Modified: packages/clientcookie/branches/upstream/current/ez_setup/README.txt
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ez_setup/README.txt?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ez_setup/README.txt (original)
+++ packages/clientcookie/branches/upstream/current/ez_setup/README.txt Mon Jun 19 07:05:08 2006
@@ -1,15 +1,15 @@
-This directory exists so that Subversion-based projects can share a single
-copy of the ``ez_setup`` bootstrap module for ``setuptools``, and have it
-automatically updated in their projects when ``setuptools`` is updated.
-
-For your convenience, you may use the following svn:externals definition::
-
-    ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup
-
-You can set this by executing this command in your project directory::
-
-    svn propedit svn:externals .
-
-And then adding the line shown above to the file that comes up for editing.
-Then, whenever you update your project, ``ez_setup`` will be updated as well.
-
+This directory exists so that Subversion-based projects can share a single
+copy of the ``ez_setup`` bootstrap module for ``setuptools``, and have it
+automatically updated in their projects when ``setuptools`` is updated.
+
+For your convenience, you may use the following svn:externals definition::
+
+    ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup
+
+You can set this by executing this command in your project directory::
+
+    svn propedit svn:externals .
+
+And then adding the line shown above to the file that comes up for editing.
+Then, whenever you update your project, ``ez_setup`` will be updated as well.
+

Propchange: packages/clientcookie/branches/upstream/current/ez_setup/README.txt
------------------------------------------------------------------------------
    svn:executable = *

Modified: packages/clientcookie/branches/upstream/current/ez_setup/__init__.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/ez_setup/__init__.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/ez_setup/__init__.py (original)
+++ packages/clientcookie/branches/upstream/current/ez_setup/__init__.py Mon Jun 19 07:05:08 2006
@@ -1,221 +1,233 @@
-#!python
-"""Bootstrap setuptools installation
-
-If you want to use setuptools in your package's setup.py, just include this
-file in the same directory with it, and add this to the top of your setup.py::
-
-    from ez_setup import use_setuptools
-    use_setuptools()
-
-If you want to require a specific version of setuptools, set a download
-mirror, or use an alternate download directory, you can do so by supplying
-the appropriate options to ``use_setuptools()``.
-
-This file can also be run as a script to install or upgrade setuptools.
-"""
-import sys
-DEFAULT_VERSION = "0.6a9"
-DEFAULT_URL     = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3]
-
-md5_data = {
-    'setuptools-0.5a13-py2.3.egg': '85edcf0ef39bab66e130d3f38f578c86',
-    'setuptools-0.5a13-py2.4.egg': 'ede4be600e3890e06d4ee5e0148e092a',
-    'setuptools-0.6a1-py2.3.egg': 'ee819a13b924d9696b0d6ca6d1c5833d',
-    'setuptools-0.6a1-py2.4.egg': '8256b5f1cd9e348ea6877b5ddd56257d',
-    'setuptools-0.6a2-py2.3.egg': 'b98da449da411267c37a738f0ab625ba',
-    'setuptools-0.6a2-py2.4.egg': 'be5b88bc30aed63fdefd2683be135c3b',
-    'setuptools-0.6a3-py2.3.egg': 'ee0e325de78f23aab79d33106dc2a8c8',
-    'setuptools-0.6a3-py2.4.egg': 'd95453d525a456d6c23e7a5eea89a063',
-    'setuptools-0.6a4-py2.3.egg': 'e958cbed4623bbf47dd1f268b99d7784',
-    'setuptools-0.6a4-py2.4.egg': '7f33c3ac2ef1296f0ab4fac1de4767d8',
-    'setuptools-0.6a5-py2.3.egg': '748408389c49bcd2d84f6ae0b01695b1',
-    'setuptools-0.6a5-py2.4.egg': '999bacde623f4284bfb3ea77941d2627',
-    'setuptools-0.6a6-py2.3.egg': '7858139f06ed0600b0d9383f36aca24c',
-    'setuptools-0.6a6-py2.4.egg': 'c10d20d29acebce0dc76219dc578d058',
-    'setuptools-0.6a7-py2.3.egg': 'cfc4125ddb95c07f9500adc5d6abef6f',
-    'setuptools-0.6a7-py2.4.egg': 'c6d62dab4461f71aed943caea89e6f20',
-    'setuptools-0.6a8-py2.3.egg': '2f18eaaa3f544f5543ead4a68f3b2e1a',
-    'setuptools-0.6a8-py2.4.egg': '799018f2894f14c9f8bcb2b34e69b391',
-    'setuptools-0.6a9-py2.3.egg': '8e438ad70438b07b0d8f82cae42b278f',
-    'setuptools-0.6a9-py2.4.egg': '8f6e01fc12fb1cd006dc0d6c04327ec1',
-}
-
-import sys, os
-
-def _validate_md5(egg_name, data):
-    if egg_name in md5_data:
-        from md5 import md5
-        digest = md5(data).hexdigest()
-        if digest != md5_data[egg_name]:
-            print >>sys.stderr, (
-                "md5 validation of %s failed!  (Possible download problem?)"
-                % egg_name
-            )
-            sys.exit(2)
-    return data    
-
-
-def use_setuptools(
-    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
-    download_delay=15
-):
-    """Automatically find/download setuptools and make it available on sys.path
-
-    `version` should be a valid setuptools version number that is available
-    as an egg for download under the `download_base` URL (which should end with
-    a '/').  `to_dir` is the directory where setuptools will be downloaded, if
-    it is not already available.  If `download_delay` is specified, it should
-    be the number of seconds that will be paused before initiating a download,
-    should one be required.  If an older version of setuptools is installed,
-    this routine will print a message to ``sys.stderr`` and raise SystemExit in
-    an attempt to abort the calling script.  
-    """
-    try:
-        import setuptools
-        if setuptools.__version__ == '0.0.1':
-            print >>sys.stderr, (
-            "You have an obsolete version of setuptools installed.  Please\n"
-            "remove it from your system entirely before rerunning this script."
-            )
-            sys.exit(2)
-    except ImportError:
-        egg = download_setuptools(version, download_base, to_dir, download_delay)
-        sys.path.insert(0, egg)
-        import setuptools; setuptools.bootstrap_install_from = egg
-
-    import pkg_resources
-    try:
-        pkg_resources.require("setuptools>="+version)
-
-    except pkg_resources.VersionConflict:
-        # XXX could we install in a subprocess here?
-        print >>sys.stderr, (
-            "The required version of setuptools (>=%s) is not available, and\n"
-            "can't be installed while this script is running. Please install\n"
-            " a more recent version first."
-        ) % version
-        sys.exit(2)
-
-def download_setuptools(
-    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
-    delay = 15
-):
-    """Download setuptools from a specified location and return its filename
-
-    `version` should be a valid setuptools version number that is available
-    as an egg for download under the `download_base` URL (which should end
-    with a '/'). `to_dir` is the directory where the egg will be downloaded.
-    `delay` is the number of seconds to pause before an actual download attempt.
-    """
-    import urllib2, shutil
-    egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
-    url = download_base + egg_name
-    saveto = os.path.join(to_dir, egg_name)
-    src = dst = None
-    if not os.path.exists(saveto):  # Avoid repeated downloads
-        try:
-            from distutils import log
-            if delay:
-                log.warn("""
----------------------------------------------------------------------------
-This script requires setuptools version %s to run (even to display
-help).  I will attempt to download it for you (from
-%s), but
-you may need to enable firewall access for this script first.
-I will start the download in %d seconds.
----------------------------------------------------------------------------""",
-                    version, download_base, delay
-                ); from time import sleep; sleep(delay)
-            log.warn("Downloading %s", url)
-            src = urllib2.urlopen(url)
-            # Read/write all in one block, so we don't create a corrupt file
-            # if the download is interrupted.
-            data = _validate_md5(egg_name, src.read())
-            dst = open(saveto,"wb"); dst.write(data)
-        finally:
-            if src: src.close()
-            if dst: dst.close()
-    return os.path.realpath(saveto)
-
-def main(argv, version=DEFAULT_VERSION):
-    """Install or upgrade setuptools and EasyInstall"""
-
-    try:
-        import setuptools
-    except ImportError:
-        import tempfile, shutil
-        tmpdir = tempfile.mkdtemp(prefix="easy_install-")
-        try:
-            egg = download_setuptools(version, to_dir=tmpdir, delay=0)
-            sys.path.insert(0,egg)
-            from setuptools.command.easy_install import main
-            main(list(argv)+[egg])
-        finally:
-            shutil.rmtree(tmpdir)
-    else:
-        if setuptools.__version__ == '0.0.1':
-            # tell the user to uninstall obsolete version
-            use_setuptools(version)
-
-    req = "setuptools>="+version
-    import pkg_resources
-    try:
-        pkg_resources.require(req)
-    except pkg_resources.VersionConflict:
-        try:
-            from setuptools.command.easy_install import main
-        except ImportError:
-            from easy_install import main
-        main(list(argv)+[download_setuptools(delay=0)])
-        sys.exit(0) # try to force an exit
-    else:
-        if argv:
-            from setuptools.command.easy_install import main
-            main(argv)
-        else:
-            print "Setuptools version",version,"or greater has been installed."
-            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
-
-
-            
-def update_md5(filenames):
-    """Update our built-in md5 registry"""
-
-    import re
-    from md5 import md5
-
-    for name in filenames:
-        base = os.path.basename(name)
-        f = open(name,'rb')       
-        md5_data[base] = md5(f.read()).hexdigest()
-        f.close()
-
-    data = ["    %r: %r,\n" % it for it in md5_data.items()]
-    data.sort()
-    repl = "".join(data)
-
-    import inspect
-    srcfile = inspect.getsourcefile(sys.modules[__name__])
-    f = open(srcfile, 'rb'); src = f.read(); f.close()
-
-    match = re.search("\nmd5_data = {\n([^}]+)}", src)
-    if not match:
-        print >>sys.stderr, "Internal error!"
-        sys.exit(2)
-
-    src = src[:match.start(1)] + repl + src[match.end(1):]
-    f = open(srcfile,'w')
-    f.write(src)
-    f.close()
-
-
-if __name__=='__main__':
-    if len(sys.argv)>2 and sys.argv[1]=='--md5update':
-        update_md5(sys.argv[2:])
-    else:
-        main(sys.argv[1:])
-
-
-
-
-
+#!python
+"""Bootstrap setuptools installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+    from ez_setup import use_setuptools
+    use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import sys
+DEFAULT_VERSION = "0.6a11"
+DEFAULT_URL     = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+
+md5_data = {
+    'setuptools-0.6a1-py2.3.egg': 'ee819a13b924d9696b0d6ca6d1c5833d',
+    'setuptools-0.6a1-py2.4.egg': '8256b5f1cd9e348ea6877b5ddd56257d',
+    'setuptools-0.6a10-py2.3.egg': '162d8357f1aff2b0349c6c247ee62987',
+    'setuptools-0.6a10-py2.4.egg': '803a2d8db501c1ac3b5b6fb4e907f788',
+    'setuptools-0.6a11-py2.3.egg': 'd12bf8e13aaeb25c91350c8d77f01a71',
+    'setuptools-0.6a11-py2.4.egg': 'a95d5bc7a070aa1028bc4dcb5270b133',
+    'setuptools-0.6a11dev_r43177-py2.3.egg': '068ef7c8522539af12f5fb14b4a8cf21',
+    'setuptools-0.6a11dev_r43295-py2.3.egg': 'eb78390e6beac3694342b5629cc6653f',
+    'setuptools-0.6a11dev_r43403-py2.3.egg': 'ba1a6b00f5c1fdd482284a7df3d8bd19',
+    'setuptools-0.6a11dev_r43417-py2.3.egg': 'c6014183afd9fd167d7d82eee78db2c6',
+    'setuptools-0.6a2-py2.3.egg': 'b98da449da411267c37a738f0ab625ba',
+    'setuptools-0.6a2-py2.4.egg': 'be5b88bc30aed63fdefd2683be135c3b',
+    'setuptools-0.6a3-py2.3.egg': 'ee0e325de78f23aab79d33106dc2a8c8',
+    'setuptools-0.6a3-py2.4.egg': 'd95453d525a456d6c23e7a5eea89a063',
+    'setuptools-0.6a4-py2.3.egg': 'e958cbed4623bbf47dd1f268b99d7784',
+    'setuptools-0.6a4-py2.4.egg': '7f33c3ac2ef1296f0ab4fac1de4767d8',
+    'setuptools-0.6a5-py2.3.egg': '748408389c49bcd2d84f6ae0b01695b1',
+    'setuptools-0.6a5-py2.4.egg': '999bacde623f4284bfb3ea77941d2627',
+    'setuptools-0.6a6-py2.3.egg': '7858139f06ed0600b0d9383f36aca24c',
+    'setuptools-0.6a6-py2.4.egg': 'c10d20d29acebce0dc76219dc578d058',
+    'setuptools-0.6a7-py2.3.egg': 'cfc4125ddb95c07f9500adc5d6abef6f',
+    'setuptools-0.6a7-py2.4.egg': 'c6d62dab4461f71aed943caea89e6f20',
+    'setuptools-0.6a8-py2.3.egg': '2f18eaaa3f544f5543ead4a68f3b2e1a',
+    'setuptools-0.6a8-py2.4.egg': '799018f2894f14c9f8bcb2b34e69b391',
+    'setuptools-0.6a9-py2.3.egg': '8e438ad70438b07b0d8f82cae42b278f',
+    'setuptools-0.6a9-py2.4.egg': '8f6e01fc12fb1cd006dc0d6c04327ec1',
+}
+
+import sys, os
+
+def _validate_md5(egg_name, data):
+    if egg_name in md5_data:
+        from md5 import md5
+        digest = md5(data).hexdigest()
+        if digest != md5_data[egg_name]:
+            print >>sys.stderr, (
+                "md5 validation of %s failed!  (Possible download problem?)"
+                % egg_name
+            )
+            sys.exit(2)
+    return data    
+
+
+def use_setuptools(
+    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+    download_delay=15
+):
+    """Automatically find/download setuptools and make it available on sys.path
+
+    `version` should be a valid setuptools version number that is available
+    as an egg for download under the `download_base` URL (which should end with
+    a '/').  `to_dir` is the directory where setuptools will be downloaded, if
+    it is not already available.  If `download_delay` is specified, it should
+    be the number of seconds that will be paused before initiating a download,
+    should one be required.  If an older version of setuptools is installed,
+    this routine will print a message to ``sys.stderr`` and raise SystemExit in
+    an attempt to abort the calling script.  
+    """
+    try:
+        import setuptools
+        if setuptools.__version__ == '0.0.1':
+            print >>sys.stderr, (
+            "You have an obsolete version of setuptools installed.  Please\n"
+            "remove it from your system entirely before rerunning this script."
+            )
+            sys.exit(2)
+    except ImportError:
+        egg = download_setuptools(version, download_base, to_dir, download_delay)
+        sys.path.insert(0, egg)
+        import setuptools; setuptools.bootstrap_install_from = egg
+
+    import pkg_resources
+    try:
+        pkg_resources.require("setuptools>="+version)
+
+    except pkg_resources.VersionConflict:
+        # XXX could we install in a subprocess here?
+        print >>sys.stderr, (
+            "The required version of setuptools (>=%s) is not available, and\n"
+            "can't be installed while this script is running. Please install\n"
+            " a more recent version first."
+        ) % version
+        sys.exit(2)
+
+def download_setuptools(
+    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+    delay = 15
+):
+    """Download setuptools from a specified location and return its filename
+
+    `version` should be a valid setuptools version number that is available
+    as an egg for download under the `download_base` URL (which should end
+    with a '/'). `to_dir` is the directory where the egg will be downloaded.
+    `delay` is the number of seconds to pause before an actual download attempt.
+    """
+    import urllib2, shutil
+    egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
+    url = download_base + egg_name
+    saveto = os.path.join(to_dir, egg_name)
+    src = dst = None
+    if not os.path.exists(saveto):  # Avoid repeated downloads
+        try:
+            from distutils import log
+            if delay:
+                log.warn("""
+---------------------------------------------------------------------------
+This script requires setuptools version %s to run (even to display
+help).  I will attempt to download it for you (from
+%s), but
+you may need to enable firewall access for this script first.
+I will start the download in %d seconds.
+
+(Note: if this machine does not have network access, please obtain the file
+
+   %s
+
+and place it in this directory before rerunning this script.)
+---------------------------------------------------------------------------""",
+                    version, download_base, delay, url
+                ); from time import sleep; sleep(delay)
+            log.warn("Downloading %s", url)
+            src = urllib2.urlopen(url)
+            # Read/write all in one block, so we don't create a corrupt file
+            # if the download is interrupted.
+            data = _validate_md5(egg_name, src.read())
+            dst = open(saveto,"wb"); dst.write(data)
+        finally:
+            if src: src.close()
+            if dst: dst.close()
+    return os.path.realpath(saveto)
+
+def main(argv, version=DEFAULT_VERSION):
+    """Install or upgrade setuptools and EasyInstall"""
+
+    try:
+        import setuptools
+    except ImportError:
+        import tempfile, shutil
+        tmpdir = tempfile.mkdtemp(prefix="easy_install-")
+        try:
+            egg = download_setuptools(version, to_dir=tmpdir, delay=0)
+            sys.path.insert(0,egg)
+            from setuptools.command.easy_install import main
+            main(list(argv)+[egg])
+        finally:
+            shutil.rmtree(tmpdir)
+    else:
+        if setuptools.__version__ == '0.0.1':
+            # tell the user to uninstall obsolete version
+            use_setuptools(version)
+
+    req = "setuptools>="+version
+    import pkg_resources
+    try:
+        pkg_resources.require(req)
+    except pkg_resources.VersionConflict:
+        try:
+            from setuptools.command.easy_install import main
+        except ImportError:
+            from easy_install import main
+        main(list(argv)+[download_setuptools(delay=0)])
+        sys.exit(0) # try to force an exit
+    else:
+        if argv:
+            from setuptools.command.easy_install import main
+            main(argv)
+        else:
+            print "Setuptools version",version,"or greater has been installed."
+            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
+
+
+            
+def update_md5(filenames):
+    """Update our built-in md5 registry"""
+
+    import re
+    from md5 import md5
+
+    for name in filenames:
+        base = os.path.basename(name)
+        f = open(name,'rb')       
+        md5_data[base] = md5(f.read()).hexdigest()
+        f.close()
+
+    data = ["    %r: %r,\n" % it for it in md5_data.items()]
+    data.sort()
+    repl = "".join(data)
+
+    import inspect
+    srcfile = inspect.getsourcefile(sys.modules[__name__])
+    f = open(srcfile, 'rb'); src = f.read(); f.close()
+
+    match = re.search("\nmd5_data = {\n([^}]+)}", src)
+    if not match:
+        print >>sys.stderr, "Internal error!"
+        sys.exit(2)
+
+    src = src[:match.start(1)] + repl + src[match.end(1):]
+    f = open(srcfile,'w')
+    f.write(src)
+    f.close()
+
+
+if __name__=='__main__':
+    if len(sys.argv)>2 and sys.argv[1]=='--md5update':
+        update_md5(sys.argv[2:])
+    else:
+        main(sys.argv[1:])
+
+
+
+
+

Propchange: packages/clientcookie/branches/upstream/current/ez_setup/__init__.py
------------------------------------------------------------------------------
    svn:executable = *

Modified: packages/clientcookie/branches/upstream/current/functional_tests.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/functional_tests.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/functional_tests.py (original)
+++ packages/clientcookie/branches/upstream/current/functional_tests.py Mon Jun 19 07:05:08 2006
@@ -51,11 +51,11 @@
             install_opener(o)
             try:
                 r = urlopen("http://wwwsearch.sf.net/cgi-bin/cookietest.cgi")
-            except URLError, e:
-                print e.read()
+            except urllib2.URLError, e:
+                #print e.read()
                 raise
             data = r.read()
-            print data
+            #print data
             self.assert_(
                 string.find(data, "Your browser supports cookies!") >= 0)
             self.assert_(len(cj) == 1)

Propchange: packages/clientcookie/branches/upstream/current/functional_tests.py
------------------------------------------------------------------------------
    svn:executable = *

Modified: packages/clientcookie/branches/upstream/current/setup.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/setup.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/setup.py (original)
+++ packages/clientcookie/branches/upstream/current/setup.py Mon Jun 19 07:05:08 2006
@@ -12,14 +12,18 @@
 module HTTP::Cookies, from the libwww-perl library.
 """
 
+try: True
+except NameError:
+    False, True = 0, 1
+
 import re
 #VERSION_MATCH = re.search(r'VERSION = "(.*)"', open("ClientCookie/_ClientCookie.py").read())
 #VERSION = VERSION_MATCH.group(1)
-VERSION = '1.1.1'
+VERSION = '1.3.0'
 INSTALL_REQUIRES = []
 NAME = "ClientCookie"
 PACKAGE = True
-LICENSE = "BSD"
+LICENSE = "BSD"  # or ZPL 2.1
 PLATFORMS = ["any"]
 ZIP_SAFE = True
 CLASSIFIERS = """\
@@ -27,6 +31,7 @@
 Intended Audience :: Developers
 Intended Audience :: System Administrators
 License :: OSI Approved :: BSD License
+License :: OSI Approved :: Zope Public License
 Natural Language :: English
 Operating System :: OS Independent
 Programming Language :: Python
@@ -46,10 +51,7 @@
 #-------------------------------------------------------
 # the rest is constant for most of my released packages:
 
-import ez_setup
-ez_setup.use_setuptools()
-
-import setuptools
+import sys
 
 if PACKAGE:
     packages, py_modules = [NAME], None
@@ -58,7 +60,36 @@
 
 doclines = __doc__.split("\n")
 
-setuptools.setup(
+if not hasattr(sys, "version_info") or sys.version_info < (2, 3):
+    from distutils.core import setup
+    _setup = setup
+    def setup(**kwargs):
+        ignore_keys = [
+            # distutils >= Python 2.3 args
+            # XXX probably download_url came in earlier than 2.3
+            "classifiers", "download_url",
+            # setuptools args
+            "install_requires", "zip_safe", "test_suite",
+            ]
+        if sys.version_info < (2, 1):
+            ignore_keys.append("platforms")
+        for key in ignore_keys:
+            if kwargs.has_key(key):
+                del kwargs[key]
+        # Only want packages keyword if this is a package,
+        # only want py_modules keyword if this is a single-file module,
+        # so get rid of packages or py_modules keyword as appropriate.
+        if kwargs["packages"] is None:
+            del kwargs["packages"]
+        else:
+            del kwargs["py_modules"]
+        apply(_setup, (), kwargs)
+else:
+    import ez_setup
+    ez_setup.use_setuptools()
+    from setuptools import setup
+
+setup(
     name = NAME,
     version = VERSION,
     license = LICENSE,

Propchange: packages/clientcookie/branches/upstream/current/setup.py
------------------------------------------------------------------------------
    svn:executable = *

Propchange: packages/clientcookie/branches/upstream/current/test.py
------------------------------------------------------------------------------
    svn:executable = *

Modified: packages/clientcookie/branches/upstream/current/test/test_headers.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/test/test_headers.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/test/test_headers.py (original)
+++ packages/clientcookie/branches/upstream/current/test/test_headers.py Mon Jun 19 07:05:08 2006
@@ -1,6 +1,32 @@
 """Tests for ClientCookie._HeadersUtil."""
 
 from unittest import TestCase
+
+try: True
+except NameError:
+    True = 1
+    False = 0
+
+class IsHtmlTests(TestCase):
+    def test_is_html(self):
+        from ClientCookie._HeadersUtil import is_html
+        for allow_xhtml in False, True:
+            for cths, ext, expect in [
+                (["text/html"], ".html", True),
+                (["text/html", "text/plain"], ".html", True),
+                # Content-type takes priority over file extension from URL
+                (["text/html"], ".txt", True),
+                (["text/plain"], ".html", False),
+                # use extension if no Content-Type
+                ([], ".html", True),
+                ([], ".gif", False),
+                # don't regard XHTML as HTML (unless user explicitly asks for it),
+                # since we don't yet handle XML properly
+                ([], ".xhtml", allow_xhtml),
+                (["text/xhtml"], ".xhtml", allow_xhtml),
+                ]:
+                url = "http://example.com/foo"+ext
+                self.assertEqual(expect, is_html(cths, url, allow_xhtml))
 
 class HeaderTests(TestCase):
     def test_parse_ns_headers(self):

Modified: packages/clientcookie/branches/upstream/current/test/test_misc.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/test/test_misc.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/test/test_misc.py (original)
+++ packages/clientcookie/branches/upstream/current/test/test_misc.py Mon Jun 19 07:05:08 2006
@@ -1,7 +1,13 @@
 """Miscellaneous pyunit tests."""
 
+import copy
 import cStringIO, string
 from unittest import TestCase
+
+try:
+    StopIteration
+except NameError:
+    from ClientCookie._ClientCookie import StopIteration
 
 class TestUnSeekable:
     def __init__(self, text):
@@ -24,34 +30,77 @@
         self.log.append(("readlines", sizehint))
         return self._file.readlines(sizehint)
 
+class TestUnSeekableResponse(TestUnSeekable):
+    def __init__(self, text, headers):
+        TestUnSeekable.__init__(self, text)
+        self.code = 200
+        self.msg = "OK"
+        self.headers = headers
+        self.url = "http://example.com/"
+
+    def geturl(self):
+        return self.url
+
+    def info(self):
+        return self.headers
+
+    def close(self):
+        pass
+
+
 class SeekableTests(TestCase):
-    def testSeekable(self):
-        try:
-            from exceptions import StopIteration
-        except ImportError:
-            from ClientCookie._ClientCookie import StopIteration
-        from ClientCookie._Util import seek_wrapper
-        text = """\
+
+    text = """\
 The quick brown fox
 jumps over the lazy
 
 dog.
 
 """
-        text_lines = map(lambda l: l+"\n", string.split(text, "\n")[:-1])
+    text_lines = map(lambda l: l+"\n", string.split(text, "\n")[:-1])
+
+    def testSeekable(self):
+        from ClientCookie._Util import seek_wrapper
+        text = self.text
+        text_lines = self.text_lines
+
+        for ii in range(1, 6):
+            fh = TestUnSeekable(text)
+            sfh = seek_wrapper(fh)
+            test = getattr(self, "_test%d" % ii)
+            test(sfh)
+
+        # copies have independent seek positions
         fh = TestUnSeekable(text)
         sfh = seek_wrapper(fh)
+        self._testCopy(sfh)
+
+    def _testCopy(self, sfh):
+        sfh2 = copy.copy(sfh)
+        sfh.read(10)
+        text = self.text
+        self.assertEqual(sfh2.read(10), text[:10])
+        sfh2.seek(5)
+        self.assertEqual(sfh.read(10), text[10:20])
+        self.assertEqual(sfh2.read(10), text[5:15])
+        sfh.seek(0)
+        sfh2.seek(0)
+        return sfh2
+
+    def _test1(self, sfh):
+        text = self.text
+        text_lines = self.text_lines
         assert sfh.read(10) == text[:10]  # calls fh.read
-        assert fh.log[-1] == ("read", 10)
+        assert sfh.log[-1] == ("read", 10)  # .log delegated to fh
         sfh.seek(0)  # doesn't call fh.seek
         assert sfh.read(10) == text[:10]  # doesn't call fh.read
-        assert len(fh.log) == 1
+        assert len(sfh.log) == 1
         sfh.seek(0)
         assert sfh.read(5) == text[:5]  # read only part of cached data
-        assert len(fh.log) == 1
+        assert len(sfh.log) == 1
         sfh.seek(0)
         assert sfh.read(25) == text[:25]  # calls fh.read
-        assert fh.log[1] == ("read", 15)
+        assert sfh.log[1] == ("read", 15)
         lines = []
         sfh.seek(-1, 1)
         while 1:
@@ -59,7 +108,7 @@
             if l == "": break
             lines.append(l)
         assert lines == ["s over the lazy\n"]+text_lines[2:]
-        assert fh.log[2:] == [("readline", -1)]*5
+        assert sfh.log[2:] == [("readline", -1)]*5
         sfh.seek(0)
         lines = []
         while 1:
@@ -68,8 +117,8 @@
             lines.append(l)
         assert lines == text_lines
 
-        fh = TestUnSeekable(text)
-        sfh = seek_wrapper(fh)
+    def _test2(self, sfh):
+        text = self.text
         sfh.read(5)
         sfh.seek(0)
         assert sfh.read() == text
@@ -83,17 +132,19 @@
         assert sfh.readline(5) == "The q"
         assert sfh.readline() == "uick brown fox\n"
 
-        fh = TestUnSeekable(text)
-        sfh = seek_wrapper(fh)
+    def _test3(self, sfh):
+        text = self.text
+        text_lines = self.text_lines
         sfh.read(25)
         sfh.seek(-1, 1)
-        assert sfh.readlines() == ["s over the lazy\n"]+text_lines[2:]
-        nr_logs = len(fh.log)
+        self.assertEqual(sfh.readlines(), ["s over the lazy\n"]+text_lines[2:])
+        nr_logs = len(sfh.log)
         sfh.seek(0)
         assert sfh.readlines() == text_lines
 
-        fh = TestUnSeekable(text)
-        sfh = seek_wrapper(fh)
+    def _test4(self, sfh):
+        text = self.text
+        text_lines = self.text_lines
         count = 0
         limit = 10
         while count < limit:
@@ -106,13 +157,55 @@
         else:
             assert False, "StopIteration not raised"
 
-        fh = TestUnSeekable(text)
-        sfh = seek_wrapper(fh)
+    def _test5(self, sfh):
+        text = self.text
         sfh.read(10)
         sfh.seek(5)
         self.assert_(sfh.invariant())
         sfh.seek(0, 2)
         self.assert_(sfh.invariant())
+        sfh.seek(0)
+        self.assertEqual(sfh.read(), text)
+
+    def testResponseSeekWrapper(self):
+        from ClientCookie import response_seek_wrapper
+        hdrs = {"Content-type": "text/html"}
+        r = TestUnSeekableResponse(self.text, hdrs)
+        rsw = response_seek_wrapper(r)
+        rsw2 = self._testCopy(rsw)
+        self.assert_(rsw is not rsw2)
+        self.assertEqual(rsw.info(), rsw2.info())
+        self.assert_(rsw.info() is not rsw2.info())
+
+        # should be able to close already-closed object
+        rsw2.close()
+        rsw2.close()
+
+    def testSetResponseData(self):
+        from ClientCookie import response_seek_wrapper
+        r = TestUnSeekableResponse(self.text, {'blah': 'yawn'})
+        rsw = response_seek_wrapper(r)
+        rsw.set_data("""\
+A Seeming somwhat more than View;
+  That doth instruct the Mind
+  In Things that ly behind,
+""")
+        self.assertEqual(rsw.read(9), "A Seeming")
+        self.assertEqual(rsw.read(13), " somwhat more")
+        rsw.seek(0)
+        self.assertEqual(rsw.read(9), "A Seeming")
+        self.assertEqual(rsw.readline(), " somwhat more than View;\n")
+        rsw.seek(0)
+        self.assertEqual(rsw.readline(), "A Seeming somwhat more than View;\n")
+        rsw.seek(-1, 1)
+        self.assertEqual(rsw.read(7), "\n  That")
+
+        r = TestUnSeekableResponse(self.text, {'blah': 'yawn'})
+        rsw = response_seek_wrapper(r)
+        rsw.set_data(self.text)
+        self._test2(rsw)
+        rsw.seek(0)
+        self._test4(rsw)
 
 
 if __name__ == "__main__":

Modified: packages/clientcookie/branches/upstream/current/test/test_urllib2.py
URL: http://svn.debian.org/wsvn/python-modules/packages/clientcookie/branches/upstream/current/test/test_urllib2.py?rev=914&op=diff
==============================================================================
--- packages/clientcookie/branches/upstream/current/test/test_urllib2.py (original)
+++ packages/clientcookie/branches/upstream/current/test/test_urllib2.py Mon Jun 19 07:05:08 2006
@@ -370,12 +370,15 @@
             TESTFN = "test.txt"
             urlpath = sanepathname2url(os.path.abspath(TESTFN))
             towrite = "hello, world\n"
+            try:
+                fqdn = socket.gethostbyname(socket.gethostname())
+            except socket.gaierror:
+                fqdn = "localhost"
             for url in [
                 "file://localhost%s" % urlpath,
                 "file://%s" % urlpath,
                 "file://%s%s" % (socket.gethostbyname('localhost'), urlpath),
-                "file://%s%s" % (socket.gethostbyname(socket.gethostname()),
-                                 urlpath),
+                "file://%s%s" % (fqdn, urlpath)
                 ]:
                 f = open(TESTFN, "wb")
                 try:
@@ -664,7 +667,11 @@
         o = h.parent = MockOpener()
 
         req = urllib2.Request("http://example.com/")
-        class MockUnseekableResponse: pass
+        class MockUnseekableResponse:
+            code = 200
+            msg = "OK"
+            def info(self): pass
+            def geturl(self): return ""
         r = MockUnseekableResponse()
         newr = h.http_response(req, r)
         self.assert_(not hasattr(r, "seek"))
@@ -675,13 +682,16 @@
         o = h.parent = MockOpener()
 
         req = Request("http://example.com/")
-        r = MockResponse(200, "OK", MockHeaders({"Foo": "Bar", "Content-type": "text/html"}),
-                         '<html><head>'
-                         '<meta http-equiv="Refresh" content="spam">'
-                         '</head></html>')
+        r = MockResponse(
+            200, "OK",
+            MockHeaders({"Foo": "Bar", "Content-type": "text/html"}),
+            '<html><head>'
+            '<meta http-equiv="Refresh" content="spam&amp;eggs">'
+            '</head></html>'
+            )
         newr = h.http_response(req, r)
         headers = newr.info()
-        self.assert_(headers["Refresh"] == "spam")
+        self.assert_(headers["Refresh"] == "spam&eggs")
         self.assert_(headers["Foo"] == "Bar")
 
     def test_refresh(self):
@@ -757,6 +767,49 @@
             self.assert_(count == HTTPRedirectHandler.max_redirections)
 
 
+class UnescapeTests(unittest.TestCase):
+
+    def test_unescape_charref(self):
+        from ClientCookie._urllib2_support import \
+             unescape_charref, get_entitydefs
+        mdash_utf8 = u"\u2014".encode("utf-8")
+        for ref, codepoint, utf8, latin1 in [
+            ("38", 38, u"&".encode("utf-8"), "&"),
+            ("x2014", 0x2014, mdash_utf8, "&#x2014;"),
+            ("8212", 8212, mdash_utf8, "&#8212;"),
+            ]:
+            self.assertEqual(unescape_charref(ref, None), unichr(codepoint))
+            self.assertEqual(unescape_charref(ref, 'latin-1'), latin1)
+            self.assertEqual(unescape_charref(ref, 'utf-8'), utf8)
+
+    def test_get_entitydefs(self):
+        from ClientCookie._urllib2_support import get_entitydefs
+        ed = get_entitydefs()
+        for name, codepoint in [
+            ("amp", ord(u"&")),
+            ("lt", ord(u"<")),
+            ("gt", ord(u">")),
+            ("mdash", 0x2014),
+            ("spades", 0x2660),
+            ]:
+            self.assertEqual(ed[name], codepoint)
+
+    def test_unescape(self):
+        import htmlentitydefs
+        from ClientCookie._urllib2_support import unescape, get_entitydefs
+        data = "&amp; &lt; &mdash; &#8212; &#x2014;"
+        mdash_utf8 = u"\u2014".encode("utf-8")
+        ue = unescape(data, get_entitydefs(), "utf-8")
+        self.assertEqual("& < %s %s %s" % ((mdash_utf8,)*3), ue)
+
+        for text, expect in [
+            ("&a&amp;", "&a&"),
+            ("a&amp;", "a&"),
+            ]:
+            got = unescape(text, get_entitydefs(), "latin-1")
+            self.assertEqual(got, expect)
+
+
 class HeadParserTests(unittest.TestCase):
 
     def test(self):




More information about the Python-modules-commits mailing list