From wwwsearch-commits at codespeak.net Thu Jan 3 20:50:08 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Thu, 3 Jan 2008 20:50:08 +0100 (CET) Subject: [wwwsearch-commits] Start Charting Today Message-ID: <20080103115010.6376.qmail@kind-link.volia.net> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080103/102082a7/attachment.htm From wwwsearch-commits at codespeak.net Fri Jan 4 13:32:06 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Fri, 4 Jan 2008 13:32:06 +0100 (CET) Subject: [wwwsearch-commits] Start Earn Today! Message-ID: <20080104043209.20230.qmail@salensta-ukraine.tenet.odessa.ua> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080104/d8fcfdd0/attachment-0001.htm From wwwsearch-commits at codespeak.net Sun Jan 6 19:10:50 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Sun, 6 Jan 2008 19:10:50 +0100 (CET) Subject: [wwwsearch-commits] GOLD CASINO BONUS $$$2400 Message-ID: <20080106121057.3561.qmail@ppp85-140-70-18.pppoe.mtu-net.ru> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080106/82ad0dcf/attachment.htm From wwwsearch-commits at codespeak.net Thu Jan 24 15:07:23 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Thu, 24 Jan 2008 15:07:23 +0100 (CET) Subject: [wwwsearch-commits] Your Featured Products for the Week‏ ‏ Message-ID: <20080124040720.5436.qmail@azq124.neoplus.adsl.tpnet.pl> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080124/11367913/attachment.htm From wwwsearch-commits at codespeak.net Thu Jan 31 11:55:57 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Thu, 31 Jan 2008 11:55:57 +0100 (CET) Subject: [wwwsearch-commits] January 76% OFF Message-ID: <20080131045550.3516.qmail@ip-131-255-122-091.pools.atnet.ru> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080131/be984b71/attachment.htm From wwwsearch-commits at codespeak.net Thu Jan 31 19:45:21 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Thu, 31 Jan 2008 19:45:21 +0100 (CET) Subject: [wwwsearch-commits] The Outstanding Offers Message-ID: <20080131124514.6766.qmail@eth-233.169-homell.natm.ru> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080131/ad55540e/attachment.htm From wwwsearch-commits at codespeak.net Mon Feb 4 18:07:30 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Mon, 4 Feb 2008 18:07:30 +0100 (CET) Subject: [wwwsearch-commits] February 74% OFF Message-ID: <20080204070719.3280.qmail@c176-95.icpnet.pl> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080204/b55fe697/attachment.htm From jjlee at codespeak.net Sat Feb 23 20:05:29 2008 From: jjlee at codespeak.net (jjlee at codespeak.net) Date: Sat, 23 Feb 2008 20:05:29 +0100 (CET) Subject: [wwwsearch-commits] r51826 - wwwsearch/mechanize/trunk Message-ID: <20080223190529.4DA861684C4@codespeak.net> Author: jjlee Date: Sat Feb 23 20:05:26 2008 New Revision: 51826 Modified: wwwsearch/mechanize/trunk/doc.html.in Log: Minor doc fixes Modified: wwwsearch/mechanize/trunk/doc.html.in ============================================================================== --- wwwsearch/mechanize/trunk/doc.html.in (original) +++ wwwsearch/mechanize/trunk/doc.html.in Sat Feb 23 20:05:26 2008 @@ -644,15 +644,15 @@

Alternatively, you can examine your individual request and response objects to see what's going on. Note, though, that mechanize upgrades -urllib2.Request objects to mechanize.Request, so you won't see any -headers that are added to requests by handlers unless you use -mechanize.Request in the first place. In addition, requests may -involve "sub-requests" in cases such as redirection, in which case you -will also not see everything that's going on just by examining the -original request and final response. mechanize's responses can be -made to have .seek() and .get_data() -methods. It's often useful to use the .get_data() method -during debugging (see above). +urllib2.Request objects to mechanize.Request, so you +won't see any headers that are added to requests by handlers unless you use +mechanize.Request in the first place. In addition, requests may +involve "sub-requests" in cases such as redirection, in which case you will +also not see everything that's going on just by examining the original request +and final response. mechanize's responses can be made to +have .seek() and .get_data() methods. It's often +useful to use the .get_data() method during debugging +(see above).

