2 import http
.cookiejar
as cookiejar
9 class GoCookieJar(cookiejar
.FileCookieJar
):
10 '''A CookieJar implementation that reads and writes cookies
11 to the cookiejar format as understood by the Go package
12 github.com/juju/persistent-cookiejar.'''
13 def _really_load(self
, f
, filename
, ignore_discard
, ignore_expires
):
14 '''Implement the _really_load method called by FileCookieJar
15 to implement the actual cookie loading'''
16 data
= json
.load(f
) or []
18 for cookie
in map(go_to_py_cookie
, data
):
19 if not ignore_expires
and cookie
.is_expired(now
):
21 self
.set_cookie(cookie
)
23 def save(self
, filename
=None, ignore_discard
=False, ignore_expires
=False):
24 '''Implement the FileCookieJar abstract method.'''
26 if self
.filename
is not None:
27 filename
= self
.filename
29 raise ValueError(cookiejar
.MISSING_FILENAME_TEXT
)
31 # TODO: obtain file lock, read contents of file, and merge with
36 if not ignore_discard
and cookie
.discard
:
38 if not ignore_expires
and cookie
.is_expired(now
):
40 go_cookies
.append(py_to_go_cookie(cookie
))
41 with
open(filename
, "w") as f
:
42 f
.write(json
.dumps(go_cookies
))
45 def go_to_py_cookie(go_cookie
):
46 '''Convert a Go-style JSON-unmarshaled cookie into a Python cookie'''
48 if go_cookie
.get('Expires') is not None:
49 t
= pyrfc3339
.parse(go_cookie
['Expires'])
50 expires
= t
.timestamp()
51 return cookiejar
.Cookie(
53 name
=go_cookie
['Name'],
54 value
=go_cookie
['Value'],
57 # Unfortunately Python cookies don't record the original
58 # host that the cookie came from, so we'll just use Domain
59 # for that purpose, and record that the domain was specified,
60 # even though it probably was not. This means that
61 # we won't correctly record the CanonicalHost entry
62 # when writing the cookie file after reading it.
63 domain
=go_cookie
['Domain'],
64 domain_specified
=not go_cookie
['HostOnly'],
65 domain_initial_dot
=False,
66 path
=go_cookie
['Path'],
68 secure
=go_cookie
['Secure'],
78 def py_to_go_cookie(py_cookie
):
79 '''Convert a python cookie to the JSON-marshalable Go-style cookie form.'''
85 # not done properly: CanonicalHost.
87 'Name': py_cookie
.name
,
88 'Value': py_cookie
.value
,
89 'Domain': py_cookie
.domain
,
90 'HostOnly': not py_cookie
.domain_specified
,
91 'Persistent': not py_cookie
.discard
,
92 'Secure': py_cookie
.secure
,
93 'CanonicalHost': py_cookie
.domain
,
95 if py_cookie
.path_specified
:
96 go_cookie
['Path'] = py_cookie
.path
97 if py_cookie
.expires
is not None:
98 unix_time
= datetime
.datetime
.fromtimestamp(py_cookie
.expires
)
99 # Note: fromtimestamp bizarrely produces a time without
100 # a time zone, so we need to use accept_naive.
101 go_cookie
['Expires'] = pyrfc3339
.generate(unix_time
, accept_naive
=True)