PyXR

c:\python24\lib \ _LWPCookieJar.py



0001 """Load / save to libwww-perl (LWP) format files.
0002 
0003 Actually, the format is slightly extended from that used by LWP's
0004 (libwww-perl's) HTTP::Cookies, to avoid losing some RFC 2965 information
0005 not recorded by LWP.
0006 
0007 It uses the version string "2.0", though really there isn't an LWP Cookies
0008 2.0 format.  This indicates that there is extra information in here
0009 (domain_dot and # port_spec) while still being compatible with
0010 libwww-perl, I hope.
0011 
0012 """
0013 
0014 import time, re, logging
0015 from cookielib import (reraise_unmasked_exceptions, FileCookieJar, Cookie,
0016      MISSING_FILENAME_TEXT, join_header_words, split_header_words,
0017      iso2time, time2isoz)
0018 
0019 def lwp_cookie_str(cookie):
0020     """Return string representation of Cookie in an the LWP cookie file format.
0021 
0022     Actually, the format is extended a bit -- see module docstring.
0023 
0024     """
0025     h = [(cookie.name, cookie.value),
0026          ("path", cookie.path),
0027          ("domain", cookie.domain)]
0028     if cookie.port is not None: h.append(("port", cookie.port))
0029     if cookie.path_specified: h.append(("path_spec", None))
0030     if cookie.port_specified: h.append(("port_spec", None))
0031     if cookie.domain_initial_dot: h.append(("domain_dot", None))
0032     if cookie.secure: h.append(("secure", None))
0033     if cookie.expires: h.append(("expires",
0034                                time2isoz(float(cookie.expires))))
0035     if cookie.discard: h.append(("discard", None))
0036     if cookie.comment: h.append(("comment", cookie.comment))
0037     if cookie.comment_url: h.append(("commenturl", cookie.comment_url))
0038 
0039     keys = cookie._rest.keys()
0040     keys.sort()
0041     for k in keys:
0042         h.append((k, str(cookie._rest[k])))
0043 
0044     h.append(("version", str(cookie.version)))
0045 
0046     return join_header_words([h])
0047 
0048 class LWPCookieJar(FileCookieJar):
0049     """
0050     The LWPCookieJar saves a sequence of"Set-Cookie3" lines.
0051     "Set-Cookie3" is the format used by the libwww-perl libary, not known
0052     to be compatible with any browser, but which is easy to read and
0053     doesn't lose information about RFC 2965 cookies.
0054 
0055     Additional methods
0056 
0057     as_lwp_str(ignore_discard=True, ignore_expired=True)
0058 
0059     """
0060 
0061     def as_lwp_str(self, ignore_discard=True, ignore_expires=True):
0062         """Return cookies as a string of "\n"-separated "Set-Cookie3" headers.
0063 
0064         ignore_discard and ignore_expires: see docstring for FileCookieJar.save
0065 
0066         """
0067         now = time.time()
0068         r = []
0069         for cookie in self:
0070             if not ignore_discard and cookie.discard:
0071                 continue
0072             if not ignore_expires and cookie.is_expired(now):
0073                 continue
0074             r.append("Set-Cookie3: %s" % lwp_cookie_str(cookie))
0075         return "\n".join(r+[""])
0076 
0077     def save(self, filename=None, ignore_discard=False, ignore_expires=False):
0078         if filename is None:
0079             if self.filename is not None: filename = self.filename
0080             else: raise ValueError(MISSING_FILENAME_TEXT)
0081 
0082         f = open(filename, "w")
0083         try:
0084             # There really isn't an LWP Cookies 2.0 format, but this indicates
0085             # that there is extra information in here (domain_dot and
0086             # port_spec) while still being compatible with libwww-perl, I hope.
0087             f.write("#LWP-Cookies-2.0\n")
0088             f.write(self.as_lwp_str(ignore_discard, ignore_expires))
0089         finally:
0090             f.close()
0091 
0092     def _really_load(self, f, filename, ignore_discard, ignore_expires):
0093         magic = f.readline()
0094         if not re.search(self.magic_re, magic):
0095             msg = "%s does not seem to contain cookies" % filename
0096             raise IOError(msg)
0097 
0098         now = time.time()
0099 
0100         header = "Set-Cookie3:"
0101         boolean_attrs = ("port_spec", "path_spec", "domain_dot",
0102                          "secure", "discard")
0103         value_attrs = ("version",
0104                        "port", "path", "domain",
0105                        "expires",
0106                        "comment", "commenturl")
0107 
0108         try:
0109             while 1:
0110                 line = f.readline()
0111                 if line == "": break
0112                 if not line.startswith(header):
0113                     continue
0114                 line = line[len(header):].strip()
0115 
0116                 for data in split_header_words([line]):
0117                     name, value = data[0]
0118                     # name and value are an exception here, since a plain "foo"
0119                     # (with no "=", unlike "bar=foo") means a cookie with no
0120                     # name and value "foo".  With all other cookie-attributes,
0121                     # the situation is reversed: "foo" means an attribute named
0122                     # "foo" with no value!
0123                     if value is None:
0124                         name, value = value, name
0125                     standard = {}
0126                     rest = {}
0127                     for k in boolean_attrs:
0128                         standard[k] = False
0129                     for k, v in data[1:]:
0130                         if k is not None:
0131                             lc = k.lower()
0132                         else:
0133                             lc = None
0134                         # don't lose case distinction for unknown fields
0135                         if (lc in value_attrs) or (lc in boolean_attrs):
0136                             k = lc
0137                         if k in boolean_attrs:
0138                             if v is None: v = True
0139                             standard[k] = v
0140                         elif k in value_attrs:
0141                             standard[k] = v
0142                         else:
0143                             rest[k] = v
0144 
0145                     h = standard.get
0146                     expires = h("expires")
0147                     discard = h("discard")
0148                     if expires is not None:
0149                         expires = iso2time(expires)
0150                     if expires is None:
0151                         discard = True
0152                     domain = h("domain")
0153                     domain_specified = domain.startswith(".")
0154                     c = Cookie(h("version"), name, value,
0155                                h("port"), h("port_spec"),
0156                                domain, domain_specified, h("domain_dot"),
0157                                h("path"), h("path_spec"),
0158                                h("secure"),
0159                                expires,
0160                                discard,
0161                                h("comment"),
0162                                h("commenturl"),
0163                                rest)
0164                     if not ignore_discard and c.discard:
0165                         continue
0166                     if not ignore_expires and c.is_expired(now):
0167                         continue
0168                     self.set_cookie(c)
0169         except:
0170             reraise_unmasked_exceptions((IOError,))
0171             raise IOError("invalid Set-Cookie3 format file %s" % filename)
0172 

Generated by PyXR 0.9.4
SourceForge.net Logo