Also, note HTTPRedirectDebugProcessor (which prints information about redirections) and HTTPResponseDebugProcessor (which prints @@ -854,7 +854,7 @@ detail.

  • HTTP cookies FAQ. -
  • Which protocols does ClientCookie support? +
  • Which protocols does mechanize 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 @@ -862,7 +862,7 @@ 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. + mechanize knows about that, too. From jjlee at codespeak.net Sat Feb 23 20:11:32 2008 From: jjlee at codespeak.net (jjlee at codespeak.net) Date: Sat, 23 Feb 2008 20:11:32 +0100 (CET) Subject: [wwwsearch-commits] r51827 - in wwwsearch/mechanize/trunk: . test Message-ID: <20080223191132.E7C071684C4@codespeak.net> Author: jjlee Date: Sat Feb 23 20:11:32 2008 New Revision: 51827 Added: wwwsearch/mechanize/trunk/test/test_password_manager.special_doctest - copied unchanged from r45426, wwwsearch/mechanize/trunk/test/test_password_manager.doctest wwwsearch/mechanize/trunk/test/test_robotfileparser.special_doctest - copied unchanged from r48480, wwwsearch/mechanize/trunk/test/test_robotfileparser.doctest Removed: wwwsearch/mechanize/trunk/test/test_password_manager.doctest wwwsearch/mechanize/trunk/test/test_robotfileparser.doctest Modified: wwwsearch/mechanize/trunk/test.py Log: Avoid running doctest files that need special context by naming convention rather than special-purpose code Modified: wwwsearch/mechanize/trunk/test.py ============================================================================== --- wwwsearch/mechanize/trunk/test.py (original) +++ wwwsearch/mechanize/trunk/test.py Sat Feb 23 20:11:32 2008 @@ -76,36 +76,23 @@ # run .doctest files needing special support common_globs = {"mechanize": mechanize} pm_doctest_filename = os.path.join( - "test", "test_password_manager.doctest") + "test", "test_password_manager.special_doctest") for globs in [ {"mgr_class": mechanize.HTTPPasswordMgr}, {"mgr_class": mechanize.HTTPProxyPasswordMgr}, ]: globs.update(common_globs) - doctest.testfile( - pm_doctest_filename, - #os.path.join("test", "test_scratch.doctest"), - globs=globs, - ) + doctest.testfile(pm_doctest_filename, globs=globs) try: import robotparser except ImportError: pass else: - doctest.testfile(os.path.join("test", - "test_robotfileparser.doctest")) + doctest.testfile(os.path.join( + "test", "test_robotfileparser.special_doctest")) # run .doctest files - special_doctests = [pm_doctest_filename, - os.path.join("test", "test_scratch.doctest"), - os.path.join("test", - "test_robotfileparser.doctest"), - ] doctest_files = glob.glob(os.path.join("test", "*.doctest")) - - for dt in special_doctests: - if dt in doctest_files: - doctest_files.remove(dt) for df in doctest_files: doctest.testfile(df) Deleted: /wwwsearch/mechanize/trunk/test/test_password_manager.doctest ============================================================================== --- /wwwsearch/mechanize/trunk/test/test_password_manager.doctest Sat Feb 23 20:11:32 2008 +++ (empty file) @@ -1,148 +0,0 @@ -Features common to HTTPPasswordMgr and HTTPProxyPasswordMgr -=========================================================== - -(mgr_class gets here through globs argument) - ->>> mgr = mgr_class() ->>> add = mgr.add_password - ->>> add("Some Realm", "http://example.com/", "joe", "password") ->>> add("Some Realm", "http://example.com/ni", "ni", "ni") ->>> add("c", "http://example.com/foo", "foo", "ni") ->>> add("c", "http://example.com/bar", "bar", "nini") ->>> add("b", "http://example.com/", "first", "blah") ->>> add("b", "http://example.com/", "second", "spam") ->>> add("a", "http://example.com", "1", "a") ->>> add("Some Realm", "http://c.example.com:3128", "3", "c") ->>> add("Some Realm", "d.example.com", "4", "d") ->>> add("Some Realm", "e.example.com:3128", "5", "e") - ->>> mgr.find_user_password("Some Realm", "example.com") -('joe', 'password') ->>> mgr.find_user_password("Some Realm", "http://example.com") -('joe', 'password') ->>> mgr.find_user_password("Some Realm", "http://example.com/") -('joe', 'password') ->>> mgr.find_user_password("Some Realm", "http://example.com/spam") -('joe', 'password') ->>> mgr.find_user_password("Some Realm", "http://example.com/spam/spam") -('joe', 'password') ->>> mgr.find_user_password("c", "http://example.com/foo") -('foo', 'ni') ->>> mgr.find_user_password("c", "http://example.com/bar") -('bar', 'nini') - -Actually, this is really undefined ATM -#Currently, we use the highest-level path where more than one match: -# -#>>> mgr.find_user_password("Some Realm", "http://example.com/ni") -#('joe', 'password') - -Use latest add_password() in case of conflict: - ->>> mgr.find_user_password("b", "http://example.com/") -('second', 'spam') - -No special relationship between a.example.com and example.com: - ->>> mgr.find_user_password("a", "http://example.com/") -('1', 'a') ->>> mgr.find_user_password("a", "http://a.example.com/") -(None, None) - -Ports: - ->>> mgr.find_user_password("Some Realm", "c.example.com") -(None, None) ->>> mgr.find_user_password("Some Realm", "c.example.com:3128") -('3', 'c') ->>> mgr.find_user_password("Some Realm", "http://c.example.com:3128") -('3', 'c') ->>> mgr.find_user_password("Some Realm", "d.example.com") -('4', 'd') ->>> mgr.find_user_password("Some Realm", "e.example.com:3128") -('5', 'e') - - -Default port tests ------------------- - ->>> mgr = mgr_class() ->>> add = mgr.add_password - -The point to note here is that we can't guess the default port if there's -no scheme. This applies to both add_password and find_user_password. - ->>> add("f", "http://g.example.com:80", "10", "j") ->>> add("g", "http://h.example.com", "11", "k") ->>> add("h", "i.example.com:80", "12", "l") ->>> add("i", "j.example.com", "13", "m") ->>> mgr.find_user_password("f", "g.example.com:100") -(None, None) ->>> mgr.find_user_password("f", "g.example.com:80") -('10', 'j') ->>> mgr.find_user_password("f", "g.example.com") -(None, None) ->>> mgr.find_user_password("f", "http://g.example.com:100") -(None, None) ->>> mgr.find_user_password("f", "http://g.example.com:80") -('10', 'j') ->>> mgr.find_user_password("f", "http://g.example.com") -('10', 'j') ->>> mgr.find_user_password("g", "h.example.com") -('11', 'k') ->>> mgr.find_user_password("g", "h.example.com:80") -('11', 'k') ->>> mgr.find_user_password("g", "http://h.example.com:80") -('11', 'k') ->>> mgr.find_user_password("h", "i.example.com") -(None, None) ->>> mgr.find_user_password("h", "i.example.com:80") -('12', 'l') ->>> mgr.find_user_password("h", "http://i.example.com:80") -('12', 'l') ->>> mgr.find_user_password("i", "j.example.com") -('13', 'm') ->>> mgr.find_user_password("i", "j.example.com:80") -(None, None) ->>> mgr.find_user_password("i", "http://j.example.com") -('13', 'm') ->>> mgr.find_user_password("i", "http://j.example.com:80") -(None, None) - - -Features specific to HTTPProxyPasswordMgr -========================================= - -Default realm: - ->>> mgr = mechanize.HTTPProxyPasswordMgr() ->>> add = mgr.add_password - ->>> mgr.find_user_password("d", "f.example.com") -(None, None) ->>> add(None, "f.example.com", "6", "f") ->>> mgr.find_user_password("d", "f.example.com") -('6', 'f') - -Default host/port: - ->>> mgr.find_user_password("e", "g.example.com") -(None, None) ->>> add("e", None, "7", "g") ->>> mgr.find_user_password("e", "g.example.com") -('7', 'g') - -Default realm and host/port: - ->>> mgr.find_user_password("f", "h.example.com") -(None, None) ->>> add(None, None, "8", "h") ->>> mgr.find_user_password("f", "h.example.com") -('8', 'h') - -Default realm beats default host/port: - ->>> add("d", None, "9", "i") ->>> mgr.find_user_password("d", "f.example.com") -('6', 'f') Deleted: /wwwsearch/mechanize/trunk/test/test_robotfileparser.doctest ============================================================================== --- /wwwsearch/mechanize/trunk/test/test_robotfileparser.doctest Sat Feb 23 20:11:32 2008 +++ (empty file) @@ -1,8 +0,0 @@ ->>> from mechanize._http import MechanizeRobotFileParser - -Calling .set_opener() without args sets a default opener. - ->>> rfp = MechanizeRobotFileParser() ->>> rfp.set_opener() ->>> rfp._opener # doctest: +ELLIPSIS - From jjlee at codespeak.net Sat Feb 23 20:49:29 2008 From: jjlee at codespeak.net (jjlee at codespeak.net) Date: Sat, 23 Feb 2008 20:49:29 +0100 (CET) Subject: [wwwsearch-commits] r51828 - in wwwsearch/mechanize/trunk: mechanize test Message-ID: <20080223194929.D05441684C9@codespeak.net> Author: jjlee Date: Sat Feb 23 20:49:27 2008 New Revision: 51828 Modified: wwwsearch/mechanize/trunk/mechanize/_mozillacookiejar.py wwwsearch/mechanize/trunk/test/test_cookies.py Log: * Handle cookies containing embedded tabs in mozilla format files * Remove an assertion about mozilla format cookies file contents (raise LoadError instead) Modified: wwwsearch/mechanize/trunk/mechanize/_mozillacookiejar.py ============================================================================== --- wwwsearch/mechanize/trunk/mechanize/_mozillacookiejar.py (original) +++ wwwsearch/mechanize/trunk/mechanize/_mozillacookiejar.py Sat Feb 23 20:49:27 2008 @@ -80,7 +80,7 @@ continue domain, domain_specified, path, secure, expires, name, value = \ - line.split("\t") + line.split("\t", 6) secure = (secure == "TRUE") domain_specified = (domain_specified == "TRUE") if name == "": @@ -88,7 +88,9 @@ value = None initial_dot = domain.startswith(".") - assert domain_specified == initial_dot + if domain_specified != initial_dot: + raise LoadError("domain and domain specified flag don't " + "match in %s: %s" % (filename, line)) discard = False if expires == "": @@ -113,9 +115,9 @@ self.set_cookie(c) except: - reraise_unmasked_exceptions((IOError,)) + reraise_unmasked_exceptions((IOError, LoadError)) raise LoadError("invalid Netscape format file %s: %s" % - (filename, line)) + (filename, line)) def save(self, filename=None, ignore_discard=False, ignore_expires=False): if filename is None: Modified: wwwsearch/mechanize/trunk/test/test_cookies.py ============================================================================== --- wwwsearch/mechanize/trunk/test/test_cookies.py (original) +++ wwwsearch/mechanize/trunk/test/test_cookies.py Sat Feb 23 20:49:27 2008 @@ -1,6 +1,6 @@ """Tests for _ClientCookie.""" -import urllib2, re, os, StringIO, mimetools, time +import urllib2, re, os, StringIO, mimetools, time, tempfile, errno from time import localtime from unittest import TestCase @@ -1344,6 +1344,46 @@ assert len(new_c) == 4 # 2 of them discarded on save assert repr(new_c).find("name='foo1', value='bar'") != -1 + def test_mozilla_cookiejar_embedded_tab(self): + from mechanize import MozillaCookieJar + filename = tempfile.mktemp() + fh = open(filename, "w") + try: + fh.write( + MozillaCookieJar.header + "\n" + + "a.com\tFALSE\t/\tFALSE\t\tname\tval\tstillthevalue\n" + "a.com\tFALSE\t/\tFALSE\t\tname2\tvalue\n") + fh.close() + cj = MozillaCookieJar(filename) + cj.revert(ignore_discard=True) + cookies = cj._cookies["a.com"]["/"] + self.assertEquals(cookies["name"].value, "val\tstillthevalue") + self.assertEquals(cookies["name2"].value, "value") + finally: + try: + os.remove(filename) + except OSError, exc: + if exc.errno != errno.EEXIST: + raise + + def test_mozilla_cookiejar_initial_dot_violation(self): + from mechanize import MozillaCookieJar, LoadError + filename = tempfile.mktemp() + fh = open(filename, "w") + try: + fh.write( + MozillaCookieJar.header + "\n" + + ".a.com\tFALSE\t/\tFALSE\t\tname\tvalue\n") + fh.close() + cj = MozillaCookieJar(filename) + self.assertRaises(LoadError, cj.revert, ignore_discard=True) + finally: + try: + os.remove(filename) + except OSError, exc: + if exc.errno != errno.EEXIST: + raise + def test_netscape_misc(self): # Some additional Netscape cookies tests. from mechanize import CookieJar, Request From jjlee at codespeak.net Sat Feb 23 21:56:33 2008 From: jjlee at codespeak.net (jjlee at codespeak.net) Date: Sat, 23 Feb 2008 21:56:33 +0100 (CET) Subject: [wwwsearch-commits] r51829 - wwwsearch/mechanize/trunk/test Message-ID: <20080223205633.53AC91684C8@codespeak.net> Author: jjlee Date: Sat Feb 23 21:56:31 2008 New Revision: 51829 Modified: wwwsearch/mechanize/trunk/test/test_cookies.py Log: Stop tests from clobbering files that happen to be lying around in cwd (!) Modified: wwwsearch/mechanize/trunk/test/test_cookies.py ============================================================================== --- wwwsearch/mechanize/trunk/test/test_cookies.py (original) +++ wwwsearch/mechanize/trunk/test/test_cookies.py Sat Feb 23 21:56:31 2008 @@ -118,7 +118,7 @@ # missing = sign in Cookie: header is regarded by Mozilla as a missing # NAME. WE regard it as a missing VALUE. - filename = os.path.abspath("cookies2.txt") + filename = tempfile.mktemp() c = MozillaCookieJar(filename) interact_netscape(c, "http://www.acme.com/", 'eggs') interact_netscape(c, "http://www.acme.com/", '"spam"; path=/foo/') @@ -1262,7 +1262,7 @@ assert len(c) == 6 # save and restore - filename = "lwp-cookies.txt" + filename = tempfile.mktemp() try: c.save(filename, ignore_discard=True) @@ -1306,7 +1306,7 @@ year_plus_one = localtime(time.time())[0] + 1 - filename = "cookies.txt" + filename = tempfile.mktemp() c = MozillaCookieJar(filename, policy=DefaultCookiePolicy(rfc2965=True)) From wwwsearch-commits at codespeak.net Mon Feb 25 20:51:30 2008 From: wwwsearch-commits at codespeak.net (zkzo ® Official Site) Date: Mon, 25 Feb 2008 20:51:30 +0100 (CET) Subject: [wwwsearch-commits] February %71 OFF Message-ID: <20080225-15058.3914.qmail@tdev161-240.codetel.net.do> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080225/71e8ae6b/attachment.htm From wwwsearch-commits at codespeak.net Wed Feb 27 23:55:43 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Wed, 27 Feb 2008 23:55:43 +0100 (CET) Subject: [wwwsearch-commits] February 74% OFF Message-ID: <20080227125510.35443.qmail@catv-5985e861.catv.broadband.hu> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080227/b70e6ea3/attachment-0001.htm From jjlee at codespeak.net Thu Feb 28 00:17:16 2008 From: jjlee at codespeak.net (jjlee at codespeak.net) Date: Thu, 28 Feb 2008 00:17:16 +0100 (CET) Subject: [wwwsearch-commits] r51910 - wwwsearch/mechanize/trunk/mechanize Message-ID: <20080227231716.C17961683E3@codespeak.net> Author: jjlee Date: Thu Feb 28 00:17:16 2008 New Revision: 51910 Modified: wwwsearch/mechanize/trunk/mechanize/_clientcookie.py Log: Handle missing cookie max-age value. Previously, a warning was emitted in this case. Modified: wwwsearch/mechanize/trunk/mechanize/_clientcookie.py ============================================================================== --- wwwsearch/mechanize/trunk/mechanize/_clientcookie.py (original) +++ wwwsearch/mechanize/trunk/mechanize/_clientcookie.py Thu Feb 28 00:17:16 2008 @@ -1212,6 +1212,10 @@ continue if k == "max-age": max_age_set = True + if v is None: + debug(" missing value for max-age attribute") + bad_cookie = True + break try: v = int(v) except ValueError: From jjlee at codespeak.net Thu Feb 28 00:22:23 2008 From: jjlee at codespeak.net (jjlee at codespeak.net) Date: Thu, 28 Feb 2008 00:22:23 +0100 (CET) Subject: [wwwsearch-commits] r51911 - in wwwsearch/mechanize/trunk: . mechanize test test-tools test-tools/support Message-ID: <20080227232223.7CAD41683D9@codespeak.net> Author: jjlee Date: Thu Feb 28 00:22:22 2008 New Revision: 51911 Added: wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py wwwsearch/mechanize/trunk/test-tools/support/ Modified: wwwsearch/mechanize/trunk/functional_tests.py wwwsearch/mechanize/trunk/mechanize/__init__.py wwwsearch/mechanize/trunk/test-tools/cookietest.cgi wwwsearch/mechanize/trunk/test/test_cookies.py Log: * Add support for Firefox 3 cookie jars ("cookies.sqlite") * Fix a couple of test typos re tempfile cleanup * Add a functional test for seek-wrapped HTTPError repr Modified: wwwsearch/mechanize/trunk/functional_tests.py ============================================================================== --- wwwsearch/mechanize/trunk/functional_tests.py (original) +++ wwwsearch/mechanize/trunk/functional_tests.py Thu Feb 28 00:22:22 2008 @@ -4,7 +4,7 @@ # thanks Moof (aka Giles Antonio Radford) for some of these -import os, sys, urllib +import os, sys, urllib, tempfile, errno from unittest import TestCase import mechanize @@ -159,6 +159,14 @@ r.get_data(), "Hello ClientCookie functional test suite.\n") + def test_seek_wrapper_class_name(self): + opener = mechanize.UserAgent() + opener.set_seekable_responses(True) + try: + opener.open(urljoin(self.uri, "nonexistent")) + except mechanize.HTTPError, exc: + self.assert_("HTTPError instance" in repr(exc)) + def test_no_seek(self): # should be possible to turn off UserAgent's .seek() functionality def check_no_seek(opener): @@ -395,6 +403,65 @@ ## r.close() ## self.assert_(data1 != data2) + +class CookieJarTests(TestCase): + + def test_mozilla_cookiejar(self): + filename = tempfile.mktemp() + try: + def get_cookiejar(): + cj = mechanize.MozillaCookieJar(filename=filename) + try: + cj.revert() + except IOError, exc: + if exc.errno != errno.ENOENT: + raise + return cj + def commit(cj): + cj.save() + self._test_cookiejar(get_cookiejar, commit) + finally: + try: + os.remove(filename) + except OSError, exc: + if exc.errno != errno.ENOENT: + raise + + def test_firefox3_cookiejar(self): + filename = tempfile.mktemp() + try: + def get_cookiejar(): + cj = mechanize.Firefox3CookieJar(filename=filename) + cj.connect() + return cj + def commit(cj): + pass + self._test_cookiejar(get_cookiejar, commit) + finally: + os.remove(filename) + + def _test_cookiejar(self, get_cookiejar, commit): + cookiejar = get_cookiejar() + br = mechanize.Browser() + br.set_cookiejar(cookiejar) + br.set_handle_refresh(False) + url = urljoin(self.uri, "/cgi-bin/cookietest.cgi") + # no cookie was set on the first request + html = br.open(url).read() + self.assertEquals(html.find("Your browser supports cookies!"), -1) + self.assertEquals(len(cookiejar), 1) + # ... but now we have the cookie + html = br.open(url).read() + self.assert_("Your browser supports cookies!" in html) + commit(cookiejar) + + # should still have the cookie when we load afresh + cookiejar = get_cookiejar() + br.set_cookiejar(cookiejar) + html = br.open(url).read() + self.assert_("Your browser supports cookies!" in html) + + class CallbackVerifier: # for .test_urlretrieve() def __init__(self, testcase): Modified: wwwsearch/mechanize/trunk/mechanize/__init__.py ============================================================================== --- wwwsearch/mechanize/trunk/mechanize/__init__.py (original) +++ wwwsearch/mechanize/trunk/mechanize/__init__.py Thu Feb 28 00:22:22 2008 @@ -115,6 +115,7 @@ from _clientcookie import Cookie, CookiePolicy, DefaultCookiePolicy, \ CookieJar, FileCookieJar, LoadError, request_host from _lwpcookiejar import LWPCookieJar, lwp_cookie_str +from _firefox3cookiejar import Firefox3CookieJar from _mozillacookiejar import MozillaCookieJar from _msiecookiejar import MSIECookieJar Added: wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py ============================================================================== --- (empty file) +++ wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py Thu Feb 28 00:22:22 2008 @@ -0,0 +1,245 @@ +"""Firefox 3 "cookies.sqlite" cookie persistence. + +Copyright 2008 John J Lee + +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 logging +import time + +from _clientcookie import CookieJar, Cookie, MappingIterator +from _util import isstringlike +debug = logging.getLogger("mechanize.cookies").debug + + +try: + import sqlite3 +except ImportError: + pass +else: + class Firefox3CookieJar(CookieJar): + + """Firefox 3 cookie jar. + + The cookies are stored in Firefox 3's "cookies.sqlite" format. + + Constructor arguments: + + filename: filename of cookies.sqlite (typically found at the top level + of a firefox profile directory) + autoconnect: as a convenience, connect to the SQLite cookies database at + Firefox3CookieJar construction time (default True) + policy: an object satisfying the mechanize.CookiePolicy interface + + Note that this is NOT a FileCookieJar, and there are no .load(), + .save() or .restore() methods. The database is in sync with the + cookiejar object's state after each public method call. + + Following Firefox's own behaviour, session cookies are never saved to + the database. + + The file is created, and an sqlite database written to it, if it does + not already exist. The moz_cookies database table is created if it does + not already exist. + """ + + def __init__(self, filename, autoconnect=True, policy=None): + CookieJar.__init__(self, policy) + if filename is not None and not isstringlike(filename): + raise ValueError("filename must be string-like") + self.filename = filename + self._conn = None + if autoconnect: + self.connect() + + def connect(self): + self._conn = sqlite3.connect(self.filename) + self._conn.isolation_level = "DEFERRED" + self._create_table_if_necessary() + + def close(self): + self._conn.close() + + def _transaction(self, func): + try: + cur = self._conn.cursor() + try: + result = func(cur) + finally: + cur.close() + except: + self._conn.rollback() + raise + else: + self._conn.commit() + return result + + def _execute(self, query, params=()): + return self._transaction(lambda cur: cur.execute(query, params)) + + def _query(self, query, params=()): + # XXX should we bother with a transaction? + cur = self._conn.cursor() + try: + cur.execute(query, params) + for row in cur.fetchall(): + yield row + finally: + cur.close() + + def _create_table_if_necessary(self): + self._execute("""\ +CREATE TABLE IF NOT EXISTS moz_cookies (id INTEGER PRIMARY KEY, name TEXT, + value TEXT, host TEXT, path TEXT,expiry INTEGER, + lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)""") + + def _cookie_from_row(self, row): + (pk, name, value, domain, path, expires, + last_accessed, secure, http_only) = row + + version = 0 + domain = domain.encode("ascii", "ignore") + path = path.encode("ascii", "ignore") + name = name.encode("ascii", "ignore") + value = value.encode("ascii", "ignore") + secure = bool(secure) + + # last_accessed isn't a cookie attribute, so isn't added to rest + rest = {} + if http_only: + rest["HttpOnly"] = None + + if name == "": + name = value + value = None + + initial_dot = domain.startswith(".") + domain_specified = initial_dot + + discard = False + if expires == "": + expires = None + discard = True + + return Cookie(version, name, value, + None, False, + domain, domain_specified, initial_dot, + path, False, + secure, + expires, + discard, + None, + None, + rest) + + def clear(self, domain=None, path=None, name=None): + CookieJar.clear(self, domain, path, name) + where_parts = [] + sql_params = [] + if domain is not None: + where_parts.append("host = ?") + sql_params.append(domain) + if path is not None: + where_parts.append("path = ?") + sql_params.append(path) + if name is not None: + where_parts.append("name = ?") + sql_params.append(name) + where = " AND ".join(where_parts) + if where: + where = " WHERE " + where + def clear(cur): + cur.execute("DELETE FROM moz_cookies%s" % where, + tuple(sql_params)) + self._transaction(clear) + + def _row_from_cookie(self, cookie, cur): + expires = cookie.expires + if cookie.discard: + expires = "" + + domain = unicode(cookie.domain) + path = unicode(cookie.path) + name = unicode(cookie.name) + value = unicode(cookie.value) + secure = bool(int(cookie.secure)) + + if value is None: + value = name + name = "" + + last_accessed = int(time.time()) + http_only = cookie.has_nonstandard_attr("HttpOnly") + + query = cur.execute("""SELECT MAX(id) + 1 from moz_cookies""") + pk = query.fetchone()[0] + if pk is None: + pk = 1 + + return (pk, name, value, domain, path, expires, + last_accessed, secure, http_only) + + def set_cookie(self, cookie): + if cookie.discard: + CookieJar.set_cookie(self, cookie) + return + + def set_cookie(cur): + row = self._row_from_cookie(cookie, cur) + name, unused, domain, path = row[1:5] + cur.execute("""\ +DELETE FROM moz_cookies WHERE host = ? AND path = ? AND name = ?""", + (domain, path, name)) + cur.execute("""\ +INSERT INTO moz_cookies VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) +""", row) + self._transaction(set_cookie) + + def __iter__(self): + # session (non-persistent) cookies + for cookie in MappingIterator(self._cookies): + yield cookie + # persistent cookies + for row in self._query("""\ +SELECT * FROM moz_cookies ORDER BY name, path, host"""): + yield self._cookie_from_row(row) + + def _cookies_for_request(self, request): + session_cookies = CookieJar._cookies_for_request(self, request) + def get_cookies(cur): + query = cur.execute("SELECT host from moz_cookies") + domains = [row[0] for row in query.fetchmany()] + cookies = [] + for domain in domains: + cookies += self._persistent_cookies_for_domain(domain, + request, cur) + return cookies + persistent_coookies = self._transaction(get_cookies) + return session_cookies + persistent_coookies + + def _persistent_cookies_for_domain(self, domain, request, cur): + cookies = [] + if not self._policy.domain_return_ok(domain, request): + return [] + debug("Checking %s for cookies to return", domain) + query = cur.execute("""\ +SELECT * from moz_cookies WHERE host = ? ORDER BY path""", + (domain,)) + cookies = [self._cookie_from_row(row) for row in query.fetchmany()] + last_path = None + r = [] + for cookie in cookies: + if (cookie.path != last_path and + not self._policy.path_return_ok(cookie.path, request)): + last_path = cookie.path + continue + if not self._policy.return_ok(cookie, request): + debug(" not returning cookie") + continue + debug(" it's a match") + r.append(cookie) + return r Modified: wwwsearch/mechanize/trunk/test-tools/cookietest.cgi ============================================================================== --- wwwsearch/mechanize/trunk/test-tools/cookietest.cgi (original) +++ wwwsearch/mechanize/trunk/test-tools/cookietest.cgi Thu Feb 28 00:22:22 2008 @@ -5,8 +5,12 @@ #import cgitb; cgitb.enable() +import time + print "Content-Type: text/html" -print "Set-Cookie: foo=bar\n" +year_plus_one = time.localtime(time.time())[0] + 1 +expires = "expires=09-Nov-%d 23:12:40 GMT" % (year_plus_one,) +print "Set-Cookie: foo=bar; %s\n" % expires import sys, os, string, cgi, Cookie, urllib from xml.sax import saxutils Modified: wwwsearch/mechanize/trunk/test/test_cookies.py ============================================================================== --- wwwsearch/mechanize/trunk/test/test_cookies.py (original) +++ wwwsearch/mechanize/trunk/test/test_cookies.py Thu Feb 28 00:22:22 2008 @@ -35,6 +35,25 @@ return cookie_hdr +class TempfileTestMixin(): + + def setUp(self): + self._tempfiles = [] + + def tearDown(self): + for fn in self._tempfiles: + try: + os.remove(fn) + except IOError, exc: + if exc.errno != errno.ENOENT: + raise + + def mktemp(self): + fn = tempfile.mktemp() + self._tempfiles.append(fn) + return fn + + class CookieTests(TestCase): # XXX # Get rid of string comparisons where not actually testing str / repr. @@ -864,7 +883,196 @@ assert cookie.expires is None -class LWPCookieTests(TestCase): +class CookieJarPersistenceTests(TempfileTestMixin, TestCase): + + def _interact(self, cj): + year_plus_one = localtime(time.time())[0] + 1 + interact_2965(cj, "http://www.acme.com/", + "foo1=bar; max-age=100; Version=1") + interact_2965(cj, "http://www.acme.com/", + 'foo2=bar; port="80"; max-age=100; Discard; Version=1') + interact_2965(cj, "http://www.acme.com/", "foo3=bar; secure; Version=1") + + expires = "expires=09-Nov-%d 23:12:40 GMT" % (year_plus_one,) + interact_netscape(cj, "http://www.foo.com/", + "fooa=bar; %s" % expires) + interact_netscape(cj, "http://www.foo.com/", + "foob=bar; Domain=.foo.com; %s" % expires) + interact_netscape(cj, "http://www.foo.com/", + "fooc=bar; Domain=www.foo.com; %s" % expires) + + def test_firefox3_cookiejar_restore(self): + try: + from mechanize import Firefox3CookieJar + except ImportError: + pass + else: + from mechanize import DefaultCookiePolicy + filename = self.mktemp() + def create_cookiejar(): + cj = Firefox3CookieJar(filename, + policy=DefaultCookiePolicy(rfc2965=True)) + cj.connect() + return cj + cj = create_cookiejar() + self._interact(cj) + self.assertEquals(len(cj), 6) + cj.close() + cj = create_cookiejar() + self.assert_("name='foo1', value='bar'" in repr(cj)) + self.assertEquals(len(cj), 4) + + def test_firefox3_cookiejar_iteration(self): + try: + from mechanize import Firefox3CookieJar + except ImportError: + pass + else: + from mechanize import DefaultCookiePolicy, Cookie + filename = self.mktemp() + cj = Firefox3CookieJar(filename, + policy=DefaultCookiePolicy(rfc2965=True)) + cj.connect() + self._interact(cj) + summary = "\n".join([str(cookie) for cookie in cj]) + self.assertEquals(summary, + """\ + + + + + +""") + + def test_firefox3_cookiejar_clear(self): + try: + from mechanize import Firefox3CookieJar + except ImportError: + pass + else: + from mechanize import DefaultCookiePolicy, Cookie + filename = self.mktemp() + cj = Firefox3CookieJar(filename, + policy=DefaultCookiePolicy(rfc2965=True)) + cj.connect() + self._interact(cj) + cj.clear("www.acme.com", "/", "foo2") + def summary(): return "\n".join([str(cookie) for cookie in cj]) + self.assertEquals(summary(), + """\ + + + + +""") + cj.clear("www.acme.com") + self.assertEquals(summary(), + """\ + + +""") + # if name is given, so must path and domain + self.assertRaises(ValueError, cj.clear, domain=".foo.com", + name="foob") + # nonexistent domain + self.assertRaises(KeyError, cj.clear, domain=".spam.com") + + def test_firefox3_cookiejar_add_cookie_header(self): + try: + from mechanize import Firefox3CookieJar + except ImportError: + pass + else: + from mechanize import DefaultCookiePolicy, Request + filename = self.mktemp() + cj = Firefox3CookieJar(filename) + cj.connect() + # Session cookies (true .discard) and persistent cookies (false + # .discard) are stored differently. Check they both get sent. + year_plus_one = localtime(time.time())[0] + 1 + expires = "expires=09-Nov-%d 23:12:40 GMT" % (year_plus_one,) + interact_netscape(cj, "http://www.foo.com/", "fooa=bar") + interact_netscape(cj, "http://www.foo.com/", + "foob=bar; %s" % expires) + ca, cb = cj + self.assert_(ca.discard) + self.assertFalse(cb.discard) + request = Request("http://www.foo.com/") + cj.add_cookie_header(request) + self.assertEquals(request.get_header("Cookie"), + "fooa=bar; foob=bar") + + def test_mozilla_cookiejar(self): + # Save / load Mozilla/Netscape cookie file format. + from mechanize import MozillaCookieJar, DefaultCookiePolicy + filename = tempfile.mktemp() + c = MozillaCookieJar(filename, + policy=DefaultCookiePolicy(rfc2965=True)) + self._interact(c) + + def save_and_restore(cj, ignore_discard, filename=filename): + from mechanize import MozillaCookieJar, DefaultCookiePolicy + try: + cj.save(ignore_discard=ignore_discard) + new_c = MozillaCookieJar(filename, + DefaultCookiePolicy(rfc2965=True)) + new_c.load(ignore_discard=ignore_discard) + finally: + try: os.unlink(filename) + except OSError: pass + return new_c + + new_c = save_and_restore(c, True) + assert len(new_c) == 6 # none discarded + assert repr(new_c).find("name='foo1', value='bar'") != -1 + + new_c = save_and_restore(c, False) + assert len(new_c) == 4 # 2 of them discarded on save + assert repr(new_c).find("name='foo1', value='bar'") != -1 + + def test_mozilla_cookiejar_embedded_tab(self): + from mechanize import MozillaCookieJar + filename = tempfile.mktemp() + fh = open(filename, "w") + try: + fh.write( + MozillaCookieJar.header + "\n" + + "a.com\tFALSE\t/\tFALSE\t\tname\tval\tstillthevalue\n" + "a.com\tFALSE\t/\tFALSE\t\tname2\tvalue\n") + fh.close() + cj = MozillaCookieJar(filename) + cj.revert(ignore_discard=True) + cookies = cj._cookies["a.com"]["/"] + self.assertEquals(cookies["name"].value, "val\tstillthevalue") + self.assertEquals(cookies["name2"].value, "value") + finally: + try: + os.remove(filename) + except IOError, exc: + if exc.errno != errno.ENOENT: + raise + + def test_mozilla_cookiejar_initial_dot_violation(self): + from mechanize import MozillaCookieJar, LoadError + filename = tempfile.mktemp() + fh = open(filename, "w") + try: + fh.write( + MozillaCookieJar.header + "\n" + + ".a.com\tFALSE\t/\tFALSE\t\tname\tvalue\n") + fh.close() + cj = MozillaCookieJar(filename) + self.assertRaises(LoadError, cj.revert, ignore_discard=True) + finally: + try: + os.remove(filename) + except IOError, exc: + if exc.errno != errno.ENOENT: + raise + + + +class LWPCookieTests(TestCase, TempfileTestMixin): # Tests taken from libwww-perl, with a few modifications. def test_netscape_example_1(self): @@ -1300,90 +1508,6 @@ # unicode URL doesn't raise exception, as it used to! cookie = interact_2965(c, u"http://www.acme.com/\xfc") - def test_mozilla(self): - # Save / load Mozilla/Netscape cookie file format. - from mechanize import MozillaCookieJar, DefaultCookiePolicy - - year_plus_one = localtime(time.time())[0] + 1 - - filename = tempfile.mktemp() - - c = MozillaCookieJar(filename, - policy=DefaultCookiePolicy(rfc2965=True)) - interact_2965(c, "http://www.acme.com/", - "foo1=bar; max-age=100; Version=1") - interact_2965(c, "http://www.acme.com/", - 'foo2=bar; port="80"; max-age=100; Discard; Version=1') - interact_2965(c, "http://www.acme.com/", "foo3=bar; secure; Version=1") - - expires = "expires=09-Nov-%d 23:12:40 GMT" % (year_plus_one,) - interact_netscape(c, "http://www.foo.com/", - "fooa=bar; %s" % expires) - interact_netscape(c, "http://www.foo.com/", - "foob=bar; Domain=.foo.com; %s" % expires) - interact_netscape(c, "http://www.foo.com/", - "fooc=bar; Domain=www.foo.com; %s" % expires) - - def save_and_restore(cj, ignore_discard, filename=filename): - from mechanize import MozillaCookieJar, DefaultCookiePolicy - try: - cj.save(ignore_discard=ignore_discard) - new_c = MozillaCookieJar(filename, - DefaultCookiePolicy(rfc2965=True)) - new_c.load(ignore_discard=ignore_discard) - finally: - try: os.unlink(filename) - except OSError: pass - return new_c - - new_c = save_and_restore(c, True) - assert len(new_c) == 6 # none discarded - assert repr(new_c).find("name='foo1', value='bar'") != -1 - - new_c = save_and_restore(c, False) - assert len(new_c) == 4 # 2 of them discarded on save - assert repr(new_c).find("name='foo1', value='bar'") != -1 - - def test_mozilla_cookiejar_embedded_tab(self): - from mechanize import MozillaCookieJar - filename = tempfile.mktemp() - fh = open(filename, "w") - try: - fh.write( - MozillaCookieJar.header + "\n" + - "a.com\tFALSE\t/\tFALSE\t\tname\tval\tstillthevalue\n" - "a.com\tFALSE\t/\tFALSE\t\tname2\tvalue\n") - fh.close() - cj = MozillaCookieJar(filename) - cj.revert(ignore_discard=True) - cookies = cj._cookies["a.com"]["/"] - self.assertEquals(cookies["name"].value, "val\tstillthevalue") - self.assertEquals(cookies["name2"].value, "value") - finally: - try: - os.remove(filename) - except OSError, exc: - if exc.errno != errno.EEXIST: - raise - - def test_mozilla_cookiejar_initial_dot_violation(self): - from mechanize import MozillaCookieJar, LoadError - filename = tempfile.mktemp() - fh = open(filename, "w") - try: - fh.write( - MozillaCookieJar.header + "\n" + - ".a.com\tFALSE\t/\tFALSE\t\tname\tvalue\n") - fh.close() - cj = MozillaCookieJar(filename) - self.assertRaises(LoadError, cj.revert, ignore_discard=True) - finally: - try: - os.remove(filename) - except OSError, exc: - if exc.errno != errno.EEXIST: - raise - def test_netscape_misc(self): # Some additional Netscape cookies tests. from mechanize import CookieJar, Request From jjlee at codespeak.net Thu Feb 28 01:31:51 2008 From: jjlee at codespeak.net (jjlee at codespeak.net) Date: Thu, 28 Feb 2008 01:31:51 +0100 (CET) Subject: [wwwsearch-commits] r51912 - wwwsearch/mechanize/trunk/mechanize Message-ID: <20080228003151.B0D671683BC@codespeak.net> Author: jjlee Date: Thu Feb 28 01:31:47 2008 New Revision: 51912 Modified: wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py Log: Note a couple of issues with Firefox 3 cookie jar implementation Modified: wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py ============================================================================== --- wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py (original) +++ wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py Thu Feb 28 01:31:47 2008 @@ -47,6 +47,8 @@ not already exist. """ + # XXX handle DatabaseError exceptions + def __init__(self, filename, autoconnect=True, policy=None): CookieJar.__init__(self, policy) if filename is not None and not isstringlike(filename): @@ -189,6 +191,9 @@ return def set_cookie(cur): + # XXX + # is this RFC 2965-correct? + # could this do an UPDATE instead? row = self._row_from_cookie(cookie, cur) name, unused, domain, path = row[1:5] cur.execute("""\ From jjlee at codespeak.net Fri Feb 29 21:58:00 2008 From: jjlee at codespeak.net (jjlee at codespeak.net) Date: Fri, 29 Feb 2008 21:58:00 +0100 (CET) Subject: [wwwsearch-commits] r51967 - wwwsearch/mechanize/trunk/mechanize Message-ID: <20080229205800.1E178168539@codespeak.net> Author: jjlee Date: Fri Feb 29 21:57:59 2008 New Revision: 51967 Modified: wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py Log: Add note re work to do on Firefox 3 cookies support Modified: wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py ============================================================================== --- wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py (original) +++ wwwsearch/mechanize/trunk/mechanize/_firefox3cookiejar.py Fri Feb 29 21:57:59 2008 @@ -47,7 +47,9 @@ not already exist. """ - # XXX handle DatabaseError exceptions + # XXX + # handle DatabaseError exceptions + # add a FileCookieJar (explicit .save() / .revert() / .load() methods) def __init__(self, filename, autoconnect=True, policy=None): CookieJar.__init__(self, policy) From wwwsearch-commits at codespeak.net Tue Mar 4 23:45:03 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Tue, 4 Mar 2008 23:45:03 +0100 (CET) Subject: [wwwsearch-commits] Pharmacy Online March 70% OFF Message-ID: <20080304004429.4450.qmail@adsl190-28-38-111.epm.net.co> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080304/7eec8f28/attachment.htm From wwwsearch-commits at codespeak.net Sun Mar 16 12:29:33 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Sun, 16 Mar 2008 12:29:33 +0100 (CET) Subject: [wwwsearch-commits] Discount. Coupon #pprwf Message-ID: <20080316132850.5034.qmail@fej49.internetdsl.tpnet.pl> Dear wwwsearch-commits at codespeak.net, be clever, purchase your pharmaceuticals from the best shop since 1992. http://www.google.com/pagead/iclk?sa=l&ai=aqbfk&num=7163396&adurl=http://zjm.darksidehome.com From wwwsearch-commits at codespeak.net Wed Mar 19 08:47:46 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Wed, 19 Mar 2008 08:47:46 +0100 (CET) Subject: [wwwsearch-commits] Men's Health id 4943907 Message-ID: <20080319094655.10122.qmail@a227.net156.okay.pl> Canadian Doctor Amado Link Best Price On Net March 84% OFF! http://www.google.in/pagead/iclk?sa=l&ai=pgohn&num=13281&adurl=http://www.samegentle.com From wwwsearch-commits at codespeak.net Thu Mar 27 10:13:24 2008 From: wwwsearch-commits at codespeak.net (MasterDeals Admin 24153426357 ® Official Site) Date: Thu, 27 Mar 2008 10:13:24 +0100 (CET) Subject: [wwwsearch-commits] March %76 OFF Message-ID: <20080327111441.14059.qmail@static-46-135-155-203.ksc.net.th> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080327/d1be4692/attachment.htm From wwwsearch-commits at codespeak.net Mon Mar 31 12:30:29 2008 From: wwwsearch-commits at codespeak.net (wwwsearch-commits at codespeak.net) Date: Mon, 31 Mar 2008 12:30:29 +0200 (CEST) Subject: [wwwsearch-commits] MedHelp 41683 Message-ID: <20080331132928.5816.qmail@dslb-088-073-120-051.pools.arcor-ip.net> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/wwwsearch-commits/attachments/20080331/429e7eb3/attachment.htm